1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //           Application Programming Interface           //
9 //                                                       //
10 //                  Library: SAGA_API                    //
11 //                                                       //
12 //-------------------------------------------------------//
13 //                                                       //
14 //                    api_string.cpp                     //
15 //                                                       //
16 //          Copyright (C) 2005 by Olaf Conrad            //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'.                              //
22 //                                                       //
23 // This library is free software; you can redistribute   //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free       //
26 // Software Foundation, either version 2.1 of the        //
27 // License, or (at your option) any later version.       //
28 //                                                       //
29 // This library is distributed in the hope that it will  //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details.                             //
34 //                                                       //
35 // You should have received a copy of the GNU Lesser     //
36 // General Public License along with this program; if    //
37 // not, see <http://www.gnu.org/licenses/>.              //
38 //                                                       //
39 //-------------------------------------------------------//
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Goettingen               //
44 //                Goldschmidtstr. 5                      //
45 //                37077 Goettingen                       //
46 //                Germany                                //
47 //                                                       //
48 //    e-mail:     oconrad@saga-gis.org                   //
49 //                                                       //
50 ///////////////////////////////////////////////////////////
51 
52 //---------------------------------------------------------
53 #include <math.h>
54 
55 #include <wx/string.h>
56 #include <wx/datetime.h>
57 #include <wx/tokenzr.h>
58 #include <wx/wxcrt.h>
59 #include <wx/wxcrtvararg.h>
60 #include <wx/convauto.h>
61 
62 #include "api_core.h"
63 #include "mat_tools.h"
64 
65 
66 ///////////////////////////////////////////////////////////
67 //														 //
68 //														 //
69 //														 //
70 ///////////////////////////////////////////////////////////
71 
72 //---------------------------------------------------------
CSG_String(void)73 CSG_String::CSG_String(void)
74 {
75 	m_pString	= new wxString;
76 }
77 
CSG_String(const CSG_String & String)78 CSG_String::CSG_String(const CSG_String &String)
79 {
80 	m_pString	= new wxString(*String.m_pString);
81 }
82 
CSG_String(const char * String)83 CSG_String::CSG_String(const char *String)
84 {
85 	m_pString	= new wxString(String);
86 }
87 
CSG_String(const wchar_t * String)88 CSG_String::CSG_String(const wchar_t *String)
89 {
90 	m_pString	= new wxString(String);
91 }
92 
CSG_String(char Character,size_t nRepeat)93 CSG_String::CSG_String(char Character, size_t nRepeat)
94 {
95 	m_pString	= new wxString(Character, nRepeat);
96 }
97 
CSG_String(wchar_t Character,size_t nRepeat)98 CSG_String::CSG_String(wchar_t Character, size_t nRepeat)
99 {
100 	m_pString	= new wxString(Character, nRepeat);
101 }
102 
103 //---------------------------------------------------------
CSG_String(const class wxString * pString)104 CSG_String::CSG_String(const class wxString *pString)
105 {
106 	if( pString )
107 		m_pString	= new wxString(*pString);
108 	else
109 		m_pString	= new wxString;
110 }
111 
Create(const class wxString * pString)112 bool CSG_String::Create(const class wxString *pString)
113 {
114 	if( pString )
115 		*m_pString	= *pString;
116 	else
117 		m_pString->Clear();
118 
119 	return( true );
120 }
121 
122 //---------------------------------------------------------
~CSG_String(void)123 CSG_String::~CSG_String(void)
124 {
125 	delete(m_pString);
126 }
127 
128 
129 ///////////////////////////////////////////////////////////
130 //														 //
131 ///////////////////////////////////////////////////////////
132 
133 //---------------------------------------------------------
operator =(const CSG_String & String)134 CSG_String & CSG_String::operator = (const CSG_String &String)
135 {
136 	*m_pString	= *String.m_pString;
137 
138 	return( *this );
139 }
140 
operator =(const char * String)141 CSG_String & CSG_String::operator = (const char *String)
142 {
143 	*m_pString	= String;
144 
145 	return( *this );
146 }
147 
operator =(const wchar_t * String)148 CSG_String & CSG_String::operator = (const wchar_t *String)
149 {
150 	*m_pString	= String;
151 
152 	return( *this );
153 }
154 
operator =(char Character)155 CSG_String & CSG_String::operator = (char Character)
156 {
157 	*m_pString	= Character;
158 
159 	return( *this );
160 }
161 
operator =(wchar_t Character)162 CSG_String & CSG_String::operator = (wchar_t Character)
163 {
164 	*m_pString	= Character;
165 
166 	return( *this );
167 }
168 
169 
170 ///////////////////////////////////////////////////////////
171 //														 //
172 ///////////////////////////////////////////////////////////
173 
174 //---------------------------------------------------------
Length(void) const175 size_t CSG_String::Length(void)	const
176 {
177 	return( m_pString->Length() );
178 }
179 
180 //---------------------------------------------------------
is_Empty(void) const181 bool CSG_String::is_Empty(void)	const
182 {
183 	return( m_pString->IsEmpty() );
184 }
185 
186 
187 ///////////////////////////////////////////////////////////
188 //														 //
189 ///////////////////////////////////////////////////////////
190 
191 //---------------------------------------------------------
operator [](int i) const192 SG_Char CSG_String::operator [] (int i) const
193 {
194 	if( i >= 0 && i < (int)Length() )
195 	{
196 		return( m_pString->GetChar(i) );
197 	}
198 
199 	return( SG_T('\0') );
200 }
201 
operator [](size_t i) const202 SG_Char CSG_String::operator [] (size_t i) const
203 {
204 	if( i < Length() )
205 	{
206 		return( m_pString->GetChar(i) );
207 	}
208 
209 	return( SG_T('\0') );
210 }
211 
Get_Char(size_t i) const212 SG_Char CSG_String::Get_Char(size_t i)	const
213 {
214 	if( i < Length() )
215 	{
216 		return( m_pString->GetChar(i) );
217 	}
218 
219 	return( SG_T('\0') );
220 }
221 
222 //---------------------------------------------------------
Set_Char(size_t i,char Character)223 void CSG_String::Set_Char(size_t i, char Character)
224 {
225 	m_pString->SetChar(i, Character);
226 }
227 
Set_Char(size_t i,wchar_t Character)228 void CSG_String::Set_Char(size_t i, wchar_t Character)
229 {
230 	m_pString->SetChar(i, Character);
231 }
232 
233 
234 ///////////////////////////////////////////////////////////
235 //														 //
236 ///////////////////////////////////////////////////////////
237 
238 //---------------------------------------------------------
c_str(void) const239 const SG_Char * CSG_String::c_str(void) const
240 {
241 	return( m_pString->c_str() );
242 }
243 
244 //---------------------------------------------------------
b_str(void) const245 const char * CSG_String::b_str(void) const
246 {
247 	return( *m_pString );
248 }
249 
250 //---------------------------------------------------------
w_str(void) const251 const wchar_t * CSG_String::w_str(void) const
252 {
253 	return( m_pString->wc_str() );
254 }
255 
256 
257 ///////////////////////////////////////////////////////////
258 //														 //
259 ///////////////////////////////////////////////////////////
260 
261 //---------------------------------------------------------
Clear(void)262 void CSG_String::Clear(void)
263 {
264 	m_pString->Clear();
265 }
266 
267 
268 ///////////////////////////////////////////////////////////
269 //														 //
270 ///////////////////////////////////////////////////////////
271 
272 //---------------------------------------------------------
Format(const char * Format,...)273 CSG_String CSG_String::Format(const char *Format, ...)
274 {
275 	CSG_String	s;
276 
277 #ifdef _SAGA_LINUX
278 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
279 	va_list	argptr; va_start(argptr, _Format);
280 	s.m_pString->PrintfV(_Format, argptr);
281 #else
282 	va_list	argptr; va_start(argptr, Format);
283 	s.m_pString->PrintfV(Format, argptr);
284 #endif
285 
286 	va_end(argptr);
287 
288 	return( s );
289 }
290 
291 //---------------------------------------------------------
Format(const wchar_t * Format,...)292 CSG_String CSG_String::Format(const wchar_t *Format, ...)
293 {
294 	CSG_String	s;
295 
296 #ifdef _SAGA_LINUX
297 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
298 	va_list	argptr; va_start(argptr, _Format);
299 	s.m_pString->PrintfV(_Format, argptr);
300 #else
301 	va_list	argptr; va_start(argptr, Format);
302 	s.m_pString->PrintfV(Format, argptr);
303 #endif
304 
305 	va_end(argptr);
306 
307 	return( s );
308 }
309 
310 //---------------------------------------------------------
Printf(const char * Format,...)311 int CSG_String::Printf(const char *Format, ...)
312 {
313 #ifdef _SAGA_LINUX
314 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
315 	va_list	argptr; va_start(argptr, _Format);
316 	int Result	= m_pString->PrintfV(_Format, argptr);
317 #else
318 	va_list	argptr; va_start(argptr, Format);
319 	int Result	= m_pString->PrintfV(Format, argptr);
320 #endif
321 
322 	va_end(argptr);
323 
324 	return( Result );
325 }
326 
327 //---------------------------------------------------------
Printf(const wchar_t * Format,...)328 int CSG_String::Printf(const wchar_t *Format, ...)
329 {
330 #ifdef _SAGA_LINUX
331 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
332 	va_list	argptr; va_start(argptr, _Format);
333 	int Result	= m_pString->PrintfV(_Format, argptr);
334 #else
335 	va_list	argptr; va_start(argptr, Format);
336 	int Result	= m_pString->PrintfV(Format, argptr);
337 #endif
338 
339 	va_end(argptr);
340 
341 	return( Result );
342 }
343 
344 
345 ///////////////////////////////////////////////////////////
346 //														 //
347 ///////////////////////////////////////////////////////////
348 
349 //---------------------------------------------------------
Prepend(const CSG_String & String)350 CSG_String & CSG_String::Prepend(const CSG_String &String)
351 {
352 	m_pString->Prepend(*String.m_pString);
353 
354 	return( *this );
355 }
356 
357 //---------------------------------------------------------
Append(const CSG_String & String)358 CSG_String & CSG_String::Append(const CSG_String &String)
359 {
360 	m_pString->Append(*String.m_pString);
361 
362 	return( *this );
363 }
364 
365 //---------------------------------------------------------
Append(const char * String)366 CSG_String & CSG_String::Append(const char *String)
367 {
368 	m_pString->Append(String);
369 
370 	return( *this );
371 }
372 
373 //---------------------------------------------------------
Append(const wchar_t * String)374 CSG_String & CSG_String::Append(const wchar_t *String)
375 {
376 	m_pString->Append(String);
377 
378 	return( *this );
379 }
380 
381 //---------------------------------------------------------
Append(char Character,size_t nRepeat)382 CSG_String & CSG_String::Append(char Character, size_t nRepeat)
383 {
384 	m_pString->Append(Character, nRepeat);
385 
386 	return( *this );
387 }
388 
389 //---------------------------------------------------------
Append(wchar_t Character,size_t nRepeat)390 CSG_String & CSG_String::Append(wchar_t Character, size_t nRepeat)
391 {
392 	m_pString->Append(Character, nRepeat);
393 
394 	return( *this );
395 }
396 
397 //---------------------------------------------------------
operator +=(const CSG_String & String)398 void CSG_String::operator += (const CSG_String &String)
399 {
400 	*m_pString	+= *String.m_pString;
401 }
402 
operator +=(const char * String)403 void CSG_String::operator += (const char *String)
404 {
405 	*m_pString	+= String;
406 }
407 
operator +=(const wchar_t * String)408 void CSG_String::operator += (const wchar_t *String)
409 {
410 	*m_pString	+= String;
411 }
412 
operator +=(char Character)413 void CSG_String::operator += (char Character)
414 {
415 	*m_pString	+= Character;
416 }
417 
operator +=(wchar_t Character)418 void CSG_String::operator += (wchar_t Character)
419 {
420 	*m_pString	+= Character;
421 }
422 
423 
424 ///////////////////////////////////////////////////////////
425 //														 //
426 ///////////////////////////////////////////////////////////
427 
428 //---------------------------------------------------------
operator +(const CSG_String & String) const429 CSG_String CSG_String::operator + (const CSG_String &String) const
430 {
431 	CSG_String	s(*this);
432 
433 	s	+= String;
434 
435 	return( s );
436 }
437 
operator +(const char * String) const438 CSG_String CSG_String::operator + (const char *String) const
439 {
440 	CSG_String	s(*this);
441 
442 	s	+= String;
443 
444 	return( s );
445 }
446 
operator +(const wchar_t * String) const447 CSG_String CSG_String::operator + (const wchar_t *String) const
448 {
449 	CSG_String	s(*this);
450 
451 	s	+= String;
452 
453 	return( s );
454 }
455 
456 //---------------------------------------------------------
operator +(char Character) const457 CSG_String CSG_String::operator + (char Character) const
458 {
459 	CSG_String	s(*this);
460 
461 	s	+= Character;
462 
463 	return( s );
464 }
465 
operator +(wchar_t Character) const466 CSG_String CSG_String::operator + (wchar_t Character) const
467 {
468 	CSG_String	s(*this);
469 
470 	s	+= Character;
471 
472 	return( s );
473 }
474 
475 //---------------------------------------------------------
operator +(const char * A,const CSG_String & B)476 CSG_String		operator + (const char *A, const CSG_String &B)
477 {
478 	CSG_String	s(A);
479 
480 	s	+= B;
481 
482 	return( s );
483 }
484 
operator +(const wchar_t * A,const CSG_String & B)485 CSG_String		operator + (const wchar_t *A, const CSG_String &B)
486 {
487 	CSG_String	s(A);
488 
489 	s	+= B;
490 
491 	return( s );
492 }
493 
operator +(char A,const CSG_String & B)494 CSG_String		operator + (char A, const CSG_String &B)
495 {
496 	CSG_String	s(A);
497 
498 	s	+= B;
499 
500 	return( s );
501 }
502 
operator +(wchar_t A,const CSG_String & B)503 CSG_String		operator + (wchar_t A, const CSG_String &B)
504 {
505 	CSG_String	s(A);
506 
507 	s	+= B;
508 
509 	return( s );
510 }
511 
512 
513 ///////////////////////////////////////////////////////////
514 //														 //
515 ///////////////////////////////////////////////////////////
516 
517 //---------------------------------------------------------
Cmp(const CSG_String & String) const518 int CSG_String::Cmp(const CSG_String &String)	const
519 {
520 	return( m_pString->Cmp(String.c_str()) );
521 }
522 
523 //---------------------------------------------------------
CmpNoCase(const CSG_String & String) const524 int CSG_String::CmpNoCase(const CSG_String &String) const
525 {
526 	return( m_pString->CmpNoCase(String.c_str()) );
527 }
528 
529 //---------------------------------------------------------
is_Same_As(const CSG_String & String,bool bCase) const530 bool CSG_String::is_Same_As(const CSG_String &String, bool bCase) const
531 {
532 	return( m_pString->IsSameAs(*String.m_pString, bCase) );
533 }
534 
is_Same_As(char Character,bool bCase) const535 bool CSG_String::is_Same_As(char Character, bool bCase) const
536 {
537 	return( m_pString->IsSameAs(Character, bCase) );
538 }
539 
is_Same_As(wchar_t Character,bool bCase) const540 bool CSG_String::is_Same_As(wchar_t Character, bool bCase) const
541 {
542 	return( m_pString->IsSameAs(Character, bCase) );
543 }
544 
545 //---------------------------------------------------------
Make_Lower(void)546 CSG_String & CSG_String::Make_Lower(void)
547 {
548 	m_pString->MakeLower();
549 
550 	return( *this );
551 }
552 
553 //---------------------------------------------------------
Make_Upper(void)554 CSG_String & CSG_String::Make_Upper(void)
555 {
556 	m_pString->MakeUpper();
557 
558 	return( *this );
559 }
560 
561 ///////////////////////////////////////////////////////////
562 //														 //
563 ///////////////////////////////////////////////////////////
564 
565 //---------------------------------------------------------
Replace(const CSG_String & sOld,const CSG_String & sNew,bool bReplaceAll)566 size_t CSG_String::Replace(const CSG_String &sOld, const CSG_String &sNew, bool bReplaceAll)
567 {
568 	return( m_pString->Replace(*sOld.m_pString, *sNew.m_pString, bReplaceAll) );
569 }
570 
571 //---------------------------------------------------------
Remove(size_t pos)572 CSG_String & CSG_String::Remove(size_t pos)
573 {
574 	m_pString->Remove(pos);
575 
576 	return( *this );
577 }
578 
579 //---------------------------------------------------------
Remove(size_t pos,size_t len)580 CSG_String & CSG_String::Remove(size_t pos, size_t len)
581 {
582 	m_pString->Remove(pos, len);
583 
584 	return( *this );
585 }
586 
587 
588 ///////////////////////////////////////////////////////////
589 //														 //
590 ///////////////////////////////////////////////////////////
591 
592 //---------------------------------------------------------
Trim(bool fromRight)593 int CSG_String::Trim(bool fromRight)
594 {
595 	size_t	n	= m_pString->Length();
596 
597 	m_pString->Trim(fromRight);
598 
599 	return( (int)(n - m_pString->Length()) );
600 }
601 
602 //---------------------------------------------------------
Trim_Both(void)603 int CSG_String::Trim_Both(void)
604 {
605 	size_t	n	= m_pString->Length();
606 
607 	m_pString->Trim( true);
608 	m_pString->Trim(false);
609 
610 	return( (int)(n - m_pString->Length()) );
611 }
612 
613 
614 ///////////////////////////////////////////////////////////
615 //														 //
616 ///////////////////////////////////////////////////////////
617 
618 //---------------------------------------------------------
Find(char Character,bool fromEnd) const619 int CSG_String::Find(char Character, bool fromEnd) const
620 {
621 	return( m_pString->Find(Character, fromEnd) );
622 }
623 
Find(wchar_t Character,bool fromEnd) const624 int CSG_String::Find(wchar_t Character, bool fromEnd) const
625 {
626 	return( m_pString->Find(Character, fromEnd) );
627 }
628 
629 //---------------------------------------------------------
Find(const CSG_String & String) const630 int CSG_String::Find(const CSG_String &String) const
631 {
632 	return( m_pString->Find(*String.m_pString) );
633 }
634 
635 //---------------------------------------------------------
Contains(const CSG_String & String) const636 bool CSG_String::Contains(const CSG_String &String) const
637 {
638 	return( m_pString->Contains(*String.m_pString) );
639 }
640 
641 
642 ///////////////////////////////////////////////////////////
643 //														 //
644 ///////////////////////////////////////////////////////////
645 
646 //---------------------------------------------------------
AfterFirst(char Character) const647 CSG_String CSG_String::AfterFirst(char Character) const
648 {
649 	return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
650 }
651 
AfterFirst(wchar_t Character) const652 CSG_String CSG_String::AfterFirst(wchar_t Character) const
653 {
654 	return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
655 }
656 
657 //---------------------------------------------------------
AfterLast(char Character) const658 CSG_String CSG_String::AfterLast(char Character) const
659 {
660 	return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
661 }
662 
AfterLast(wchar_t Character) const663 CSG_String CSG_String::AfterLast(wchar_t Character) const
664 {
665 	return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
666 }
667 
668 //---------------------------------------------------------
BeforeFirst(char Character) const669 CSG_String CSG_String::BeforeFirst(char Character) const
670 {
671 	return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
672 }
673 
BeforeFirst(wchar_t Character) const674 CSG_String CSG_String::BeforeFirst(wchar_t Character) const
675 {
676 	return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
677 }
678 
679 //---------------------------------------------------------
BeforeLast(char Character) const680 CSG_String CSG_String::BeforeLast(char Character) const
681 {
682 	return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
683 }
684 
BeforeLast(wchar_t Character) const685 CSG_String CSG_String::BeforeLast(wchar_t Character) const
686 {
687 	return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
688 }
689 
690 
691 ///////////////////////////////////////////////////////////
692 //														 //
693 ///////////////////////////////////////////////////////////
694 
695 //---------------------------------------------------------
Right(size_t count) const696 CSG_String CSG_String::Right(size_t count) const
697 {
698 	return( CSG_String(m_pString->Right(count).c_str().AsWChar()) );
699 }
700 
701 //---------------------------------------------------------
Mid(size_t first,size_t count) const702 CSG_String CSG_String::Mid(size_t first, size_t count) const
703 {
704 	return( CSG_String(m_pString->Mid(first, count <= 0 ? Length() : count).c_str().AsWChar()) );
705 }
706 
707 //---------------------------------------------------------
Left(size_t count) const708 CSG_String CSG_String::Left(size_t count) const
709 {
710 	return( CSG_String(m_pString->Left(count).c_str().AsWChar()) );
711 }
712 
713 
714 ///////////////////////////////////////////////////////////
715 //														 //
716 ///////////////////////////////////////////////////////////
717 
718 //---------------------------------------------------------
is_Number(void) const719 bool CSG_String::is_Number(void) const
720 {
721 	return( m_pString->IsNumber() );
722 }
723 
724 //---------------------------------------------------------
asInt(void) const725 int CSG_String::asInt(void) const
726 {
727 	int		Value	= 0;
728 
729 	asInt(Value);
730 
731 	return( Value );
732 }
733 
asInt(int & Value) const734 bool CSG_String::asInt(int &Value) const
735 {
736 	const wxChar	*start = m_pString->c_str();
737 	wxChar			*end;
738 
739 	Value	= wxStrtol(start, &end, 10);
740 
741 	return( end > start );
742 }
743 
744 //---------------------------------------------------------
asDouble(void) const745 double CSG_String::asDouble(void) const
746 {
747 	double	Value	= 0.0;
748 
749 	asDouble(Value);
750 
751 	return( Value );
752 }
753 
asDouble(double & Value) const754 bool CSG_String::asDouble(double &Value) const
755 {
756 	const wxChar	*start = m_pString->c_str();
757 	wxChar			*end;
758 
759 	Value	= wxStrtod(start, &end);
760 
761 	return( end > start );
762 }
763 
764 
765 ///////////////////////////////////////////////////////////
766 //														 //
767 ///////////////////////////////////////////////////////////
768 
769 //---------------------------------------------------------
from_UTF8(const char * String,size_t Length)770 CSG_String CSG_String::from_UTF8(const char *String, size_t Length)
771 {
772 	CSG_String	s;
773 
774 	if( String )
775 	{
776 		if( !Length )
777 		{
778 			Length	= strlen(String);
779 		}
780 
781 		*s.m_pString	= wxString::FromUTF8(String, Length);
782 	}
783 
784 	return( s );
785 }
786 
787 //---------------------------------------------------------
788 /**
789 * This function creates a single char array and fills it
790 * with the UTF-8 representation of this string object.
791 * If successful pString will point to the address of the
792 * allocated memory. Freeing memory is in response of the
793 * calling function.
794 */
795 //---------------------------------------------------------
to_UTF8(char ** pString) const796 size_t CSG_String::to_UTF8(char **pString) const
797 {
798 	if( !is_Empty() )
799 	{
800 		const wxScopedCharBuffer	Buffer	= m_pString->utf8_str();
801 
802 		if( (*pString = (char *)SG_Malloc(Buffer.length())) != NULL )
803 		{
804 			memcpy(*pString, Buffer.data(), Buffer.length());
805 
806 			return( Buffer.length() );
807 		}
808 	}
809 
810 	*pString	= NULL;
811 
812 	return( 0 );
813 }
814 
815 //---------------------------------------------------------
to_UTF8(void) const816 CSG_Buffer CSG_String::to_UTF8(void) const
817 {
818 	CSG_Buffer	String;
819 
820 	if( !is_Empty() )
821 	{
822 		const wxScopedCharBuffer	Buffer	= m_pString->utf8_str();
823 
824 		String.Set_Data(Buffer.data(), Buffer.length() + 1);
825 	}
826 
827 	return( String );
828 }
829 
830 
831 ///////////////////////////////////////////////////////////
832 //														 //
833 ///////////////////////////////////////////////////////////
834 
835 //---------------------------------------------------------
836 /**
837 * This function creates a single char array and fills it
838 * with the multibyte representation of this string object.
839 * If successful pString will point to the address of the
840 * allocated memory. Freeing memory is in response of the
841 * calling function.
842 */
843 //---------------------------------------------------------
to_MBChar(char ** pString,int Encoding) const844 size_t CSG_String::to_MBChar(char **pString, int Encoding) const
845 {
846 	CSG_Buffer	String(to_MBChar(Encoding));
847 
848 	if( String.Get_Size() && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
849 	{
850 		memcpy(*pString, String.Get_Data(), String.Get_Size());
851 
852 		return( String.Get_Size() );
853 	}
854 
855 	*pString	= NULL;
856 
857 	return( 0 );
858 }
859 
860 //---------------------------------------------------------
to_MBChar(int Encoding) const861 CSG_Buffer CSG_String::to_MBChar(int Encoding) const
862 {
863 	CSG_Buffer	String;
864 
865 	if( !is_Empty() )
866 	{
867 		wxScopedCharBuffer	Buffer;
868 
869 		switch( Encoding )	// selecting the appropriate wxMBConv class
870 		{
871 		case SG_FILE_ENCODING_ANSI   : Buffer = m_pString->mb_str(wxConvLibc       ); break;
872 		case SG_FILE_ENCODING_UTF7   : Buffer = m_pString->mb_str(wxConvUTF7       ); break;
873 		case SG_FILE_ENCODING_UTF8   : Buffer = m_pString->mb_str(wxConvUTF8       ); break;
874 		case SG_FILE_ENCODING_UTF16LE: Buffer = m_pString->mb_str(wxMBConvUTF16LE()); break;
875 		case SG_FILE_ENCODING_UTF16BE: Buffer = m_pString->mb_str(wxMBConvUTF16BE()); break;
876 		case SG_FILE_ENCODING_UTF32LE: Buffer = m_pString->mb_str(wxMBConvUTF32LE()); break;
877 		case SG_FILE_ENCODING_UTF32BE: Buffer = m_pString->mb_str(wxMBConvUTF32BE()); break;
878 		default                      : Buffer = m_pString->mb_str(wxConvAuto     ()); break;
879 		}
880 
881 		String.Set_Data(Buffer.data(), Buffer.length());
882 	}
883 
884 	return( String );
885 }
886 
887 
888 ///////////////////////////////////////////////////////////
889 //														 //
890 ///////////////////////////////////////////////////////////
891 
892 //---------------------------------------------------------
893 /**
894   * This function creates a single char array and fills it
895   * with the ASCII representation of this string object.
896   * If successful pString will point to the address of the
897   * allocated memory. Freeing memory is in response of the
898   * calling function.
899 */
900 //---------------------------------------------------------
to_ASCII(char ** pString,char Replace) const901 bool CSG_String::to_ASCII(char **pString, char Replace)	const
902 {
903 	if( !is_Empty() )
904 	{
905 		#if wxCHECK_VERSION(3, 1, 0)
906 			const wxScopedCharBuffer	Buffer	= m_pString->ToAscii(Replace);
907 		#else
908 			const wxScopedCharBuffer	Buffer	= m_pString->ToAscii();
909 		#endif
910 
911 		if( (*pString = (char *)SG_Malloc(Buffer.length())) != NULL )
912 		{
913 			memcpy(*pString, Buffer.data(), Buffer.length());
914 
915 			return( true );
916 		}
917 	}
918 
919 	return( false );
920 }
921 
922 //---------------------------------------------------------
to_ASCII(char Replace) const923 CSG_Buffer CSG_String::to_ASCII(char Replace) const
924 {
925 	CSG_Buffer	String;
926 
927 	if( !is_Empty() )
928 	{
929 		#if wxCHECK_VERSION(3, 1, 0)
930 			const wxScopedCharBuffer	Buffer	= m_pString->ToAscii(Replace);
931 		#else
932 			const wxScopedCharBuffer	Buffer	= m_pString->ToAscii();
933 		#endif
934 
935 		String.Set_Data(Buffer.data(), Buffer.length());
936 	}
937 
938 	return( String );
939 }
940 
941 ///////////////////////////////////////////////////////////
942 //														 //
943 ///////////////////////////////////////////////////////////
944 
945 //---------------------------------------------------------
946 /**
947 * This function returns the string as an std::string in the
948 * current locale encoding. Note that if the conversion of
949 * the string contents to the current locale fails, the
950 * return string will be empty.
951 */
952 //---------------------------------------------------------
to_StdString(void) const953 std::string CSG_String::to_StdString(void) const
954 {
955     return( m_pString->ToStdString() );
956 }
957 
958 //---------------------------------------------------------
959 /**
960 * This function returns the string as an std::wstring.
961 */
962 //---------------------------------------------------------
to_StdWstring(void) const963 std::wstring CSG_String::to_StdWstring(void) const
964 {
965     return( m_pString->ToStdWstring() );
966 }
967 
968 
969 ///////////////////////////////////////////////////////////
970 //														 //
971 //														 //
972 //														 //
973 ///////////////////////////////////////////////////////////
974 
975 //---------------------------------------------------------
CSG_Strings(void)976 CSG_Strings::CSG_Strings(void)
977 {}
978 
979 //---------------------------------------------------------
CSG_Strings(const CSG_Strings & Strings)980 CSG_Strings::CSG_Strings(const CSG_Strings &Strings)
981 {
982 	Create(Strings);
983 }
984 
Create(const CSG_Strings & Strings)985 bool CSG_Strings::Create(const CSG_Strings &Strings)
986 {
987 	Destroy();
988 
989 	return( Add(Strings) );
990 }
991 
992 //---------------------------------------------------------
CSG_Strings(int nStrings,const SG_Char ** Strings)993 CSG_Strings::CSG_Strings(int nStrings, const SG_Char **Strings)
994 {
995 	for(int i=0; i<nStrings; i++)
996 	{
997 		Add(Strings[i]);
998 	}
999 }
1000 
1001 //---------------------------------------------------------
~CSG_Strings(void)1002 CSG_Strings::~CSG_Strings(void)
1003 {
1004 	Clear();
1005 }
1006 
1007 //---------------------------------------------------------
Destroy(void)1008 bool CSG_Strings::Destroy(void)
1009 {
1010 	for(size_t i=0; i<Get_Size(); i++)
1011 	{
1012 		delete((CSG_String *)m_Strings[i]);
1013 	}
1014 
1015 	m_Strings.Destroy();
1016 
1017 	return( true );
1018 }
1019 
1020 //---------------------------------------------------------
Add(const CSG_Strings & Strings)1021 bool CSG_Strings::Add(const CSG_Strings &Strings)
1022 {
1023 	for(size_t i=0; i<Strings.Get_Size(); i++)
1024 	{
1025 		Add(Strings[i]);
1026 	}
1027 
1028 	return( true );
1029 }
1030 
1031 //---------------------------------------------------------
Add(const CSG_String & String)1032 bool CSG_Strings::Add(const CSG_String &String)
1033 {
1034 	size_t	i	= Get_Size();
1035 
1036 	if( m_Strings.Inc_Array() )
1037 	{
1038 		m_Strings[i]	=  new CSG_String(String);
1039 
1040 		return( true );
1041 	}
1042 
1043 	return( false );
1044 }
1045 
1046 //---------------------------------------------------------
Ins(const CSG_String & String,size_t Index)1047 bool CSG_Strings::Ins(const CSG_String &String, size_t Index)
1048 {
1049 	if( Index >= Get_Size() )
1050 	{
1051 		return( Add(String) );
1052 	}
1053 
1054 	if( m_Strings.Inc_Array() )
1055 	{
1056 		for(size_t i=Get_Size()-1; i>Index; i--)
1057 		{
1058 			m_Strings[i]	= m_Strings[i - 1];
1059 		}
1060 
1061 		m_Strings[Index]	=  new CSG_String(String);
1062 
1063 		return( true );
1064 	}
1065 
1066 	return( false );
1067 }
1068 
1069 //---------------------------------------------------------
Del(size_t Index)1070 bool CSG_Strings::Del(size_t Index)
1071 {
1072 	if( Index >= Get_Size() )
1073 	{
1074 		return( false );
1075 	}
1076 
1077 	delete((CSG_String *)m_Strings[Index]);
1078 
1079 	for(size_t i=Index+1; i<Get_Size(); i++)
1080 	{
1081 		m_Strings[i - 1]	= m_Strings[i];
1082 	}
1083 
1084 	m_Strings.Dec_Array();
1085 
1086 	return( true );
1087 }
1088 
1089 //---------------------------------------------------------
Set_Count(size_t Count)1090 bool CSG_Strings::Set_Count(size_t Count)
1091 {
1092 	while( Del(Count) )	{}
1093 
1094 	for(size_t i=Get_Size(); i<Count; i++)
1095 	{
1096 		Add("");
1097 	}
1098 
1099 	return( true );
1100 }
1101 
1102 //---------------------------------------------------------
1103 class CSG_Index_Compare_Strings : public CSG_Index::CSG_Index_Compare
1104 {
1105 public:
1106 	CSG_String **m_Values; bool m_Ascending;
1107 
CSG_Index_Compare_Strings(CSG_String ** Values,bool Ascending)1108 	CSG_Index_Compare_Strings(CSG_String **Values, bool Ascending) : m_Values(Values), m_Ascending(Ascending) {}
1109 
Compare(const int _a,const int _b)1110 	virtual int			Compare		(const int _a, const int _b)
1111 	{
1112 		int	a	= m_Ascending ? _a : _b;
1113 		int	b	= m_Ascending ? _b : _a;
1114 
1115 		return( m_Values[a]->Cmp(*m_Values[b]) );
1116 	}
1117 };
1118 
1119 //---------------------------------------------------------
Sort(bool Ascending)1120 bool CSG_Strings::Sort(bool Ascending)
1121 {
1122 	if( Get_Size() < 2 )
1123 	{
1124 		return( true );
1125 	}
1126 
1127 	CSG_Index_Compare_Strings	Compare((CSG_String **)m_Strings.Get_Array(), Ascending);
1128 
1129 	CSG_Index	Index(Get_Count(), Compare);
1130 
1131 	CSG_Array_Pointer	Strings(m_Strings);
1132 
1133 	for(size_t i=0; i<Get_Size(); i++)
1134 	{
1135 		m_Strings[i]	= Strings[Index[i]];
1136 	}
1137 
1138 	return( true );
1139 }
1140 
1141 
1142 ///////////////////////////////////////////////////////////
1143 //														 //
1144 //														 //
1145 //														 //
1146 ///////////////////////////////////////////////////////////
1147 
1148 //---------------------------------------------------------
SG_is_Character_Numeric(int Character)1149 bool SG_is_Character_Numeric(int Character)
1150 {
1151 	switch( Character )
1152 	{
1153 	case '0':
1154 	case '1':
1155 	case '2':
1156 	case '3':
1157 	case '4':
1158 	case '5':
1159 	case '6':
1160 	case '7':
1161 	case '8':
1162 	case '9':
1163 	case '-':
1164 	case '+':
1165 	case '.':
1166 	case ',':
1167 	case 'e':
1168 	case 'E':
1169 		return( true );
1170 	}
1171 
1172 	return( false );
1173 }
1174 
1175 
1176 ///////////////////////////////////////////////////////////
1177 //														 //
1178 //														 //
1179 //														 //
1180 ///////////////////////////////////////////////////////////
1181 
1182 //---------------------------------------------------------
SG_Printf(const CSG_String & Format)1183 int				SG_Printf(const CSG_String &Format)
1184 {
1185 	return( SG_Printf(Format.c_str()) );
1186 }
1187 
SG_Printf(const char * Format,...)1188 int				SG_Printf(const char *Format, ...)
1189 {
1190 #ifdef _SAGA_LINUX
1191 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
1192 	va_list	argptr; va_start(argptr, _Format); int ret = wxVprintf(_Format, argptr); va_end(argptr); return( ret );
1193 #else
1194 	va_list	argptr; va_start(argptr,  Format); int ret = wxVprintf( Format, argptr); va_end(argptr); return( ret );
1195 #endif
1196 }
1197 
SG_Printf(const wchar_t * Format,...)1198 int				SG_Printf(const wchar_t *Format, ...)
1199 {
1200 #ifdef _SAGA_LINUX
1201 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
1202 	va_list	argptr; va_start(argptr, _Format); int ret = wxVprintf(_Format, argptr); va_end(argptr); return( ret );
1203 #else
1204 	va_list	argptr; va_start(argptr,  Format); int ret = wxVprintf( Format, argptr); va_end(argptr); return( ret );
1205 #endif
1206 }
1207 
1208 //---------------------------------------------------------
SG_FPrintf(FILE * Stream,const CSG_String & String)1209 int				SG_FPrintf(FILE *Stream, const CSG_String &String)
1210 {
1211 	return( SG_FPrintf(Stream, String.c_str()) );
1212 }
1213 
SG_FPrintf(FILE * Stream,const char * Format,...)1214 int				SG_FPrintf(FILE *Stream, const char *Format, ...)
1215 {
1216 #ifdef _SAGA_LINUX
1217 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
1218 	va_list	argptr; va_start(argptr, _Format); int ret = wxVfprintf(Stream, _Format, argptr); va_end(argptr); return( ret );
1219 #else
1220 	va_list	argptr; va_start(argptr,  Format); int ret = wxVfprintf(Stream,  Format, argptr); va_end(argptr); return( ret );
1221 #endif
1222 }
1223 
SG_FPrintf(FILE * Stream,const wchar_t * Format,...)1224 int				SG_FPrintf(FILE *Stream, const wchar_t *Format, ...)
1225 {
1226 #ifdef _SAGA_LINUX
1227 	wxString _Format(Format); _Format.Replace("%s", "%ls");	// workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
1228 	va_list	argptr; va_start(argptr, _Format); int ret = wxVfprintf(Stream, _Format, argptr); va_end(argptr); return( ret );
1229 #else
1230 	va_list	argptr; va_start(argptr,  Format); int ret = wxVfprintf(Stream,  Format, argptr); va_end(argptr); return( ret );
1231 #endif
1232 }
1233 
1234 
1235 ///////////////////////////////////////////////////////////
1236 //														 //
1237 //														 //
1238 //														 //
1239 ///////////////////////////////////////////////////////////
1240 
1241 //---------------------------------------------------------
SG_Get_CurrentTimeStr(bool bWithDate)1242 CSG_String		SG_Get_CurrentTimeStr(bool bWithDate)
1243 {
1244 	CSG_String	s;
1245 	wxDateTime	t;
1246 
1247 	t.SetToCurrent();
1248 
1249 	if( bWithDate )
1250 	{
1251 		s.Append(t.FormatISODate().wc_str());
1252 		s.Append(SG_T("/"));
1253 	}
1254 
1255 	s.Append(t.FormatISOTime().wc_str());
1256 
1257 	return( s );
1258 }
1259 
1260 
1261 ///////////////////////////////////////////////////////////
1262 //														 //
1263 //														 //
1264 //														 //
1265 ///////////////////////////////////////////////////////////
1266 
1267 //---------------------------------------------------------
SG_Double_To_Degree(double Value)1268 CSG_String		SG_Double_To_Degree(double Value)
1269 {
1270 	SG_Char		c;
1271 	int			d, h;
1272 	double		s;
1273 	CSG_String	String;
1274 
1275 	if( Value < 0.0 )
1276 	{
1277 		Value	= -Value;
1278 		c		= SG_T('-');
1279 	}
1280 	else
1281 	{
1282 		c		= SG_T('+');
1283 	}
1284 
1285 	Value	= fmod(Value, 360.0);
1286 	d		= (int)Value;
1287 	Value	= 60.0 * (Value - d);
1288 	h		= (int)Value;
1289 	Value	= 60.0 * (Value - h);
1290 	s		= Value;
1291 
1292 	String.Printf(SG_T("%c%03d\xb0%02d'%02.*f''"), c, d, h, SG_Get_Significant_Decimals(s), s);
1293 
1294 	return( String );
1295 }
1296 
1297 //---------------------------------------------------------
SG_Degree_To_Double(const CSG_String & String)1298 double			SG_Degree_To_Double(const CSG_String &String)
1299 {
1300 	double		d, h, s, sig;
1301 
1302 	sig	= 1.0;
1303 	d	= h	= s	= 0.0;
1304 
1305 	if( String.BeforeFirst('\xb0').asDouble(d) )
1306 	{
1307 		if( d < 0.0 )
1308 		{
1309 			sig	= -1.0;
1310 			d	= -d;
1311 		}
1312 
1313 		String.AfterFirst('\xb0').asDouble(h);
1314 		String.AfterFirst('\''  ).asDouble(s);
1315 	}
1316 	else
1317 	{
1318 		String.asDouble(d);
1319 	}
1320 
1321 	return( sig * (d + h / 60.0 + s / (60.0 * 60.0)) );
1322 }
1323 
1324 
1325 ///////////////////////////////////////////////////////////
1326 //														 //
1327 //														 //
1328 //														 //
1329 ///////////////////////////////////////////////////////////
1330 
1331 //---------------------------------------------------------
SG_Get_Significant_Decimals(double Value,int maxDecimals)1332 int				SG_Get_Significant_Decimals(double Value, int maxDecimals)
1333 {
1334 	int		Decimals;
1335 	double	Reminder;
1336 
1337 	Value	= fabs(Value);
1338 
1339 	for(Decimals=0; Decimals<maxDecimals; Decimals++)
1340 	{
1341 		Reminder	= Value - floor(Value);
1342 
1343 		if( Reminder == 0.0 )
1344 		{
1345 			return( Decimals );
1346 		}
1347 
1348 		Value	= 10.0 * Value;
1349 	}
1350 
1351 	return( maxDecimals );
1352 }
1353 
1354 
1355 ///////////////////////////////////////////////////////////
1356 //														 //
1357 //														 //
1358 //														 //
1359 ///////////////////////////////////////////////////////////
1360 
1361 //---------------------------------------------------------
SG_Flip_Decimal_Separators(CSG_String & String)1362 void			SG_Flip_Decimal_Separators(CSG_String &String)
1363 {
1364 	for(size_t i=0; i<String.Length(); i++)
1365 	{
1366 		switch( String[i] )
1367 		{
1368 		case SG_T('.'):	String.Set_Char(i, ',');	break;
1369 		case SG_T(','):	String.Set_Char(i, '.');	break;
1370 		}
1371 	}
1372 }
1373 
1374 
1375 ///////////////////////////////////////////////////////////
1376 //														 //
1377 //														 //
1378 //														 //
1379 ///////////////////////////////////////////////////////////
1380 
1381 //---------------------------------------------------------
1382 /**
1383   * Returns floating point number 'Value' as formatted string.
1384   * The format depends on the 'Precision' value.
1385   * If Precision is -99 (the default) it will simply use %f format.
1386   * If 'Precision' is -98 the string will always be formatted
1387   * with the %e format specification (i.e. scientific: d.dddd e dd).
1388   * If Precision is zero (= 0) no decimals will be printed
1389   * If Precision is positive (> 0) it specifies the fix number
1390   * of decimals ("%.*f", Precision, Value),
1391   * if negative only significant decimals will be plotted up to a
1392   * maximum of the absolute value of 'Precision' digits.
1393 */
1394 //---------------------------------------------------------
SG_Get_String(double Value,int Precision)1395 CSG_String		SG_Get_String(double Value, int Precision)
1396 {
1397 	CSG_String	s;
1398 
1399 	if     ( Precision == -99 )
1400 	{
1401 		s.Printf("%f", Value);
1402 	}
1403 	else if( Precision == -98 )
1404 	{
1405 		s.Printf("%e", Value);
1406 	}
1407 	else if( Precision ==   0 )
1408 	{
1409 		s.Printf("%d", (int)Value);
1410 	}
1411 	else if( Precision  >   0 )
1412 	{
1413 		s.Printf("%.*f", Precision, Value);
1414 	}
1415 	else // if( Precision < 0 )
1416 	{
1417 		Precision	= SG_Get_Significant_Decimals(Value, abs(Precision));
1418 
1419 		if( Precision == 0 )
1420 		{
1421 			s.Printf("%.0f", Value);
1422 		}
1423 		else // if( Precision > 0 )
1424 		{
1425 			s.Printf("%.*f", Precision, Value);
1426 
1427 			while( s.Length() > 1 && s[s.Length() - 1] == '0' )
1428 			{
1429 				s	= s.Left(s.Length() - 1);
1430 			}
1431 
1432 			if( s.Length() > 1 && (s[s.Length() - 1] == '.' || s[s.Length() - 1] == ',') )
1433 			{
1434 				s	= s.Left(s.Length() - 1);
1435 			}
1436 		}
1437 	}
1438 
1439 	s.Replace(",", ".");
1440 
1441 	return( s );
1442 }
1443 
1444 //---------------------------------------------------------
SG_Get_String(int Value,int Precision)1445 CSG_String		SG_Get_String(int Value, int Precision)
1446 {
1447 	if( Precision > 0 )
1448 	{
1449 		return( SG_Get_String((double)Value, Precision) );
1450 	}
1451 
1452 	if( Precision < 0 )
1453 	{
1454 		return( CSG_String::Format("%0*d", Precision, Value) );
1455 	}
1456 
1457 	return( CSG_String::Format("%d", Value) );
1458 }
1459 
1460 
1461 ///////////////////////////////////////////////////////////
1462 //														 //
1463 //														 //
1464 //														 //
1465 ///////////////////////////////////////////////////////////
1466 
1467 //---------------------------------------------------------
CSG_String_Tokenizer(void)1468 CSG_String_Tokenizer::CSG_String_Tokenizer(void)
1469 {
1470 	m_pTokenizer	= new wxStringTokenizer();
1471 }
1472 
1473 //---------------------------------------------------------
CSG_String_Tokenizer(const CSG_String & String,const CSG_String & Delimiters,TSG_String_Tokenizer_Mode Mode)1474 CSG_String_Tokenizer::CSG_String_Tokenizer(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
1475 {
1476 	m_pTokenizer	= new wxStringTokenizer();
1477 
1478 	Set_String(String, Delimiters, Mode);
1479 }
1480 
1481 //---------------------------------------------------------
~CSG_String_Tokenizer(void)1482 CSG_String_Tokenizer::~CSG_String_Tokenizer(void)
1483 {
1484 	delete(m_pTokenizer);
1485 }
1486 
1487 //---------------------------------------------------------
Get_Tokens_Count(void) const1488 size_t CSG_String_Tokenizer::Get_Tokens_Count(void)	const
1489 {
1490 	return( m_pTokenizer->CountTokens() );
1491 }
1492 
1493 //---------------------------------------------------------
Get_Last_Delimiter(void) const1494 SG_Char CSG_String_Tokenizer::Get_Last_Delimiter(void)	const
1495 {
1496 	return( m_pTokenizer->GetLastDelimiter() );
1497 }
1498 
1499 //---------------------------------------------------------
Get_Next_Token(void)1500 CSG_String CSG_String_Tokenizer::Get_Next_Token(void)
1501 {
1502 	wxString	s(m_pTokenizer->GetNextToken());
1503 
1504 	return( &s );
1505 }
1506 
1507 //---------------------------------------------------------
Get_Position(void) const1508 size_t CSG_String_Tokenizer::Get_Position(void)	const
1509 {
1510 	return( m_pTokenizer->GetPosition() );
1511 }
1512 
1513 //---------------------------------------------------------
Get_String(void) const1514 CSG_String CSG_String_Tokenizer::Get_String(void)	const
1515 {
1516 	wxString	s(m_pTokenizer->GetString());
1517 
1518 	return( &s );
1519 }
1520 
1521 //---------------------------------------------------------
Has_More_Tokens(void) const1522 bool CSG_String_Tokenizer::Has_More_Tokens(void)	const
1523 {
1524 	return( m_pTokenizer->HasMoreTokens() );
1525 }
1526 
1527 //---------------------------------------------------------
Set_String(const CSG_String & String,const CSG_String & Delimiters,TSG_String_Tokenizer_Mode Mode)1528 void CSG_String_Tokenizer::Set_String(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
1529 {
1530 	wxStringTokenizerMode	_Mode;
1531 
1532 	switch( Mode )
1533 	{
1534 	default:                     _Mode	= wxTOKEN_DEFAULT      ; break;
1535 	case SG_TOKEN_INVALID:       _Mode	= wxTOKEN_INVALID      ; break;
1536 	case SG_TOKEN_RET_EMPTY:     _Mode	= wxTOKEN_RET_EMPTY    ; break;
1537 	case SG_TOKEN_RET_EMPTY_ALL: _Mode	= wxTOKEN_RET_EMPTY_ALL; break;
1538 	case SG_TOKEN_RET_DELIMS:    _Mode	= wxTOKEN_RET_DELIMS   ; break;
1539 	case SG_TOKEN_STRTOK:        _Mode	= wxTOKEN_STRTOK       ; break;
1540 	}
1541 
1542 	m_pTokenizer->SetString(String.c_str(), Delimiters.c_str(), _Mode);
1543 }
1544 
1545 
1546 ///////////////////////////////////////////////////////////
1547 //														 //
1548 ///////////////////////////////////////////////////////////
1549 
1550 //---------------------------------------------------------
SG_String_Tokenize(const CSG_String & String,const CSG_String & Delimiters,TSG_String_Tokenizer_Mode Mode)1551 CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
1552 {
1553 	CSG_Strings	Strings;
1554 
1555 	CSG_String_Tokenizer	Tokenizer(String, Delimiters, Mode);
1556 
1557 	while( Tokenizer.Has_More_Tokens() )
1558 	{
1559 		Strings	+= Tokenizer.Get_Next_Token();
1560 	}
1561 
1562 	return( Strings );
1563 }
1564 
1565 
1566 ///////////////////////////////////////////////////////////
1567 //														 //
1568 //														 //
1569 //														 //
1570 ///////////////////////////////////////////////////////////
1571 
1572 //---------------------------------------------------------
1573