Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE CHUNKLISTS;
  9.  
  10. IMPORT LISTS, WR := WRITER;
  11.  
  12.  
  13. CONST
  14.  
  15.     LENOFBYTECHUNK = 64000;
  16.     LENOFINTCHUNK  = 16000;
  17.  
  18.  
  19. TYPE
  20.  
  21.     ANYLIST = POINTER TO RECORD (LISTS.LIST)
  22.  
  23.         length: INTEGER
  24.  
  25.     END;
  26.  
  27.     BYTELIST* = POINTER TO RECORD (ANYLIST) END;
  28.  
  29.     BYTECHUNK = POINTER TO RECORD (LISTS.ITEM)
  30.  
  31.         data:   ARRAY LENOFBYTECHUNK OF BYTE;
  32.         count:  INTEGER
  33.  
  34.     END;
  35.  
  36.  
  37.     INTLIST* = POINTER TO RECORD (ANYLIST) END;
  38.  
  39.     INTCHUNK = POINTER TO RECORD (LISTS.ITEM)
  40.  
  41.         data:   ARRAY LENOFINTCHUNK OF INTEGER;
  42.         count:  INTEGER
  43.  
  44.     END;
  45.  
  46.  
  47. PROCEDURE SetByte* (list: BYTELIST; idx: INTEGER; byte: BYTE);
  48. VAR
  49.     ChunkNum: INTEGER;
  50.     chunk:    BYTECHUNK;
  51.  
  52. BEGIN
  53.     ASSERT(idx >= 0);
  54.     ASSERT(list # NIL);
  55.  
  56.     ChunkNum := idx DIV LENOFBYTECHUNK;
  57.     idx      := idx MOD LENOFBYTECHUNK;
  58.  
  59.     chunk := list.first(BYTECHUNK);
  60.  
  61.     WHILE (chunk # NIL) & (ChunkNum > 0) DO
  62.         chunk := chunk.next(BYTECHUNK);
  63.         DEC(ChunkNum)
  64.     END;
  65.  
  66.     ASSERT(chunk # NIL);
  67.     ASSERT(idx < chunk.count);
  68.  
  69.     chunk.data[idx] := byte
  70. END SetByte;
  71.  
  72.  
  73. PROCEDURE GetByte* (list: BYTELIST; idx: INTEGER): BYTE;
  74. VAR
  75.     ChunkNum: INTEGER;
  76.     chunk:    BYTECHUNK;
  77.  
  78. BEGIN
  79.     ASSERT(idx >= 0);
  80.     ASSERT(list # NIL);
  81.  
  82.     ChunkNum := idx DIV LENOFBYTECHUNK;
  83.     idx      := idx MOD LENOFBYTECHUNK;
  84.  
  85.     chunk := list.first(BYTECHUNK);
  86.  
  87.     WHILE (chunk # NIL) & (ChunkNum > 0) DO
  88.         chunk := chunk.next(BYTECHUNK);
  89.         DEC(ChunkNum)
  90.     END;
  91.  
  92.     ASSERT(chunk # NIL);
  93.     ASSERT(idx < chunk.count)
  94.  
  95.     RETURN chunk.data[idx]
  96. END GetByte;
  97.  
  98.  
  99. PROCEDURE PushByte* (list: BYTELIST; byte: BYTE);
  100. VAR
  101.     chunk: BYTECHUNK;
  102.  
  103. BEGIN
  104.     ASSERT(list # NIL);
  105.  
  106.     chunk := list.last(BYTECHUNK);
  107.  
  108.     IF chunk.count = LENOFBYTECHUNK THEN
  109.         NEW(chunk);
  110.         chunk.count := 0;
  111.         LISTS.push(list, chunk)
  112.     END;
  113.  
  114.     chunk.data[chunk.count] := byte;
  115.     INC(chunk.count);
  116.  
  117.     INC(list.length)
  118. END PushByte;
  119.  
  120.  
  121. PROCEDURE WriteToFile* (file: WR.FILE; list: BYTELIST);
  122. VAR
  123.     chunk: BYTECHUNK;
  124.  
  125. BEGIN              
  126.     chunk := list.first(BYTECHUNK);
  127.     WHILE chunk # NIL DO
  128.         WR.Write(file, chunk.data, chunk.count);
  129.         chunk := chunk.next(BYTECHUNK)
  130.     END
  131. END WriteToFile;
  132.  
  133.  
  134. PROCEDURE CreateByteList* (): BYTELIST;
  135. VAR
  136.     bytelist: BYTELIST;
  137.     list:     LISTS.LIST;
  138.     chunk:    BYTECHUNK;
  139.  
  140. BEGIN
  141.     NEW(bytelist);
  142.     list := LISTS.create(bytelist);
  143.     bytelist.length := 0;
  144.  
  145.     NEW(chunk);
  146.     chunk.count := 0;
  147.     LISTS.push(list, chunk)
  148.  
  149.     RETURN list(BYTELIST)
  150. END CreateByteList;
  151.  
  152.  
  153. PROCEDURE SetInt* (list: INTLIST; idx: INTEGER; int: INTEGER);
  154. VAR
  155.     ChunkNum: INTEGER;
  156.     chunk:    INTCHUNK;
  157.  
  158. BEGIN
  159.     ASSERT(idx >= 0);
  160.     ASSERT(list # NIL);
  161.  
  162.     ChunkNum := idx DIV LENOFINTCHUNK;
  163.     idx      := idx MOD LENOFINTCHUNK;
  164.  
  165.     chunk := list.first(INTCHUNK);
  166.  
  167.     WHILE (chunk # NIL) & (ChunkNum > 0) DO
  168.         chunk := chunk.next(INTCHUNK);
  169.         DEC(ChunkNum)
  170.     END;
  171.  
  172.     ASSERT(chunk # NIL);
  173.     ASSERT(idx < chunk.count);
  174.  
  175.     chunk.data[idx] := int
  176. END SetInt;
  177.  
  178.  
  179. PROCEDURE GetInt* (list: INTLIST; idx: INTEGER): INTEGER;
  180. VAR
  181.     ChunkNum: INTEGER;
  182.     chunk:    INTCHUNK;
  183.  
  184. BEGIN
  185.     ASSERT(idx >= 0);
  186.     ASSERT(list # NIL);
  187.  
  188.     ChunkNum := idx DIV LENOFINTCHUNK;
  189.     idx      := idx MOD LENOFINTCHUNK;
  190.  
  191.     chunk := list.first(INTCHUNK);
  192.  
  193.     WHILE (chunk # NIL) & (ChunkNum > 0) DO
  194.         chunk := chunk.next(INTCHUNK);
  195.         DEC(ChunkNum)
  196.     END;
  197.  
  198.     ASSERT(chunk # NIL);
  199.     ASSERT(idx < chunk.count)
  200.  
  201.     RETURN chunk.data[idx]
  202. END GetInt;
  203.  
  204.  
  205. PROCEDURE PushInt* (list: INTLIST; int: INTEGER);
  206. VAR
  207.     chunk: INTCHUNK;
  208.  
  209. BEGIN
  210.     ASSERT(list # NIL);
  211.  
  212.     chunk := list.last(INTCHUNK);
  213.  
  214.     IF chunk.count = LENOFINTCHUNK THEN
  215.         NEW(chunk);
  216.         chunk.count := 0;
  217.         LISTS.push(list, chunk)
  218.     END;
  219.  
  220.     chunk.data[chunk.count] := int;
  221.     INC(chunk.count);
  222.  
  223.     INC(list.length)
  224. END PushInt;
  225.  
  226.  
  227. PROCEDURE CreateIntList* (): INTLIST;
  228. VAR
  229.     intlist:  INTLIST;
  230.     list:     LISTS.LIST;
  231.     chunk:    INTCHUNK;
  232.  
  233. BEGIN
  234.     NEW(intlist);
  235.     list := LISTS.create(intlist);
  236.     intlist.length := 0;
  237.  
  238.     NEW(chunk);
  239.     chunk.count := 0;
  240.     LISTS.push(list, chunk)
  241.  
  242.     RETURN list(INTLIST)
  243. END CreateIntList;
  244.  
  245.  
  246. PROCEDURE Length* (list: ANYLIST): INTEGER;
  247.     RETURN list.length
  248. END Length;
  249.  
  250.  
  251. END CHUNKLISTS.