1 /**********************************************************
2 * Version $Id$
3 *********************************************************/
4
5 ///////////////////////////////////////////////////////////
6 // //
7 // SAGA //
8 // //
9 // System for Automated Geoscientific Analyses //
10 // //
11 // Application Programming Interface //
12 // //
13 // Library: SAGA_API //
14 // //
15 //-------------------------------------------------------//
16 // //
17 // api_memory.cpp //
18 // //
19 // Copyright (C) 2005 by Olaf Conrad //
20 // //
21 //-------------------------------------------------------//
22 // //
23 // This file is part of 'SAGA - System for Automated //
24 // Geoscientific Analyses'. //
25 // //
26 // This library is free software; you can redistribute //
27 // it and/or modify it under the terms of the GNU Lesser //
28 // General Public License as published by the Free //
29 // Software Foundation, either version 2.1 of the //
30 // License, or (at your option) any later version. //
31 // //
32 // This library is distributed in the hope that it will //
33 // be useful, but WITHOUT ANY WARRANTY; without even the //
34 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
35 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
36 // License for more details. //
37 // //
38 // You should have received a copy of the GNU Lesser //
39 // General Public License along with this program; if //
40 // not, see <http://www.gnu.org/licenses/>. //
41 // //
42 //-------------------------------------------------------//
43 // //
44 // contact: Olaf Conrad //
45 // Institute of Geography //
46 // University of Goettingen //
47 // Goldschmidtstr. 5 //
48 // 37077 Goettingen //
49 // Germany //
50 // //
51 // e-mail: oconrad@saga-gis.org //
52 // //
53 ///////////////////////////////////////////////////////////
54
55 //---------------------------------------------------------
56
57
58 ///////////////////////////////////////////////////////////
59 // //
60 // //
61 // //
62 ///////////////////////////////////////////////////////////
63
64 //---------------------------------------------------------
65 #include "api_core.h"
66
67
68 ///////////////////////////////////////////////////////////
69 // //
70 // //
71 // //
72 ///////////////////////////////////////////////////////////
73
74 #ifndef _WINDOWS_
75
76 //---------------------------------------------------------
SG_Malloc(size_t size)77 void * SG_Malloc(size_t size)
78 {
79 return( malloc(size) );
80 }
81
82 //---------------------------------------------------------
SG_Calloc(size_t num,size_t size)83 void * SG_Calloc(size_t num, size_t size)
84 {
85 return( calloc(num, size) );
86 }
87
88 //---------------------------------------------------------
SG_Realloc(void * memblock,size_t new_size)89 void * SG_Realloc(void *memblock, size_t new_size)
90 {
91 return( realloc(memblock, new_size) );
92 }
93
94 //---------------------------------------------------------
SG_Free(void * memblock)95 void SG_Free(void *memblock)
96 {
97 if( memblock )
98 {
99 free(memblock);
100 }
101 }
102
103
104 ///////////////////////////////////////////////////////////
105 // //
106 // //
107 // //
108 ///////////////////////////////////////////////////////////
109
110 //---------------------------------------------------------
111 // Due to a bad 'feature' in the realloc routine of MS's
112 // MSVCRT (C-Runtime-Library), we recommend to use our own
113 // memory allocation routines...
114
115 #else // ifndef _WINDOWS_
116
SG_Malloc(size_t size)117 void * SG_Malloc(size_t size)
118 {
119 return( HeapAlloc(GetProcessHeap(), 0, size) );
120 }
121
SG_Calloc(size_t num,size_t size)122 void * SG_Calloc(size_t num, size_t size)
123 {
124 return( HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, num * size) );
125 }
126
SG_Realloc(void * memblock,size_t new_size)127 void * SG_Realloc(void *memblock, size_t new_size)
128 {
129 if( new_size > 0 )
130 {
131 if( memblock )
132 {
133 return( HeapReAlloc(GetProcessHeap(), 0, memblock, new_size) );
134 }
135 else
136 {
137 return( HeapAlloc(GetProcessHeap(), 0, new_size) );
138 }
139 }
140 else
141 {
142 SG_Free(memblock);
143
144 return( NULL );
145 }
146 }
147
SG_Free(void * memblock)148 void SG_Free(void *memblock)
149 {
150 if( memblock )
151 {
152 HeapFree(GetProcessHeap(), 0, memblock);
153 }
154 }
155
156 #endif // ifndef _WINDOWS_
157
158
159 ///////////////////////////////////////////////////////////
160 // //
161 // //
162 // //
163 ///////////////////////////////////////////////////////////
164
165 //---------------------------------------------------------
SG_Swap_Bytes(void * Buffer,int nBytes)166 void SG_Swap_Bytes(void *Buffer, int nBytes)
167 {
168 char Byte, *pA, *pB;
169
170 pA = (char *)Buffer;
171 pB = pA + nBytes - 1;
172
173 while( pA < pB )
174 {
175 Byte = *pA;
176 *(pA++) = *pB;
177 *(pB--) = Byte;
178 }
179 }
180
181
182 ///////////////////////////////////////////////////////////
183 // //
184 // //
185 // //
186 ///////////////////////////////////////////////////////////
187
188 //---------------------------------------------------------
SG_Mem_Get_Int(const char * Buffer,bool bSwapBytes)189 int SG_Mem_Get_Int(const char *Buffer, bool bSwapBytes)
190 {
191 int Value = *(int *)Buffer;
192
193 if( bSwapBytes )
194 {
195 SG_Swap_Bytes(&Value, sizeof(Value));
196 }
197
198 return( Value );
199 }
200
SG_Mem_Set_Int(char * Buffer,int Value,bool bSwapBytes)201 void SG_Mem_Set_Int(char *Buffer, int Value, bool bSwapBytes)
202 {
203 if( bSwapBytes )
204 {
205 SG_Swap_Bytes(&Value, sizeof(Value));
206 }
207
208 *((int *)Buffer) = Value;
209 }
210
211 //---------------------------------------------------------
SG_Mem_Get_Double(const char * Buffer,bool bSwapBytes)212 double SG_Mem_Get_Double(const char *Buffer, bool bSwapBytes)
213 {
214 double Value = *(double *)Buffer;
215
216 if( bSwapBytes )
217 {
218 SG_Swap_Bytes(&Value, sizeof(Value));
219 }
220
221 return( Value );
222 }
223
SG_Mem_Set_Double(char * Buffer,double Value,bool bSwapBytes)224 void SG_Mem_Set_Double(char *Buffer, double Value, bool bSwapBytes)
225 {
226 if( bSwapBytes )
227 {
228 SG_Swap_Bytes(&Value, sizeof(Value));
229 }
230
231 *(double *)Buffer = Value;
232 }
233
234
235 ///////////////////////////////////////////////////////////
236 // //
237 // //
238 // //
239 ///////////////////////////////////////////////////////////
240
241 //---------------------------------------------------------
CSG_Array(void)242 CSG_Array::CSG_Array(void)
243 {
244 m_nBuffer = 0;
245 m_nValues = 0;
246 m_Values = NULL;
247
248 m_Value_Size = sizeof(char);
249 m_Growth = SG_ARRAY_GROWTH_0;
250 }
251
252 //---------------------------------------------------------
CSG_Array(const CSG_Array & Array)253 CSG_Array::CSG_Array(const CSG_Array &Array)
254 {
255 m_nBuffer = 0;
256 m_nValues = 0;
257 m_Values = NULL;
258
259 Create(Array);
260 }
261
Create(const CSG_Array & Array)262 void * CSG_Array::Create(const CSG_Array &Array)
263 {
264 Destroy();
265
266 m_Value_Size = Array.m_Value_Size;
267 m_Growth = Array.m_Growth;
268
269 if( Array.m_nValues > 0 && Get_Array(Array.m_nValues) )
270 {
271 memcpy(m_Values, Array.m_Values, Array.m_nValues * Array.m_Value_Size);
272 }
273
274 return( Get_Array() );
275 }
276
277 //---------------------------------------------------------
CSG_Array(size_t Value_Size,size_t nValues,TSG_Array_Growth Growth)278 CSG_Array::CSG_Array(size_t Value_Size, size_t nValues, TSG_Array_Growth Growth)
279 {
280 m_nBuffer = 0;
281 m_nValues = 0;
282 m_Values = NULL;
283
284 Create(Value_Size, nValues, Growth);
285 }
286
Create(size_t Value_Size,size_t nValues,TSG_Array_Growth Growth)287 void * CSG_Array::Create(size_t Value_Size, size_t nValues, TSG_Array_Growth Growth)
288 {
289 Destroy();
290
291 m_Value_Size = Value_Size;
292 m_Growth = Growth;
293
294 return( Get_Array(nValues) );
295 }
296
297 //---------------------------------------------------------
~CSG_Array(void)298 CSG_Array::~CSG_Array(void)
299 {
300 Destroy();
301 }
302
Destroy(void)303 void CSG_Array::Destroy(void)
304 {
305 m_nBuffer = 0;
306 m_nValues = 0;
307
308 SG_FREE_SAFE(m_Values);
309 }
310
311 //---------------------------------------------------------
Set_Growth(TSG_Array_Growth Growth)312 bool CSG_Array::Set_Growth(TSG_Array_Growth Growth)
313 {
314 m_Growth = Growth;
315
316 return( true );
317 }
318
319 //---------------------------------------------------------
Set_Array(size_t nValues,bool bShrink)320 bool CSG_Array::Set_Array(size_t nValues, bool bShrink)
321 {
322 if( nValues >= m_nValues && nValues <= m_nBuffer )
323 {
324 m_nValues = nValues;
325
326 return( true );
327 }
328
329 if( nValues < m_nValues && !bShrink )
330 {
331 m_nValues = nValues;
332
333 return( true );
334 }
335
336 if( nValues == 0 )
337 {
338 Destroy();
339
340 return( true );
341 }
342
343 //-----------------------------------------------------
344 size_t nBuffer;
345
346 switch( m_Growth )
347 {
348 default:
349 case SG_ARRAY_GROWTH_0:
350 nBuffer = nValues;
351 break;
352
353 case SG_ARRAY_GROWTH_1:
354 nBuffer = nValues < 100 ? nValues
355 : nValues < 1000 ? (1 + nValues / 10) * 10
356 : nValues < 10000 ? (1 + nValues / 100) * 100
357 : nValues < 100000 ? (1 + nValues / 1000) * 1000
358 : (1 + nValues / 10000) * 10000;
359 break;
360
361 case SG_ARRAY_GROWTH_2:
362 nBuffer = nValues < 10 ? nValues
363 : nValues < 100 ? (1 + nValues / 10) * 10
364 : nValues < 1000 ? (1 + nValues / 100) * 100
365 : nValues < 10000 ? (1 + nValues / 1000) * 1000
366 : (1 + nValues / 10000) * 10000;
367 break;
368
369 case SG_ARRAY_GROWTH_3:
370 nBuffer = nValues < 1000 ? (1 + nValues / 1000) * 1000
371 : nValues < 10000 ? (1 + nValues / 10000) * 10000
372 : nValues < 100000 ? (1 + nValues / 100000) * 100000
373 : (1 + nValues / 1000000) * 1000000;
374 break;
375 }
376
377 //-----------------------------------------------------
378 if( nBuffer == m_nBuffer )
379 {
380 m_nValues = nValues;
381
382 return( true );
383 }
384
385 //-----------------------------------------------------
386 void *Values = SG_Realloc(m_Values, nBuffer * m_Value_Size);
387
388 if( Values )
389 {
390 m_nBuffer = nBuffer;
391 m_nValues = nValues;
392 m_Values = Values;
393
394 return( true );
395 }
396
397 return( false );
398 }
399
400 //---------------------------------------------------------
Set_Array(size_t nValues,void ** pArray,bool bShrink)401 bool CSG_Array::Set_Array(size_t nValues, void **pArray, bool bShrink)
402 {
403 if( Set_Array(nValues, bShrink) )
404 {
405 *pArray = m_Values;
406
407 return( true );
408 }
409
410 *pArray = m_Values;
411
412 return( false );
413 }
414
415 //---------------------------------------------------------
Inc_Array(size_t nValues)416 bool CSG_Array::Inc_Array (size_t nValues)
417 {
418 return( Set_Array(m_nValues + nValues) );
419 }
420
Inc_Array(void ** pArray)421 bool CSG_Array::Inc_Array (void **pArray)
422 {
423 return( Set_Array(m_nValues + 1, pArray) );
424 }
425
426 //---------------------------------------------------------
Dec_Array(bool bShrink)427 bool CSG_Array::Dec_Array (bool bShrink)
428 {
429 return( m_nValues > 0 ? Set_Array(m_nValues - 1, bShrink) : false );
430 }
431
Dec_Array(void ** pArray,bool bShrink)432 bool CSG_Array::Dec_Array (void **pArray, bool bShrink)
433 {
434 return( m_nValues > 0 ? Set_Array(m_nValues - 1, pArray, bShrink) : false );
435 }
436
437
438 ///////////////////////////////////////////////////////////
439 // //
440 // //
441 // //
442 ///////////////////////////////////////////////////////////
443
444 //---------------------------------------------------------
Create(const CSG_Array_Pointer & Array)445 void ** CSG_Array_Pointer::Create(const CSG_Array_Pointer &Array)
446 {
447 m_Array.Create(Array.m_Array);
448
449 return( (void **)m_Array.Get_Array() );
450 }
451
452 //---------------------------------------------------------
Create(size_t nValues,TSG_Array_Growth Growth)453 void ** CSG_Array_Pointer::Create(size_t nValues, TSG_Array_Growth Growth)
454 {
455 m_Array.Create(sizeof(void *), nValues, Growth);
456
457 return( (void **)m_Array.Get_Array() );
458 }
459
460 //---------------------------------------------------------
Add(void * Value)461 bool CSG_Array_Pointer::Add(void *Value)
462 {
463 if( Inc_Array() )
464 {
465 Get_Array()[Get_Size() - 1] = Value;
466
467 return( true );
468 }
469
470 return( false );
471 }
472
473 //---------------------------------------------------------
Add(const CSG_Array_Pointer & Array)474 bool CSG_Array_Pointer::Add(const CSG_Array_Pointer &Array)
475 {
476 for(size_t i=0; i<Array.Get_Size(); i++)
477 {
478 if( Add(Array[i]) == false )
479 {
480 return( false );
481 }
482 }
483
484 return( true );
485 }
486
487 //---------------------------------------------------------
Del(int Index)488 bool CSG_Array_Pointer::Del(int Index)
489 {
490 return( Del((size_t)Index) );
491 }
492
493 //---------------------------------------------------------
Del(size_t Index)494 bool CSG_Array_Pointer::Del(size_t Index)
495 {
496 if( Index < Get_Size() )
497 {
498 for(size_t i=Index+1; i<Get_Size(); i++, Index++)
499 {
500 (*this)[Index] = (*this)[i];
501 }
502
503 return( Dec_Array() );
504 }
505
506 return( false );
507 }
508
509 //---------------------------------------------------------
Del(void * Value)510 size_t CSG_Array_Pointer::Del(void *Value)
511 {
512 size_t n = 0;
513
514 for(size_t i=Get_Size(); i>0; i--)
515 {
516 if( Value == (*this)[i - 1] && Del(i - 1) )
517 {
518 n++;
519 }
520 }
521
522 return( n );
523 }
524
525
526 ///////////////////////////////////////////////////////////
527 // //
528 // //
529 // //
530 ///////////////////////////////////////////////////////////
531
532 //---------------------------------------------------------
Create(const CSG_Array_Int & Array)533 int * CSG_Array_Int::Create(const CSG_Array_Int &Array)
534 {
535 m_Array.Create(Array.m_Array);
536
537 return( (int *)m_Array.Get_Array() );
538 }
539
540 //---------------------------------------------------------
Create(size_t nValues,TSG_Array_Growth Growth)541 int * CSG_Array_Int::Create(size_t nValues, TSG_Array_Growth Growth)
542 {
543 m_Array.Create(sizeof(int), nValues, Growth);
544
545 return( (int *)m_Array.Get_Array() );
546 }
547
548 //---------------------------------------------------------
Add(int Value)549 bool CSG_Array_Int::Add(int Value)
550 {
551 if( Inc_Array() )
552 {
553 Get_Array()[Get_Size() - 1] = Value;
554
555 return( true );
556 }
557
558 return( false );
559 }
560
561 //---------------------------------------------------------
Add(const CSG_Array_Int & Array)562 bool CSG_Array_Int::Add(const CSG_Array_Int &Array)
563 {
564 for(size_t i=0; i<Array.Get_Size(); i++)
565 {
566 if( Add(Array[i]) == false )
567 {
568 return( false );
569 }
570 }
571
572 return( true );
573 }
574
575 //---------------------------------------------------------
Assign(int Value)576 bool CSG_Array_Int::Assign(int Value)
577 {
578 for(size_t i=0; i<Get_Size(); i++)
579 {
580 Get_Array()[i] = Value;
581 }
582
583 return( true );
584 }
585
586
587 ///////////////////////////////////////////////////////////
588 // //
589 // //
590 // //
591 ///////////////////////////////////////////////////////////
592
593 //---------------------------------------------------------
CSG_Buffer(void)594 CSG_Buffer::CSG_Buffer(void)
595 {
596 m_Data = NULL;
597 m_Size = 0;
598 }
599
Create(void)600 bool CSG_Buffer::Create(void)
601 {
602 Destroy();
603
604 return( true );
605 }
606
607 //---------------------------------------------------------
CSG_Buffer(const CSG_Buffer & Buffer)608 CSG_Buffer::CSG_Buffer(const CSG_Buffer &Buffer)
609 {
610 m_Data = NULL;
611 m_Size = 0;
612
613 Create(Buffer);
614 }
615
Create(const CSG_Buffer & Buffer)616 bool CSG_Buffer::Create(const CSG_Buffer &Buffer)
617 {
618 return( Set_Data(Buffer.m_Data, Buffer.m_Size) );
619 }
620
621 //---------------------------------------------------------
CSG_Buffer(size_t Size)622 CSG_Buffer::CSG_Buffer(size_t Size)
623 {
624 m_Data = NULL;
625 m_Size = 0;
626
627 Create(Size);
628 }
629
Create(size_t Size)630 bool CSG_Buffer::Create(size_t Size)
631 {
632 return( Set_Size(Size) );
633 }
634
635 //---------------------------------------------------------
~CSG_Buffer(void)636 CSG_Buffer::~CSG_Buffer(void)
637 {
638 Destroy();
639 }
640
Destroy(void)641 void CSG_Buffer::Destroy(void)
642 {
643 if( m_Data )
644 {
645 SG_Free(m_Data);
646 }
647
648 m_Data = NULL;
649 m_Size = 0;
650 }
651
652 //---------------------------------------------------------
Set_Size(size_t Size,bool bShrink)653 bool CSG_Buffer::Set_Size(size_t Size, bool bShrink)
654 {
655 if( Size < 1 )
656 {
657 Destroy();
658 }
659 else if( Size > m_Size || (Size < m_Size && bShrink) )
660 {
661 char *Data = (char *)SG_Realloc(m_Data, Size * sizeof(char));
662
663 if( !Data )
664 {
665 return( false );
666 }
667
668 m_Data = Data;
669 m_Size = Size;
670 }
671
672 return( true );
673 }
674
675 //---------------------------------------------------------
Set_Data(const char * Data,size_t Size,bool bShrink)676 bool CSG_Buffer::Set_Data(const char *Data, size_t Size, bool bShrink)
677 {
678 if( !Data || !Size || !Set_Size(Size, bShrink) )
679 {
680 return( false );
681 }
682
683 memcpy(m_Data, Data, m_Size);
684
685 return( true );
686 }
687
688
689 ///////////////////////////////////////////////////////////
690 // //
691 // //
692 // //
693 ///////////////////////////////////////////////////////////
694
695 //---------------------------------------------------------
CSG_Bytes(void)696 CSG_Bytes::CSG_Bytes(void)
697 {
698 m_Bytes = NULL;
699 m_nBytes = 0;
700 m_nBuffer = 0;
701 m_Cursor = 0;
702 }
703
704 //---------------------------------------------------------
Create(void)705 bool CSG_Bytes::Create(void)
706 {
707 return( Destroy() );
708 }
709
710 //---------------------------------------------------------
CSG_Bytes(const CSG_Bytes & Bytes)711 CSG_Bytes::CSG_Bytes(const CSG_Bytes &Bytes)
712 {
713 m_Bytes = NULL;
714 m_nBytes = 0;
715 m_nBuffer = 0;
716 m_Cursor = 0;
717
718 Create(Bytes);
719 }
720
Create(const CSG_Bytes & Bytes)721 bool CSG_Bytes::Create(const CSG_Bytes &Bytes)
722 {
723 return( Assign(Bytes) );
724 }
725
726 //---------------------------------------------------------
CSG_Bytes(const BYTE * Bytes,int nBytes)727 CSG_Bytes::CSG_Bytes(const BYTE *Bytes, int nBytes)
728 {
729 m_Bytes = NULL;
730 m_nBytes = 0;
731 m_nBuffer = 0;
732 m_Cursor = 0;
733
734 Create(Bytes, nBytes);
735 }
736
Create(const BYTE * Bytes,int nBytes)737 bool CSG_Bytes::Create(const BYTE *Bytes, int nBytes)
738 {
739 Destroy();
740
741 return( Add((void *)Bytes, nBytes, false) );
742 }
743
744 //---------------------------------------------------------
~CSG_Bytes(void)745 CSG_Bytes::~CSG_Bytes(void)
746 {
747 Destroy();
748 }
749
Destroy(void)750 bool CSG_Bytes::Destroy(void)
751 {
752 if( m_Bytes )
753 {
754 SG_Free(m_Bytes);
755 }
756
757 m_Bytes = NULL;
758 m_nBytes = 0;
759 m_nBuffer = 0;
760 m_Cursor = 0;
761
762 return( true );
763 }
764
Clear(void)765 bool CSG_Bytes::Clear(void)
766 {
767 m_nBytes = 0;
768 m_Cursor = 0;
769
770 return( true );
771 }
772
773
774 ///////////////////////////////////////////////////////////
775 // //
776 ///////////////////////////////////////////////////////////
777
778 //---------------------------------------------------------
_Inc_Array(int nBytes)779 bool CSG_Bytes::_Inc_Array(int nBytes)
780 {
781 if( m_nBuffer < m_nBytes + nBytes )
782 {
783 int nBuffer = m_nBuffer + nBytes + 1024;
784 BYTE *Bytes = (BYTE *)SG_Realloc(m_Bytes, nBuffer * sizeof(BYTE));
785
786 if( !Bytes )
787 {
788 return( false );
789 }
790
791 m_Bytes = Bytes;
792 m_nBuffer = nBuffer;
793 }
794
795 m_nBytes += nBytes;
796
797 return( true );
798 }
799
800
801 ///////////////////////////////////////////////////////////
802 // //
803 ///////////////////////////////////////////////////////////
804
805 //---------------------------------------------------------
Assign(const CSG_Bytes & Bytes)806 bool CSG_Bytes::Assign(const CSG_Bytes &Bytes)
807 {
808 Destroy();
809
810 if( _Inc_Array(Bytes.m_nBytes) )
811 {
812 memcpy(m_Bytes, Bytes.m_Bytes, m_nBytes);
813
814 return( true );
815 }
816
817 return( false );
818 }
819
820
821 ///////////////////////////////////////////////////////////
822 // //
823 ///////////////////////////////////////////////////////////
824
825 //---------------------------------------------------------
Add(const CSG_Bytes & Bytes)826 bool CSG_Bytes::Add(const CSG_Bytes &Bytes)
827 {
828 return( Add(Bytes.m_Bytes, Bytes.m_nBytes, false) );
829 }
830
831 //---------------------------------------------------------
Add(void * Bytes,int nBytes,bool bSwapBytes)832 bool CSG_Bytes::Add(void *Bytes, int nBytes, bool bSwapBytes)
833 {
834 int Offset = m_nBytes;
835
836 if( _Inc_Array(nBytes) )
837 {
838 memcpy(m_Bytes + Offset, Bytes, nBytes);
839
840 if( bSwapBytes )
841 {
842 SG_Swap_Bytes(m_Bytes + Offset, nBytes);
843 }
844
845 return( true );
846 }
847
848 return( false );
849 }
850
851
852 ///////////////////////////////////////////////////////////
853 // //
854 ///////////////////////////////////////////////////////////
855
856 //---------------------------------------------------------
SG_Hex_to_Byte(const SG_Char Hex)857 BYTE SG_Hex_to_Byte (const SG_Char Hex)
858 {
859 switch( Hex )
860 {
861 case '1': return( 1 );
862 case '2': return( 2 );
863 case '3': return( 3 );
864 case '4': return( 4 );
865 case '5': return( 5 );
866 case '6': return( 6 );
867 case '7': return( 7 );
868 case '8': return( 8 );
869 case '9': return( 9 );
870 case 'a': case 'A': return( 10 );
871 case 'b': case 'B': return( 11 );
872 case 'c': case 'C': return( 12 );
873 case 'd': case 'D': return( 13 );
874 case 'e': case 'E': return( 14 );
875 case 'f': case 'F': return( 15 );
876 }
877
878 return( 0 );
879 }
880
881
882 ///////////////////////////////////////////////////////////
883 // //
884 ///////////////////////////////////////////////////////////
885
886 //---------------------------------------------------------
toHexString(void) const887 CSG_String CSG_Bytes::toHexString(void) const
888 {
889 CSG_String HexString;
890
891 for(int i=0; i<m_nBytes; i++)
892 {
893 HexString += CSG_String::Format(SG_T("%02X"), m_Bytes[i]);
894 }
895
896 return( HexString );
897 }
898
899 //---------------------------------------------------------
fromHexString(const CSG_String & HexString)900 bool CSG_Bytes::fromHexString(const CSG_String &HexString)
901 {
902 Destroy();
903
904 const SG_Char *s = HexString.c_str();
905
906 for(size_t i=0; i<HexString.Length(); i+=2, s+=2)
907 {
908 Add((BYTE)(SG_Hex_to_Byte(s[1]) + 16 * SG_Hex_to_Byte(s[0])));
909 }
910
911 return( true );
912 }
913
914
915 ///////////////////////////////////////////////////////////
916 // //
917 // //
918 // //
919 ///////////////////////////////////////////////////////////
920
921 //---------------------------------------------------------
CSG_Bytes_Array(void)922 CSG_Bytes_Array::CSG_Bytes_Array(void)
923 {
924 m_pBytes = NULL;
925 m_nBytes = 0;
926 m_nBuffer = 0;
927 }
928
929 //---------------------------------------------------------
~CSG_Bytes_Array(void)930 CSG_Bytes_Array::~CSG_Bytes_Array(void)
931 {
932 Destroy();
933 }
934
935 //---------------------------------------------------------
Destroy(void)936 bool CSG_Bytes_Array::Destroy(void)
937 {
938 if( m_pBytes )
939 {
940 for(int i=0; i<m_nBytes; i++)
941 {
942 delete(m_pBytes[i]);
943 }
944
945 SG_Free(m_pBytes);
946 }
947
948 m_pBytes = NULL;
949 m_nBytes = 0;
950 m_nBuffer = 0;
951
952 return( true );
953 }
954
955 //---------------------------------------------------------
Add(void)956 CSG_Bytes * CSG_Bytes_Array::Add(void)
957 {
958 if( m_nBytes >= m_nBuffer )
959 {
960 CSG_Bytes **pBytes = (CSG_Bytes **)SG_Realloc(m_pBytes, (m_nBuffer + 256) * sizeof(CSG_Bytes *));
961
962 if( !pBytes )
963 {
964 return( NULL );
965 }
966
967 m_pBytes = pBytes;
968 m_nBuffer += 256;
969 }
970
971 return( m_pBytes[m_nBytes++] = new CSG_Bytes );
972 }
973
974
975 ///////////////////////////////////////////////////////////
976 // //
977 // //
978 // //
979 ///////////////////////////////////////////////////////////
980
981 //---------------------------------------------------------
982