| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- MODULE CHUNKLISTS;
- IMPORT LISTS, WR := WRITER;
- CONST
- LENOFBYTECHUNK = 65536;
- LENOFINTCHUNK = 16384;
- TYPE
- ANYLIST = POINTER TO RECORD (LISTS.LIST)
- length: INTEGER
- END;
- BYTELIST* = POINTER TO RECORD (ANYLIST) END;
- BYTECHUNK = POINTER TO RECORD (LISTS.ITEM)
- data: ARRAY LENOFBYTECHUNK OF BYTE;
- count: INTEGER
- END;
- INTLIST* = POINTER TO RECORD (ANYLIST) END;
- INTCHUNK = POINTER TO RECORD (LISTS.ITEM)
- data: ARRAY LENOFINTCHUNK OF INTEGER;
- count: INTEGER
- END;
- PROCEDURE SetByte* (list: BYTELIST; idx: INTEGER; byte: BYTE);
- VAR
- chunk: BYTECHUNK;
- item: LISTS.ITEM;
- BEGIN
- ASSERT(idx >= 0);
- ASSERT(list # NIL);
- item := LISTS.getidx(list, idx DIV LENOFBYTECHUNK);
- ASSERT(item # NIL);
- chunk := item(BYTECHUNK);
- idx := idx MOD LENOFBYTECHUNK;
- ASSERT(idx < chunk.count);
- chunk.data[idx] := byte
- END SetByte;
- PROCEDURE GetByte* (list: BYTELIST; idx: INTEGER): BYTE;
- VAR
- chunk: BYTECHUNK;
- item: LISTS.ITEM;
- BEGIN
- ASSERT(idx >= 0);
- ASSERT(list # NIL);
- item := LISTS.getidx(list, idx DIV LENOFBYTECHUNK);
- ASSERT(item # NIL);
- chunk := item(BYTECHUNK);
- idx := idx MOD LENOFBYTECHUNK;
- ASSERT(idx < chunk.count)
- RETURN chunk.data[idx]
- END GetByte;
- PROCEDURE PushByte* (list: BYTELIST; byte: BYTE);
- VAR
- chunk: BYTECHUNK;
- BEGIN
- ASSERT(list # NIL);
- chunk := list.last(BYTECHUNK);
- IF chunk.count = LENOFBYTECHUNK THEN
- NEW(chunk);
- chunk.count := 0;
- LISTS.push(list, chunk)
- END;
- chunk.data[chunk.count] := byte;
- INC(chunk.count);
- INC(list.length)
- END PushByte;
- PROCEDURE PushStr* (list: BYTELIST; str: ARRAY OF CHAR): INTEGER;
- VAR
- i, res: INTEGER;
- BEGIN
- res := list.length;
- i := 0;
- REPEAT
- PushByte(list, ORD(str[i]));
- INC(i)
- UNTIL str[i - 1] = 0X
- RETURN res
- END PushStr;
- PROCEDURE GetStr* (list: BYTELIST; pos: INTEGER; VAR str: ARRAY OF CHAR): BOOLEAN;
- VAR
- i: INTEGER;
- res: BOOLEAN;
- BEGIN
- res := FALSE;
- i := 0;
- WHILE (pos < list.length) & (i < LEN(str)) & ~res DO
- str[i] := CHR(GetByte(list, pos));
- res := str[i] = 0X;
- INC(pos);
- INC(i)
- END
- RETURN res
- END GetStr;
- PROCEDURE WriteToFile* (list: BYTELIST);
- VAR
- chunk: BYTECHUNK;
- BEGIN
- chunk := list.first(BYTECHUNK);
- WHILE chunk # NIL DO
- WR.Write(chunk.data, chunk.count);
- chunk := chunk.next(BYTECHUNK)
- END
- END WriteToFile;
- PROCEDURE CreateByteList* (): BYTELIST;
- VAR
- bytelist: BYTELIST;
- list: LISTS.LIST;
- chunk: BYTECHUNK;
- BEGIN
- NEW(bytelist);
- list := LISTS.create(bytelist);
- bytelist.length := 0;
- NEW(chunk);
- chunk.count := 0;
- LISTS.push(list, chunk)
- RETURN list(BYTELIST)
- END CreateByteList;
- PROCEDURE SetInt* (list: INTLIST; idx: INTEGER; int: INTEGER);
- VAR
- chunk: INTCHUNK;
- item: LISTS.ITEM;
- BEGIN
- ASSERT(idx >= 0);
- ASSERT(list # NIL);
- item := LISTS.getidx(list, idx DIV LENOFINTCHUNK);
- ASSERT(item # NIL);
- chunk := item(INTCHUNK);
- idx := idx MOD LENOFINTCHUNK;
- ASSERT(idx < chunk.count);
- chunk.data[idx] := int
- END SetInt;
- PROCEDURE GetInt* (list: INTLIST; idx: INTEGER): INTEGER;
- VAR
- chunk: INTCHUNK;
- item: LISTS.ITEM;
- BEGIN
- ASSERT(idx >= 0);
- ASSERT(list # NIL);
- item := LISTS.getidx(list, idx DIV LENOFINTCHUNK);
- ASSERT(item # NIL);
- chunk := item(INTCHUNK);
- idx := idx MOD LENOFINTCHUNK;
- ASSERT(idx < chunk.count)
- RETURN chunk.data[idx]
- END GetInt;
- PROCEDURE PushInt* (list: INTLIST; int: INTEGER);
- VAR
- chunk: INTCHUNK;
- BEGIN
- ASSERT(list # NIL);
- chunk := list.last(INTCHUNK);
- IF chunk.count = LENOFINTCHUNK THEN
- NEW(chunk);
- chunk.count := 0;
- LISTS.push(list, chunk)
- END;
- chunk.data[chunk.count] := int;
- INC(chunk.count);
- INC(list.length)
- END PushInt;
- PROCEDURE CreateIntList* (): INTLIST;
- VAR
- intlist: INTLIST;
- list: LISTS.LIST;
- chunk: INTCHUNK;
- BEGIN
- NEW(intlist);
- list := LISTS.create(intlist);
- intlist.length := 0;
- NEW(chunk);
- chunk.count := 0;
- LISTS.push(list, chunk)
- RETURN list(INTLIST)
- END CreateIntList;
- PROCEDURE Length* (list: ANYLIST): INTEGER;
- RETURN list.length
- END Length;
- END CHUNKLISTS.
|