Subversion Repositories Kolibri OS

Rev

Rev 8097 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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