MODULE ZlibBuffers;
IMPORT
SYSTEM;
TYPE
Buffer* = RECORD
avail-: LONGINT;
size-: LONGINT;
totalOut-, totalIn-: LONGINT;
next: SYSTEM.ADDRESS;
adr: SYSTEM.ADDRESS;
END;
PROCEDURE Reset*(VAR buf: Buffer);
BEGIN
buf.totalIn := 0; buf.totalOut := 0
END Reset;
PROCEDURE Init* (VAR buf: Buffer; CONST mem: ARRAY OF CHAR; offset, size, avail: LONGINT);
BEGIN
ASSERT((0 <= offset) & (0 < size) & (offset + size <= LEN(mem)), 100);
ASSERT((0 <= avail) & (avail <= size),101);
buf.avail := avail; buf.size := size; buf.adr := SYSTEM.ADR(mem[offset]); buf.next := buf.adr;
END Init;
PROCEDURE Read* (VAR buf: Buffer; VAR ch: CHAR);
BEGIN
ASSERT(buf.avail > 0, 100);
SYSTEM.GET(buf.next, ch);
INC(buf.next); DEC(buf.avail); INC(buf.totalIn)
END Read;
PROCEDURE ReadBytes* (VAR buf: Buffer; VAR dst: ARRAY OF CHAR; offset, len: LONGINT);
BEGIN
ASSERT((0 <= offset) & (0 < len) & (offset + len <= LEN(dst)) & (len <= buf.avail), 100);
SYSTEM.MOVE(buf.next, SYSTEM.ADR(dst[offset]), len);
INC(buf.next, len); DEC(buf.avail, len); INC(buf.totalIn, len)
END ReadBytes;
PROCEDURE Write* (VAR buf: Buffer; ch: CHAR);
BEGIN
ASSERT(buf.avail > 0, 100);
SYSTEM.PUT(buf.next, ch);
INC(buf.next); DEC(buf.avail); INC(buf.totalOut)
END Write;
PROCEDURE WriteBytes* (VAR buf: Buffer; CONST src: ARRAY OF CHAR; offset, len: LONGINT);
BEGIN
ASSERT((0 <= offset) & (0 < len) & (offset + len <= LEN(src)) & (len <= buf.avail), 100);
SYSTEM.MOVE(SYSTEM.ADR(src[offset]), buf.next, len);
INC(buf.next, len); DEC(buf.avail, len); INC(buf.totalOut, len)
END WriteBytes;
PROCEDURE Rewind* (VAR buf: Buffer; avail: LONGINT);
BEGIN
ASSERT(buf.avail = 0, 100);
ASSERT((0 <= avail) & (avail <= buf.size), 101);
buf.next := buf.adr; buf.avail := avail
END Rewind;
PROCEDURE Reread* (VAR buf: Buffer; offset: LONGINT);
BEGIN
ASSERT((0 <= offset) & (buf.avail + offset <= buf.size), 101);
DEC(buf.next, offset); INC(buf.avail, offset)
END Reread;
PROCEDURE Rewrite* (VAR buf: Buffer);
BEGIN
buf.next := buf.adr; buf.avail := buf.size
END Rewrite;
PROCEDURE Fill* (VAR buf: Buffer; CONST src: ARRAY OF CHAR; offset, size: LONGINT);
BEGIN
ASSERT((0 <= offset) & (0 < size) & (offset + size <= LEN(src)), 100);
ASSERT(buf.avail + size <= buf.size, 101);
IF buf.avail # 0 THEN
SYSTEM.MOVE(buf.next, buf.adr, buf.avail)
END;
buf.next := buf.adr + buf.avail;
SYSTEM.MOVE(SYSTEM.ADR(src[offset]), buf.next, size);
INC(buf.avail, size)
END Fill;
PROCEDURE Drain* (VAR buf: Buffer; VAR dst: ARRAY OF CHAR; offset, size: LONGINT);
VAR i, n: LONGINT; s, d: SYSTEM.ADDRESS; c: CHAR;
BEGIN
ASSERT((0 <= offset) & (0 < size) & (offset + size <= LEN(dst)), 100);
ASSERT(buf.avail + size <= buf.size, 101);
SYSTEM.MOVE(buf.adr, SYSTEM.ADR(dst[offset]), size);
n := buf.size - buf.avail - size; s := buf.adr + size; d := buf.adr;
FOR i := 0 TO n - 1 DO SYSTEM.GET( s + i, c ); SYSTEM.PUT( d + i, c ) END;
INC(buf.avail, size); DEC(buf.next, size);
END Drain;
END ZlibBuffers.