1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: arr 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16 #include "arr.h"
17 #include "../bytecode/cmdlist.h"
18 #include "../vm/vmtype.h"
19 //! temporary
20 #include "../os/user/defines.h"
21 #include "../genteeapi/gentee.h"
22
23 //--------------------------------------------------------------------------
24 // Возвращается указатель на добавленный элемент
25
26 pvoid STDCALL arr_append( parr pa )
27 {
28 arr_reserve( pa, 1 );
29
30 mem_zero( buf_ptr( &pa->data ) + pa->data.use, pa->isize );
31 pa->data.use += pa->isize;
32
33 return buf_ptr( &pa->data ) + pa->data.use - pa->isize;
34 }
35
36 //--------------------------------------------------------------------------
37
38 uint STDCALL arr_appenditems( parr pa, uint count )
39 {
40 uint size = count * pa->isize;
41
42 arr_reserve( pa, count );
43
44 mem_zero( buf_ptr( &pa->data ) + pa->data.use, size );
45 pa->data.use += size;
46
47 // printf("Append %i size=%i\n", pa->data.use, pa->data.size );
48 return pa->data.use / pa->isize;
49 }
50
51 //--------------------------------------------------------------------------
52
53 void STDCALL arr_appendnum( parr pa, uint val )
54 {
55 *( puint )arr_append( pa ) = val;
56 }
57
58 //--------------------------------------------------------------------------
59
60 pvoid STDCALL arr_appendzero( parr pa )
61 {
62 return mem_zero( arr_append( pa ), pa->isize );
63 }
64
65 //--------------------------------------------------------------------------
66
67 void STDCALL arr_clear( parr pa )
68 {
69 buf_clear( &pa->data );
70 }
71
72 //--------------------------------------------------------------------------
73
74 uint STDCALL arr_count( parr pa )
75 {
76 return buf_len( &pa->data ) / pa->isize;
77 }
78
79 //--------------------------------------------------------------------------
80
81 void STDCALL arr_delete( parr pa )
82 {
83 puint ptr, end;
84
85 if ( pa->isobj )
86 {
87 ptr = ( puint )buf_ptr( &pa->data );
88 end = ( puint )(( pubyte )ptr + buf_len( &pa->data ));
89 while ( ptr < end )
90 {
91 mem_free( ( pvoid )*ptr );
92 ptr++;
93 }
94 }
95 buf_delete( &pa->data );
96 }
97
98 //--------------------------------------------------------------------------
99
100 uint STDCALL arr_getuint( parr pa, uint num )
101 {
102 return *( puint )( buf_ptr( &pa->data ) + num * pa->isize );
103 }
104
105 //--------------------------------------------------------------------------
106
107 uint STDCALL arr_getlast( parr pa )
108 {
109 return arr_getuint( pa, arr_count( pa ) - 1 );
110 }
111
112 //--------------------------------------------------------------------------
113
114 void STDCALL arr_init( parr pa, uint size )
115 {
116 buf_init( &pa->data );
117
118 pa->isobj = 0;
119 if ( !size )
120 {
121 size = sizeof( uint );
122 pa->isobj = 1;
123 }
124 pa->isize = size;
125 }
126
127 //--------------------------------------------------------------------------
128
129 uint STDCALL arr_pop( parr pa )
130 {
131 uint ret = arr_getlast( pa );
132
133 pa->data.use -= pa->isize;
134
135 return ret;
136 }
137
138 //--------------------------------------------------------------------------
139
140 pvoid STDCALL arr_ptr( parr pa, uint num )
141 {
142 return buf_ptr( &pa->data ) + num * pa->isize;
143 }
144
145 //--------------------------------------------------------------------------
146
147 pvoid STDCALL arr_top( parr pa )
148 {
149 uint len = buf_len( &pa->data );
150 if ( !len )
151 return 0;
152 return buf_ptr( &pa->data ) + len - pa->isize;
153 }
154
155 //--------------------------------------------------------------------------
156 // count - количество резервируемых элементов
157
158 void STDCALL arr_reserve( parr pa, uint count )
159 {
160 buf_expand( &pa->data, count * pa->isize );
161 }
162
163 //--------------------------------------------------------------------------
164
165 void STDCALL arr_setuint( parr pa, uint num, uint value )
166 {
167 *( puint )( buf_ptr( &pa->data ) + num * pa->isize ) = value;
168 }
169
170 //--------------------------------------------------------------------------
171 // count - количество резервируемых элементов
172
173 void STDCALL arr_step( parr pa, uint count )
174 {
175 pa->data.step = count * pa->isize;
176 }
177
178 //--------------------------------------------------------------------------
179
180 pgarr STDCALL garr_init( pgarr pga )
181 {
182 pga->itype = TUint;
183 pga->isize = sizeof( uint );
184 return pga;
185 }
186
187 /*-----------------------------------------------------------------------------
188 * Id: arr_del_1 FA
189 *
190 * Summary: The method removes items from the array.
191 *
192 * Params: from - The number of the first item being deleted (from 0).
193 count - The count of the items to be deleted.
194 *
195 * Return: #lng/retobj#
196 *
197 * Define: method arr arr.del( uint from, uint count )
198 *
199 -----------------------------------------------------------------------------*/
200
201 pgarr STDCALL garr_del( pgarr pga, uint from, uint number )
202 {
203 uint count = garr_count( pga );
204 pubyte data = buf_ptr( &pga->data );
205 uint i;
206
207 if ( from >= count )
208 return pga;
209 number = min( number, count - from );
210 data = buf_ptr( &pga->data ) + from * pga->isize;
211
212 if ( type_hasdelete( pga->itype ))
213 {
214 i = number;
215
216 while ( i-- )
217 {
218 type_delete( data, pga->itype );
219 data += pga->isize;
220 }
221 }
222 buf_del( &pga->data, from * pga->isize, number * pga->isize );
223
224 return pga;
225 }
226
227 //--------------------------------------------------------------------------
228
229 void STDCALL garr_delete( pgarr pga )
230 {
231 garr_del( pga, 0, garr_count( pga ));
232 }
233
234 pgarr STDCALL garr_clear( pgarr pga )
235 {
236 garr_delete( pga );
237 buf_free( &pga->data );
238
239 return pga;
240 }
241
242 /*-----------------------------------------------------------------------------
243 * Id: arr_oplen F4
244 *
245 * Summary: Get the count of items.
246 *
247 * Return: Count of array items.
248 *
249 * Define: operator uint *( arr left )
250 *
251 -----------------------------------------------------------------------------*/
252
253 uint STDCALL garr_count( pgarr pga )
254 {
255 return buf_len( &pga->data ) / pga->isize;
256 }
257
258 /*-----------------------------------------------------------------------------
259 * Id: arr_expand F2
260 *
261 * Summary: Add items to an array.
262 *
263 * Params: count - The number of items being added.
264 *
265 * Return: The index of the first added item.
266 *
267 * Define: method uint arr.expand( uint count )
268 *
269 -----------------------------------------------------------------------------*/
270
271 uint STDCALL garr_expand( pgarr pga, uint count )
272 {
273 return garr_insert( pga, garr_count( pga ), count );
274 }
275
276 /*-----------------------------------------------------------------------------
277 * Id: arr_insert_1 FA
278 *
279 * Summary: The method inserts elements into the array at the specified index.
280 *
281 * Params: from - The index of the first inserted element starts at zero.
282 count - The amount of elements are required to be inserted.
283 *
284 * Return: The index of the first inserted item.
285 *
286 * Define: method uint arr.insert( uint from, uint count )
287 *
288 -----------------------------------------------------------------------------*/
289
290 uint STDCALL garr_insert( pgarr pga, uint from, uint number )
291 {
292 uint size;
293 pubyte data;
294
295 if ( !number )
296 return from;
297
298 size = number * pga->isize;
299 from = min( from, garr_count( pga ));
300
301 buf_insert( &pga->data, from * pga->isize, NULL, size );
302
303 data = buf_ptr( &pga->data ) + from * pga->isize;
304
305 if ( type_hasinit( pga->itype ))
306 {
307 while ( number-- )
308 {
309 // print("INIT=%i from=%i type=%i\n", number, from, pga->itype );
310 type_init( data, pga->itype );
311 data += pga->isize;
312 }
313 }
314 else
315 mem_zero( data, size );
316
317 return from;
318 }
319
320 void STDCALL garr_array( pgarr pga, uint first )
321 {
322 uint count = garr_count( pga );
323
324 if ( first < count )
325 garr_del( pga, first, count - first );
326 else
327 if ( first > count )
328 garr_expand( pga, first - count );
329
330 mem_zeroui( ( puint )&pga->dim, MAX_MSR );
331 pga->dim[0] = first;
332 }
333
334 /*-----------------------------------------------------------------------------
335 * Id: arr_opof F4
336 *
337 * Summary: Specifying the type of items. You can specify #b(of) type when you
338 describe #b(arr) variable. In default, the type of the items
339 is #b(uint).
340 *
341 * Title: arr of type
342 *
343 * Define: method arr.oftype( uint itype )
344 *
345 -----------------------------------------------------------------------------*/
346
347 void STDCALL garr_oftype( pgarr pga, uint itype )
348 {
349 garr_clear( pga );
350 pga->itype = itype;
351 pga->isize = (( povmtype )PCMD( itype ))->size;
352 }
353
354 void STDCALL garr_array2( pgarr pga, uint first, uint second )
355 {
356 garr_array( pga, first * second );
357 pga->dim[0] = first;
358 pga->dim[1] = second;
359 }
360
361 void STDCALL garr_array3( pgarr pga, uint first, uint second, uint third )
362 {
363 garr_array( pga, first * second * third );
364 pga->dim[0] = first;
365 pga->dim[1] = second;
366 pga->dim[2] = third;
367 }
368
369 /*-----------------------------------------------------------------------------
370 * Id: arr_opind F4
371 *
372 * Summary: Getting #b('[i]') item of the array.
373 *
374 * Title: arr[i]
375 *
376 * Return: The #b('[i]') item of the array.
377 *
378 * Define: method uint arr.index( uint i )
379 *
380 -----------------------------------------------------------------------------*/
381
382 pubyte STDCALL garr_index( pgarr pga, uint first )
383 {
384 if ( first >= garr_count( pga ))
385 return 0;
386 return buf_ptr( &pga->data ) + first * pga->isize;
387 }
388
389 /*-----------------------------------------------------------------------------
390 * Id: arr_opind_1 FC
391 *
392 * Summary: Getting #b('[i,j]') item of the array.
393 *
394 * Title: arr[i,j]
395 *
396 * Return: The #b('[i,j]') item of the array.
397 *
398 * Define: method uint arr.index( uint i, uint j )
399 *
400 -----------------------------------------------------------------------------*/
401
402 pubyte STDCALL garr_index2( pgarr pga, uint first, uint second )
403 {
404 return garr_index( pga, first * pga->dim[1] + second );
405 }
406
407 /*-----------------------------------------------------------------------------
408 ** Id: arr_opind_2 FC
409 *
410 * Summary: Getting #b('[i,j,k]') item of the array.
411 *
412 * Title: arr[i,j,k]
413 *
414 * Return: The #b('[i,j,k]') item of the array.
415 *
416 * Define: method uint arr.index( uint i, uint j, uint k )
417 *
418 -----------------------------------------------------------------------------*/
419
420 pubyte STDCALL garr_index3( pgarr pga, uint first, uint second, uint third )
421 {
422 return garr_index( pga, first * pga->dim[1] * pga->dim[2] +
423 second * pga->dim[2] + third );
424 }
425
426
427 //--------------------------------------------------------------------------
428