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: buf 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov
13 *
14 * Summary: This file provides functionality for 'buf' type.
15 *
16 ******************************************************************************/
17
18 #include "buf.h"
19 #include "../genteeapi/gentee.h"
20 #include "../os/user/defines.h"
21
22 //--------------------------------------------------------------------------
23
24 pbuf STDCALL buf_alloc( pbuf pb, uint size )
25 {
26 // if ( !pb->data ) bufnum++;
27 mem_free( pb->data );
28
29 pb->data = mem_alloc( size );
30 pb->size = mem_getsize( pb->data );
31 pb->use = 0;
32
33 return pb;
34 }
35
36 pbuf STDCALL buf_array( pbuf pb, uint count )
37 {
38 buf_alloc( pb, count );
39 mem_zero( pb->data, count );
40 pb->use = count;
41 return pb;
42 }
43
44 /*-----------------------------------------------------------------------------
45 * Id: buf_clear F3
46 *
47 * Summary: Clear data in the object. This method sets the size of the binary
48 data to zero.
49 *
50 * Return: #lng/retobj#
51 *
52 * Define: method buf buf.clear()
53 *
54 -----------------------------------------------------------------------------*/
55
56 pbuf STDCALL buf_clear( pbuf pb )
57 {
58 pb->use = 0;
59 return pb;
60 }
61
62 /*-----------------------------------------------------------------------------
63 * Id: buf_free F3
64 *
65 * Summary: Memory deallocation. The method deallocates memory allocated for
66 the object and destroys all data.
67 *
68 * Return: #lng/retobj#
69 *
70 * Define: method buf buf.free()
71 *
72 -----------------------------------------------------------------------------*/
73
74 pbuf STDCALL buf_free( pbuf pb )
75 {
76 //if (pb->data) bufnum--;
77 mem_free( pb->data );
78
79 pb->data = NULL;
80 pb->size = 0;
81 pb->use = 0;
82 return pb;
83 }
84
85 /*-----------------------------------------------------------------------------
86 * Id: buf_opind F4
87 *
88 * Summary: Getting byte #b[#lgt(i)] from the buffer.
89 *
90 * Title: buf[ i ]
91 *
92 * Return: The value of byte i of the memory data.
93 *
94 * Define: method uint buf.index( uint i )
95 *
96 -----------------------------------------------------------------------------*/
97
98 pubyte STDCALL buf_index( pbuf pb, uint index )
99 {
100 return pb->data + index;
101 }
102
103 /*-----------------------------------------------------------------------------
104 * Id: buf_append F2
105 *
106 * Summary: Data addition. The method adds data to the object.
107 *
108 * Params: ptr - The pointer to the data to be added.
109 size - The size of the data being added.
110 *
111 * Return: #lng/retobj#
112 *
113 * Define: method buf buf.append( uint ptr, uint size )
114 *
115 -----------------------------------------------------------------------------*/
116
117 pbuf STDCALL buf_append( pbuf pb, pubyte src, uint size )
118 {
119 buf_expand( pb, size + 1 );
120 mem_copy( pb->data + pb->use, src, size );
121 pb->use += size;
122
123 return pb;
124 }
125
126 /*-----------------------------------------------------------------------------
127 *
128 * ID: buf_appendtype 19.10.06 0.0.A.
129 *
130 * Summary: Append a ubyte to buf
131 *
132 -----------------------------------------------------------------------------*/
133
134 pubyte STDCALL buf_appendtype( pbuf pb, uint size )
135 {
136 buf_expand( pb, size + 1 );
137 pb->use += size;
138
139 return pb->data + pb->use - size;
140 }
141
142 /*-----------------------------------------------------------------------------
143 * Id: buf_opadd F4
144 *
145 * Summary: Appending types to the buffer. Append #b(buf) to #b(buf) =>
146 #b( buf += buf ).
147 *
148 * Title: buf += type
149 *
150 * Return: The result buffer.
151 *
152 * Define: operator buf +=( buf left, buf right )
153 *
154 -----------------------------------------------------------------------------*/
155
156 pbuf STDCALL buf_add( pbuf pb, pbuf src )
157 {
158 return buf_append( pb, src->data, src->use );
159 }
160
161 /*-----------------------------------------------------------------------------
162 * Id: buf_opadd_1 FC
163 *
164 * Summary: Append #b(ubyte) to #b(buf) => #b( buf += ubyte ).
165 *
166 * Define: operator buf +=( buf left, ubyte right )
167 *
168 -----------------------------------------------------------------------------*/
169
170 pbuf STDCALL buf_appendch( pbuf pb, ubyte val )
171 {
172 buf_expand( pb, 1 );
173 *( pb->data + pb->use ) = val;
174 pb->use++;
175 return pb;
176 }
177
178 /*-----------------------------------------------------------------------------
179 * Id: buf_opadd_2 FC
180 *
181 * Summary: Append #b(uint) to #b(buf) => #b( buf += uint ).
182 *
183 * Define: operator buf +=( buf left, uint right )
184 *
185 -----------------------------------------------------------------------------*/
186
187 pbuf STDCALL buf_appenduint( pbuf pb, uint val )
188 {
189 buf_expand( pb, sizeof( uint ));
190 *( pint )( pb->data + pb->use ) = val;
191 pb->use += sizeof( uint );
192
193 return pb;
194 }
195
196 /*-----------------------------------------------------------------------------
197 * Id: buf_opadd_4 FC
198 *
199 * Summary: Append #b(ulong) to #b(buf) => #b( buf += ulong ).
200 *
201 * Define: operator buf +=( buf left, ulong right )
202 *
203 -----------------------------------------------------------------------------*/
204
205 pbuf STDCALL buf_appendulong( pbuf pb, ulong64 val )
206 {
207 buf_expand( pb, sizeof( ulong64 ));
208 *( pulong64 )( pb->data + pb->use ) = val;
209 pb->use += sizeof( ulong64 );
210
211 return pb;
212 }
213
214 /*-----------------------------------------------------------------------------
215 * Id: buf_opadd_3 FC
216 *
217 * Summary: Append #b(ushort) to #b(buf) => #b( buf += ushort ).
218 *
219 * Define: operator buf +=( buf left, ushort right )
220 *
221 -----------------------------------------------------------------------------*/
222
223 pbuf STDCALL buf_appendushort( pbuf pb, ushort val )
224 {
225 buf_expand( pb, sizeof( ushort ));
226 *( pushort )( pb->data + pb->use ) = val;
227 pb->use += sizeof( ushort );
228
229 return pb;
230 }
231
232 /*-----------------------------------------------------------------------------
233 * Id: buf_copy F2
234 *
235 * Summary: Copying. The method copies a binary data into the object.
236 *
237 * Params: ptr - The pointer to the data being copied.
238 size - The size of the data being copied.
239 *
240 * Return: #lng/retobj#
241 *
242 * Define: method buf buf.copy( uint ptr, uint size )
243 *
244 -----------------------------------------------------------------------------*/
245
246 pbuf STDCALL buf_copy( pbuf pb, pubyte src, uint size )
247 {
248 pb->use = 0;
249 buf_reserve( pb, size + 1 );
250 mem_copy( pb->data, src, size );
251 pb->use = size;
252
253 return pb;
254 }
255
256 /*-----------------------------------------------------------------------------
257 * Id: buf_opeq F4
258 *
259 * Summary: Copying data from one buffer into another.
260 *
261 * Return: The result buffer.
262 *
263 * Define: operator buf =( buf left, buf right )
264 *
265 -----------------------------------------------------------------------------*/
266
267 pbuf STDCALL buf_set( pbuf pb, pbuf src )
268 {
269 return buf_copy( pb, src->data, src->use );
270 }
271
272 //--------------------------------------------------------------------------
273
274 pbuf STDCALL buf_copyzero( pbuf pb, pubyte src )
275 {
276 return buf_copy( pb, src, mem_len( src ) + 1 );
277 }
278
279 //--------------------------------------------------------------------------
280
281 void STDCALL buf_delete( pbuf pb )
282 {
283 // if (pb->data) bufnum--;
284 mem_free( pb->data );
285 pb->data = NULL;
286 }
287
288 //--------------------------------------------------------------------------
289
290 pbuf STDCALL buf_init( pbuf pb )
291 {
292 mem_zero( pb, sizeof( buf ));
293 return pb;
294 }
295
296 /*-----------------------------------------------------------------------------
297 * Id: buf_insert_1 FA
298 *
299 * Summary: The method inserts one memory data into the buffer.
300 *
301 * Title: buf.insert
302 *
303 * Params: offset - The offset where data will be inserted. If the offset is /
304 greater than the size, data is added to the end to the buffer.
305 ptr - The pointer to the memory data to be inserted.
306 size - The size of the data to be inserted.
307 *
308 * Define: method buf buf.insert( uint offset, uint ptr, uint size )
309 *
310 -----------------------------------------------------------------------------*/
311
312 pbuf STDCALL buf_insert( pbuf pb, uint off, pubyte data, uint size )
313 {
314 if ( off > pb->use )
315 off = pb->use;
316
317 buf_expand( pb, size );
318 mem_move( pb->data + off + size, pb->data + off, pb->use - off );
319 if ( data )
320 mem_copy( pb->data + off, data, size );
321 pb->use += size;
322
323 return pb;
324 }
325
326 /*-----------------------------------------------------------------------------
327 * Id: buf_oplen F4
328 *
329 * Summary: Get the size of the memory being used.
330 *
331 * Return: The size of the used memory.
332 *
333 * Define: operator uint *( buf left )
334 *
335 -----------------------------------------------------------------------------*/
336
337 uint STDCALL buf_len( pbuf pb )
338 {
339 return pb->use;
340 }
341
342 /*-----------------------------------------------------------------------------
343 * Id: buf_ptr F3
344 *
345 * Summary: Get the pointer to memory.
346 *
347 * Return: The pointer to the allocated memory of the binary data.
348 *
349 * Define: method buf buf.ptr()
350 *
351 -----------------------------------------------------------------------------*/
352
353 pubyte STDCALL buf_ptr( pbuf pb )
354 {
355 return pb->data;
356 }
357
358 /*-----------------------------------------------------------------------------
359 * Id: buf_expand F2
360 *
361 * Summary: Expansion. The method increases the size of memory allocated for
362 the object.
363 *
364 * Params: size - The requested additional size of memory. It is an additional /
365 size to be reserved in the buffer.
366 *
367 * Return: #lng/retobj#
368 *
369 * Define: method buf buf.expand( uint size )
370 *
371 -----------------------------------------------------------------------------*/
372
373 pbuf STDCALL buf_expand( pbuf pb, uint size )
374 {
375 uint tmp;
376 pubyte old = pb->data;
377 uint use = pb->use;
378
379 size += use; // only size is additional size
380 if ( size <= pb->size )
381 return pb;
382
383 if ( !pb->step )
384 pb->step = max( size/2, 32 );
385 else
386 if ( pb->step < pb->size / 2 )
387 pb->step = pb->size / 2;
388
389 tmp = pb->size + pb->step;
390 if ( size < tmp )
391 size = tmp;
392 pb->data = 0;
393 buf_alloc( pb, size );
394 if ( old )
395 {
396 // bufnum--;
397 mem_copy( pb->data, old, use );
398 pb->use = use;
399 mem_free( old );
400 }
401
402 return pb;
403 }
404
405 /*-----------------------------------------------------------------------------
406 * Id: buf_opeqeq F4
407 *
408 * Summary: Comparison operation.
409 *
410 * Return: Returns #b(1) if the buffers are equal. Otherwise, it returns #b(0).
411 *
412 * Define: operator uint ==( buf left, buf right )
413 *
414 -----------------------------------------------------------------------------*/
415
416 uint STDCALL buf_isequal( pbuf left, pbuf right )
417 {
418 return left->use == right->use &&
419 !mem_cmp( left->data, right->data, left->use );
420 }
421
422 /*-----------------------------------------------------------------------------
423 * Id: buf_opeqeq_1 FC
424 *
425 * Summary: Comparison operation.
426 *
427 * Return: Returns #b(0) if the buffers are equal. Otherwise, it returns #b(1).
428 *
429 * Define: operator uint !=( buf left, buf right )
430 *
431 -----------------------------------------------------------------------------*/
432
433 /*-----------------------------------------------------------------------------
434 * Id: buf_reserve F2
435 *
436 * Summary: Memory reservation. The method increases the size of memory
437 allocated for the object.
438 *
439 * Params: size - The summary requested size of memory. If it is less than the /
440 current size, nothing happens. If the size is increased, the /
441 current data is saved.
442 *
443 * Return: #lng/retobj#
444 *
445 * Define: method buf buf.reserve( uint size )
446 *
447 -----------------------------------------------------------------------------*/
448
449 pbuf STDCALL buf_reserve( pbuf pb, uint size )
450 {
451 if ( size <= pb->size )
452 return pb;
453
454 return buf_expand( pb, size - pb->use );
455 }
456
457 /*-----------------------------------------------------------------------------
458 *
459 * ID: buf_setlen 19.10.06 0.0.A.
460 *
461 * Summary: Set the length of the buffer
462 *
463 -----------------------------------------------------------------------------*/
464
465 pbuf STDCALL buf_setlen( pbuf pb, uint len )
466 {
467 pb->use = len > pb->size ? pb->size : len ;
468
469 return pb;
470 }
471
472 /*-----------------------------------------------------------------------------
473 *
474 * ID: buf_subbuf 19.10.06 0.0.A.
475 *
476 * Summary: Get a subbuf
477 *
478 -----------------------------------------------------------------------------*/
479 /*
480 pbuf STDCALL buf_subbuf( pbuf dest, pbuf src, uint off, uint len )
481 {
482 uint slen = buf_len( src );
483
484 if ( len && off < slen )
485 {
486 if ( len > slen - off )
487 len = slen - off;
488 buf_copy( dest, buf_ptr( src ) + off, len );
489 }
490 else
491 buf_clear( dest );
492
493 return dest;
494 }
495 */
496 /*-----------------------------------------------------------------------------
497 * Id: buf_del F2
498 *
499 * Summary: Data deletion. The method deletes part of the buffer.
500 *
501 * Params: offset - The offset of the data being deleted.
502 size - The size of the data being deleted.
503 *
504 * Return: #lng/retobj#
505 *
506 * Define: method buf buf.del( uint offset, uint size )
507 *
508 -----------------------------------------------------------------------------*/
509
510 pbuf STDCALL buf_del( pbuf pb, uint off, uint size )
511 {
512 uint tmp;
513
514 if ( !size || off > pb->use )
515 return pb;
516
517 tmp = pb->use - off;
518
519 if ( size > tmp )
520 size = tmp;
521
522 mem_move( pb->data + off, pb->data + off + size, tmp - size );
523 pb->use -= size;
524
525 return pb;
526 }
527
528 /*-----------------------------------------------------------------------------
529 ** Id: buf_findch F2
530 *
531 * Summary: Find a byte in a binary data.
532 *
533 * Params: offset - The offset to start searching from.
534 ch - A unsigned byte to be searched.
535 *
536 * Return: The offset of the byte if it is found. If the byte is not found, the
537 size of the buffer is returned.
538 *
539 * Define: method uint buf.findch( uint offset, uint ch )
540 *
541 -----------------------------------------------------------------------------*/
542
543 uint STDCALL buf_find( pbuf ps, uint offset, ubyte symbol )
544 {
545 pubyte cur = ps->data + offset;
546 pubyte end = ps->data + buf_len( ps );
547
548 while ( cur < end )
549 {
550 if ( *cur == symbol )
551 break;
552 cur++;
553 }
554
555 return ( cur < end ? cur - ps->data : buf_len( ps ));
556 }
557
558 /*-----------------------------------------------------------------------------
559 *
560 * ID: buf_find 19.10.06 0.0.A.
561 *
562 * Summary: Find the ushort in the buf
563 *
564 -----------------------------------------------------------------------------*/
565
566 uint STDCALL buf_findsh( pbuf ps, uint offset, ushort val )
567 {
568 pushort cur = ( pushort )( ps->data + ( offset << 1 ));
569 pushort end = ( pushort )(ps->data + buf_len( ps ));
570
571 while ( cur < end )
572 {
573 if ( *cur == val )
574 break;
575 cur++;
576 }
577
578 return ( cur < end ? (( pubyte )cur - ps->data ) >> 1 :
579 ( buf_len( ps ) >> 1 ) - 1 );
580 }