Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7983 leency 1
(*
7597 akron1 2
    BSD 2-Clause License
3
 
8859 leency 4
    Copyright (c) 2018-2021, Anton Krotov
7597 akron1 5
    All rights reserved.
6
*)
7
 
8
MODULE CHUNKLISTS;
9
 
10
IMPORT LISTS, WR := WRITER;
11
 
12
 
13
CONST
14
 
7983 leency 15
    LENOFBYTECHUNK = 65536;
16
    LENOFINTCHUNK  = 16384;
7597 akron1 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
8859 leency 49
    chunk: BYTECHUNK;
50
    item:  LISTS.ITEM;
7597 akron1 51
 
52
BEGIN
53
    ASSERT(idx >= 0);
54
    ASSERT(list # NIL);
55
 
8859 leency 56
    item := LISTS.getidx(list, idx DIV LENOFBYTECHUNK);
57
    ASSERT(item # NIL);
58
    chunk := item(BYTECHUNK);
59
    idx := idx MOD LENOFBYTECHUNK;
7597 akron1 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
8859 leency 67
    chunk: BYTECHUNK;
68
    item:  LISTS.ITEM;
7597 akron1 69
 
70
BEGIN
71
    ASSERT(idx >= 0);
72
    ASSERT(list # NIL);
73
 
8859 leency 74
    item := LISTS.getidx(list, idx DIV LENOFBYTECHUNK);
75
    ASSERT(item # NIL);
76
    chunk := item(BYTECHUNK);
77
    idx := idx MOD LENOFBYTECHUNK;
7597 akron1 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
 
7693 akron1 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
 
8097 maxcodehac 140
PROCEDURE WriteToFile* (list: BYTELIST);
7597 akron1 141
VAR
142
    chunk: BYTECHUNK;
143
 
7693 akron1 144
BEGIN
7597 akron1 145
    chunk := list.first(BYTECHUNK);
146
    WHILE chunk # NIL DO
8097 maxcodehac 147
        WR.Write(chunk.data, chunk.count);
7597 akron1 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
8859 leency 174
    chunk: INTCHUNK;
175
    item:  LISTS.ITEM;
7597 akron1 176
 
177
BEGIN
178
    ASSERT(idx >= 0);
179
    ASSERT(list # NIL);
180
 
8859 leency 181
    item := LISTS.getidx(list, idx DIV LENOFINTCHUNK);
182
    ASSERT(item # NIL);
183
    chunk := item(INTCHUNK);
184
    idx := idx MOD LENOFINTCHUNK;
7597 akron1 185
    ASSERT(idx < chunk.count);
186
    chunk.data[idx] := int
187
END SetInt;
188
 
189
 
190
PROCEDURE GetInt* (list: INTLIST; idx: INTEGER): INTEGER;
8859 leency 191
 
7597 akron1 192
VAR
8859 leency 193
    chunk: INTCHUNK;
194
    item:  LISTS.ITEM;
7597 akron1 195
 
196
BEGIN
197
    ASSERT(idx >= 0);
198
    ASSERT(list # NIL);
199
 
8859 leency 200
    item := LISTS.getidx(list, idx DIV LENOFINTCHUNK);
201
    ASSERT(item # NIL);
202
    chunk := item(INTCHUNK);
203
    idx := idx MOD LENOFINTCHUNK;
7597 akron1 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
 
7983 leency 255
END CHUNKLISTS.