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