SAGA API v9.10
Loading...
Searching...
No Matches
api_string.cpp
Go to the documentation of this file.
1
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// //
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
67// //
68// //
69// //
71
72//---------------------------------------------------------
74{
75 m_pString = new wxString;
76}
77
79{
80 m_pString = new wxString(*String.m_pString);
81}
82
83CSG_String::CSG_String(const char *String)
84{
85 m_pString = String ? new wxString(String) : new wxString;
86}
87
88CSG_String::CSG_String(const wchar_t *String)
89{
90 m_pString = String ? new wxString(String) : new wxString;
91}
92
93CSG_String::CSG_String(char Character, size_t nRepeat)
94{
95 m_pString = new wxString(Character, nRepeat);
96}
97
98CSG_String::CSG_String(wchar_t Character, size_t nRepeat)
99{
100 m_pString = new wxString(Character, nRepeat);
101}
102
103//---------------------------------------------------------
104CSG_String::CSG_String(const class wxString *String)
105{
106 m_pString = String ? new wxString(*String) : new wxString;
107}
108
109bool CSG_String::Create(const class wxString *pString)
110{
111 if( pString )
112 *m_pString = *pString;
113 else
114 m_pString->Clear();
115
116 return( true );
117}
118
119//---------------------------------------------------------
121{
122 delete(m_pString);
123}
124
125
127// //
129
130//---------------------------------------------------------
132{
133 *m_pString = *String.m_pString;
134
135 return( *this );
136}
137
139{
140 *m_pString = String;
141
142 return( *this );
143}
144
145CSG_String & CSG_String::operator = (const wchar_t *String)
146{
147 *m_pString = String;
148
149 return( *this );
150}
151
153{
154 *m_pString = Character;
155
156 return( *this );
157}
158
160{
161 *m_pString = Character;
162
163 return( *this );
164}
165
166
168// //
170
171//---------------------------------------------------------
172size_t CSG_String::Length(void) const
173{
174 return( m_pString->Length() );
175}
176
177//---------------------------------------------------------
178bool CSG_String::is_Empty(void) const
179{
180 return( m_pString->IsEmpty() );
181}
182
183
185// //
187
188//---------------------------------------------------------
190{
191 if( i >= 0 && i < (int)Length() )
192 {
193 return( m_pString->GetChar(i) );
194 }
195
196 return( SG_T('\0') );
197}
198
200{
201 if( i < Length() )
202 {
203 return( m_pString->GetChar(i) );
204 }
205
206 return( SG_T('\0') );
207}
208
210{
211 if( i < Length() )
212 {
213 return( m_pString->GetChar(i) );
214 }
215
216 return( SG_T('\0') );
217}
218
219//---------------------------------------------------------
220void CSG_String::Set_Char(size_t i, char Character)
221{
222 m_pString->SetChar(i, Character);
223}
224
225void CSG_String::Set_Char(size_t i, wchar_t Character)
226{
227 m_pString->SetChar(i, Character);
228}
229
230
232// //
234
235//---------------------------------------------------------
236const SG_Char * CSG_String::c_str(void) const
237{
238 return( m_pString->c_str() );
239}
240
241//---------------------------------------------------------
242const char * CSG_String::b_str(void) const
243{
244 return( *m_pString );
245}
246
247//---------------------------------------------------------
248const wchar_t * CSG_String::w_str(void) const
249{
250 return( m_pString->wc_str() );
251}
252
253
255// //
257
258//---------------------------------------------------------
260{
261 m_pString->Clear();
262}
263
264
266// //
268
269//---------------------------------------------------------
271{
272 CSG_String s;
273
274#ifdef _SAGA_LINUX
275 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
276 va_list argptr; va_start(argptr, _Format);
277 s.m_pString->PrintfV(_Format, argptr);
278#else
279 va_list argptr; va_start(argptr, Format);
280 s.m_pString->PrintfV(Format, argptr);
281#endif
282
283 va_end(argptr);
284
285 return( s );
286}
287
288//---------------------------------------------------------
290{
291 CSG_String s;
292
293#ifdef _SAGA_LINUX
294 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
295 va_list argptr; va_start(argptr, _Format);
296 s.m_pString->PrintfV(_Format, argptr);
297#else
298 va_list argptr; va_start(argptr, Format);
299 s.m_pString->PrintfV(Format, argptr);
300#endif
301
302 va_end(argptr);
303
304 return( s );
305}
306
307//---------------------------------------------------------
308int CSG_String::Printf(const char *Format, ...)
309{
310#ifdef _SAGA_LINUX
311 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
312 va_list argptr; va_start(argptr, _Format);
313 int Result = m_pString->PrintfV(_Format, argptr);
314#else
315 va_list argptr; va_start(argptr, Format);
316 int Result = m_pString->PrintfV(Format, argptr);
317#endif
318
319 va_end(argptr);
320
321 return( Result );
322}
323
324//---------------------------------------------------------
325int CSG_String::Printf(const wchar_t *Format, ...)
326{
327#ifdef _SAGA_LINUX
328 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
329 va_list argptr; va_start(argptr, _Format);
330 int Result = m_pString->PrintfV(_Format, argptr);
331#else
332 va_list argptr; va_start(argptr, Format);
333 int Result = m_pString->PrintfV(Format, argptr);
334#endif
335
336 va_end(argptr);
337
338 return( Result );
339}
340
341
343// //
345
346//---------------------------------------------------------
348{
349 m_pString->Prepend(*String.m_pString);
350
351 return( *this );
352}
353
354//---------------------------------------------------------
356{
357 m_pString->Append(*String.m_pString);
358
359 return( *this );
360}
361
362//---------------------------------------------------------
363CSG_String & CSG_String::Append(const char *String)
364{
365 m_pString->Append(String);
366
367 return( *this );
368}
369
370//---------------------------------------------------------
371CSG_String & CSG_String::Append(const wchar_t *String)
372{
373 m_pString->Append(String);
374
375 return( *this );
376}
377
378//---------------------------------------------------------
379CSG_String & CSG_String::Append(char Character, size_t nRepeat)
380{
381 m_pString->Append(Character, nRepeat);
382
383 return( *this );
384}
385
386//---------------------------------------------------------
387CSG_String & CSG_String::Append(wchar_t Character, size_t nRepeat)
388{
389 m_pString->Append(Character, nRepeat);
390
391 return( *this );
392}
393
394//---------------------------------------------------------
396{
397 *m_pString += *String.m_pString;
398}
399
400void CSG_String::operator += (const char *String)
401{
402 *m_pString += String;
403}
404
405void CSG_String::operator += (const wchar_t *String)
406{
407 *m_pString += String;
408}
409
410void CSG_String::operator += (char Character)
411{
412 *m_pString += Character;
413}
414
415void CSG_String::operator += (wchar_t Character)
416{
417 *m_pString += Character;
418}
419
420
422// //
424
425//---------------------------------------------------------
427{
428 CSG_String s(*this);
429
430 s += String;
431
432 return( s );
433}
434
435CSG_String CSG_String::operator + (const char *String) const
436{
437 CSG_String s(*this);
438
439 s += String;
440
441 return( s );
442}
443
444CSG_String CSG_String::operator + (const wchar_t *String) const
445{
446 CSG_String s(*this);
447
448 s += String;
449
450 return( s );
451}
452
453//---------------------------------------------------------
455{
456 CSG_String s(*this);
457
458 s += Character;
459
460 return( s );
461}
462
463CSG_String CSG_String::operator + (wchar_t Character) const
464{
465 CSG_String s(*this);
466
467 s += Character;
468
469 return( s );
470}
471
472//---------------------------------------------------------
473CSG_String operator + (const char *A, const CSG_String &B)
474{
475 CSG_String s(A);
476
477 s += B;
478
479 return( s );
480}
481
482CSG_String operator + (const wchar_t *A, const CSG_String &B)
483{
484 CSG_String s(A);
485
486 s += B;
487
488 return( s );
489}
490
492{
493 CSG_String s(A);
494
495 s += B;
496
497 return( s );
498}
499
501{
502 CSG_String s(A);
503
504 s += B;
505
506 return( s );
507}
508
509
511// //
513
514//---------------------------------------------------------
515int CSG_String::Cmp(const CSG_String &String) const
516{
517 return( m_pString->Cmp(String.c_str()) );
518}
519
520//---------------------------------------------------------
521int CSG_String::CmpNoCase(const CSG_String &String) const
522{
523 return( m_pString->CmpNoCase(String.c_str()) );
524}
525
526//---------------------------------------------------------
527bool CSG_String::is_Same_As(const CSG_String &String, bool bCase) const
528{
529 return( m_pString->IsSameAs(*String.m_pString, bCase) );
530}
531
532bool CSG_String::is_Same_As(char Character, bool bCase) const
533{
534 return( m_pString->IsSameAs(Character, bCase) );
535}
536
537bool CSG_String::is_Same_As(wchar_t Character, bool bCase) const
538{
539 return( m_pString->IsSameAs(Character, bCase) );
540}
541
542//---------------------------------------------------------
544{
545 m_pString->MakeLower();
546
547 return( *this );
548}
549
550//---------------------------------------------------------
552{
553 m_pString->MakeUpper();
554
555 return( *this );
556}
557
559// //
561
562//---------------------------------------------------------
563size_t CSG_String::Replace(const CSG_String &sOld, const CSG_String &sNew, bool bReplaceAll)
564{
565 return( m_pString->Replace(*sOld.m_pString, *sNew.m_pString, bReplaceAll) );
566}
567
568//---------------------------------------------------------
569size_t CSG_String::Replace_Single_Char(const SG_Char Old, const CSG_String &New, bool bReplaceAll)
570{
571 size_t n = 0; CSG_String s;
572
573 for(size_t i=0; i<Length(); i++)
574 {
575 if( (n == 0 || bReplaceAll)
576 && Get_Char(i) == Old && ((i < 1 || !isalnum(Get_Char(i - 1))) && (i >= Length() - 1 || !isalnum(Get_Char(i + 1)))) )
577 {
578 s += New; n++;
579 }
580 else
581 {
582 s += Get_Char(i);
583 }
584 }
585
586 if( n )
587 {
588 *m_pString = *s.m_pString;
589 }
590
591 return( n );
592}
593
594//---------------------------------------------------------
595size_t CSG_String::Replace_Single_Char(const SG_Char Old, const SG_Char New, bool bReplaceAll)
596{
597 size_t n = 0;
598
599 for(size_t i=0; i<Length(); i++)
600 {
601 if( Get_Char(i) == Old && ((i < 1 || !isalnum(Get_Char(i - 1))) && (i >= Length() - 1 || !isalnum(Get_Char(i + 1)))) )
602 {
603 Set_Char(i, New); n++;
604
605 if( !bReplaceAll )
606 {
607 return( n );
608 }
609 }
610 }
611
612 return( n );
613}
614
615//---------------------------------------------------------
617{
618 m_pString->Remove(pos);
619
620 return( *this );
621}
622
623//---------------------------------------------------------
624CSG_String & CSG_String::Remove(size_t pos, size_t len)
625{
626 m_pString->Remove(pos, len);
627
628 return( *this );
629}
630
631
633// //
635
636//---------------------------------------------------------
637int CSG_String::Trim(bool fromRight)
638{
639 size_t n = m_pString->Length();
640
641 m_pString->Trim(fromRight);
642
643 return( (int)(n - m_pString->Length()) );
644}
645
646//---------------------------------------------------------
648{
649 size_t n = m_pString->Length();
650
651 m_pString->Trim( true);
652 m_pString->Trim(false);
653
654 return( (int)(n - m_pString->Length()) );
655}
656
657
659// //
661
662//---------------------------------------------------------
663int CSG_String::Find(char Character, bool fromEnd) const
664{
665 return( m_pString->Find(Character, fromEnd) );
666}
667
668int CSG_String::Find(wchar_t Character, bool fromEnd) const
669{
670 return( m_pString->Find(Character, fromEnd) );
671}
672
673//---------------------------------------------------------
674int CSG_String::Find(const CSG_String &String) const
675{
676 return( m_pString->Find(*String.m_pString) );
677}
678
679//---------------------------------------------------------
680bool CSG_String::Contains(const CSG_String &String) const
681{
682 return( m_pString->Contains(*String.m_pString) );
683}
684
685
687// //
689
690//---------------------------------------------------------
692{
693 return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
694}
695
696CSG_String CSG_String::AfterFirst(wchar_t Character) const
697{
698 return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
699}
700
701//---------------------------------------------------------
703{
704 return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
705}
706
707CSG_String CSG_String::AfterLast(wchar_t Character) const
708{
709 return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
710}
711
712//---------------------------------------------------------
714{
715 return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
716}
717
718CSG_String CSG_String::BeforeFirst(wchar_t Character) const
719{
720 return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
721}
722
723//---------------------------------------------------------
725{
726 return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
727}
728
729CSG_String CSG_String::BeforeLast(wchar_t Character) const
730{
731 return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
732}
733
734
736// //
738
739//---------------------------------------------------------
740CSG_String CSG_String::Right(size_t count) const
741{
742 return( CSG_String(m_pString->Right(count).c_str().AsWChar()) );
743}
744
745//---------------------------------------------------------
746CSG_String CSG_String::Mid(size_t first, size_t count) const
747{
748 return( CSG_String(m_pString->Mid(first, count <= 0 ? Length() : count).c_str().AsWChar()) );
749}
750
751//---------------------------------------------------------
752CSG_String CSG_String::Left(size_t count) const
753{
754 return( CSG_String(m_pString->Left(count).c_str().AsWChar()) );
755}
756
757
759// //
761
762//---------------------------------------------------------
763bool CSG_String::is_Number(void) const
764{
765 return( m_pString->IsNumber() );
766}
767
768//---------------------------------------------------------
769int CSG_String::asInt(void) const
770{
771 int Value; return( asInt(Value) ? Value : 0 );
772}
773
774bool CSG_String::asInt(int &Value) const
775{
776 const wxChar *start = m_pString->c_str(); wxChar *end;
777
778 int value = wxStrtol(start, &end, 10);
779
780 if( end > start )
781 {
782 Value = value;
783
784 return( true );
785 }
786
787 return( false );
788}
789
790//---------------------------------------------------------
792{
793 sLong Value; return( asLongLong(Value) ? Value : 0 );
794}
795
797{
798 if( m_pString->ToLongLong(&Value) )
799 {
800 return( true );
801 }
802
803 return( false );
804}
805
806//---------------------------------------------------------
807double CSG_String::asDouble(void) const
808{
809 double Value; return( asDouble(Value) ? Value : 0. );
810}
811
812bool CSG_String::asDouble(double &Value) const
813{
814 const wxChar *start = m_pString->c_str(); wxChar *end;
815
816 double value = wxStrtod(start, &end);
817
818 if( end > start )
819 {
820 Value = value;
821
822 return( true );
823 }
824
825 return( false );
826}
827
828
830// //
832
833//---------------------------------------------------------
834CSG_String CSG_String::from_UTF8(const char *String, size_t Length)
835{
836 CSG_String s;
837
838 if( String )
839 {
840 if( !Length )
841 {
842 Length = strlen(String);
843 }
844
845 *s.m_pString = wxString::FromUTF8(String, Length);
846 }
847
848 return( s );
849}
850
851//---------------------------------------------------------
859//---------------------------------------------------------
860size_t CSG_String::to_UTF8(char **pString) const
861{
862 CSG_Buffer String(to_UTF8());
863
864 if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
865 {
866 memcpy(*pString, String.Get_Data(), String.Get_Size());
867
868 return( String.Get_Size() - 1 );
869 }
870
871 *pString = NULL;
872
873 return( 0 );
874}
875
876//---------------------------------------------------------
878{
879 CSG_Buffer String;
880
881 const wxScopedCharBuffer Buffer = m_pString->utf8_str();
882
883 String.Set_Data(Buffer.data(), Buffer.length() + 1);
884
885 return( String );
886}
887
888
890// //
892
893//---------------------------------------------------------
901//---------------------------------------------------------
902size_t CSG_String::to_MBChar(char **pString, int Encoding) const
903{
904 CSG_Buffer String(to_MBChar(Encoding));
905
906 if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
907 {
908 memcpy(*pString, String.Get_Data(), String.Get_Size());
909
910 return( String.Get_Size() - 1 );
911 }
912
913 *pString = NULL;
914
915 return( 0 );
916}
917
918//---------------------------------------------------------
920{
921 CSG_Buffer String;
922
923 wxScopedCharBuffer Buffer;
924
925 switch( Encoding ) // selecting the appropriate wxMBConv class
926 {
927 case SG_FILE_ENCODING_ANSI : Buffer = m_pString->mb_str(wxConvLibc ); break;
928 case SG_FILE_ENCODING_UTF7 : Buffer = m_pString->mb_str(wxConvUTF7 ); break;
929 case SG_FILE_ENCODING_UTF8 : Buffer = m_pString->mb_str(wxConvUTF8 ); break;
930 case SG_FILE_ENCODING_UTF16LE: Buffer = m_pString->mb_str(wxMBConvUTF16LE()); break;
931 case SG_FILE_ENCODING_UTF16BE: Buffer = m_pString->mb_str(wxMBConvUTF16BE()); break;
932 case SG_FILE_ENCODING_UTF32LE: Buffer = m_pString->mb_str(wxMBConvUTF32LE()); break;
933 case SG_FILE_ENCODING_UTF32BE: Buffer = m_pString->mb_str(wxMBConvUTF32BE()); break;
934 default : Buffer = m_pString->mb_str(wxConvAuto ()); break;
935 }
936
937 String.Set_Data(Buffer.data(), Buffer.length() + 1);
938
939 return( String );
940}
941
942
944// //
946
947//---------------------------------------------------------
955//---------------------------------------------------------
956bool CSG_String::to_ASCII(char **pString, char Replace) const
957{
958 CSG_Buffer String(to_ASCII());
959
960 if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
961 {
962 memcpy(*pString, String.Get_Data(), String.Get_Size());
963
964 return( true );
965 }
966
967 *pString = NULL;
968
969 return( false );
970}
971
972//---------------------------------------------------------
974{
975 CSG_Buffer String;
976
977 #if wxCHECK_VERSION(3, 1, 0)
978 const wxScopedCharBuffer Buffer = m_pString->ToAscii(Replace);
979 #else
980 const wxScopedCharBuffer Buffer = m_pString->ToAscii();
981 #endif
982
983 String.Set_Data(Buffer.data(), Buffer.length() + 1);
984
985 return( String );
986}
987
988
990// //
992
993//---------------------------------------------------------
1000//---------------------------------------------------------
1001std::string CSG_String::to_StdString(void) const
1002{
1003 return( m_pString->ToStdString() );
1004}
1005
1006//---------------------------------------------------------
1010//---------------------------------------------------------
1011std::wstring CSG_String::to_StdWstring(void) const
1012{
1013 return( m_pString->ToStdWstring() );
1014}
1015
1016
1018// //
1019// //
1020// //
1022
1023//---------------------------------------------------------
1026
1027//---------------------------------------------------------
1029{
1030 Create(Strings);
1031}
1032
1034{
1035 Destroy();
1036
1037 return( Add(Strings) );
1038}
1039
1040//---------------------------------------------------------
1041CSG_Strings::CSG_Strings(int nStrings, const SG_Char **Strings)
1042{
1043 for(int i=0; i<nStrings; i++)
1044 {
1045 Add(Strings[i]);
1046 }
1047}
1048
1049//---------------------------------------------------------
1051{
1052 Clear();
1053}
1054
1055//---------------------------------------------------------
1057{
1058 for(size_t i=0; i<Get_Size(); i++)
1059 {
1060 delete((CSG_String *)m_Strings[i]);
1061 }
1062
1063 m_Strings.Destroy();
1064
1065 return( true );
1066}
1067
1068//---------------------------------------------------------
1069bool CSG_Strings::Add(const CSG_Strings &Strings)
1070{
1071 for(size_t i=0; i<Strings.Get_Size(); i++)
1072 {
1073 Add(Strings[i]);
1074 }
1075
1076 return( true );
1077}
1078
1079//---------------------------------------------------------
1080bool CSG_Strings::Add(const CSG_String &String)
1081{
1082 size_t i = Get_Size();
1083
1084 if( m_Strings.Inc_Array() )
1085 {
1086 m_Strings[i] = new CSG_String(String);
1087
1088 return( true );
1089 }
1090
1091 return( false );
1092}
1093
1094//---------------------------------------------------------
1095bool CSG_Strings::Ins(const CSG_String &String, size_t Index)
1096{
1097 if( Index >= Get_Size() )
1098 {
1099 return( Add(String) );
1100 }
1101
1102 if( m_Strings.Inc_Array() )
1103 {
1104 for(size_t i=Get_Size()-1; i>Index; i--)
1105 {
1106 m_Strings[i] = m_Strings[i - 1];
1107 }
1108
1109 m_Strings[Index] = new CSG_String(String);
1110
1111 return( true );
1112 }
1113
1114 return( false );
1115}
1116
1117//---------------------------------------------------------
1118bool CSG_Strings::Del(size_t Index)
1119{
1120 if( Index >= Get_Size() )
1121 {
1122 return( false );
1123 }
1124
1125 delete((CSG_String *)m_Strings[Index]);
1126
1127 for(size_t i=Index+1; i<Get_Size(); i++)
1128 {
1129 m_Strings[i - 1] = m_Strings[i];
1130 }
1131
1132 m_Strings.Dec_Array();
1133
1134 return( true );
1135}
1136
1137//---------------------------------------------------------
1138bool CSG_Strings::Set_Count(size_t Count)
1139{
1140 while( Del(Count) ) {}
1141
1142 for(size_t i=Get_Size(); i<Count; i++)
1143 {
1144 Add("");
1145 }
1146
1147 return( true );
1148}
1149
1150//---------------------------------------------------------
1151class CSG_Index_Compare_Strings : public CSG_Index::CSG_Index_Compare
1152{
1153public:
1154 CSG_String **m_Values; bool m_Ascending;
1155
1156 CSG_Index_Compare_Strings(CSG_String **Values, bool Ascending) : m_Values(Values), m_Ascending(Ascending) {}
1157
1158 virtual int Compare (const sLong _a, const sLong _b)
1159 {
1160 sLong a = m_Ascending ? _a : _b;
1161 sLong b = m_Ascending ? _b : _a;
1162
1163 return( m_Values[a]->Cmp(*m_Values[b]) );
1164 }
1165};
1166
1167//---------------------------------------------------------
1168bool CSG_Strings::Sort(bool Ascending)
1169{
1170 if( Get_Size() < 2 )
1171 {
1172 return( true );
1173 }
1174
1175 CSG_Index_Compare_Strings Compare((CSG_String **)m_Strings.Get_Array(), Ascending);
1176
1177 CSG_Index Index(Get_Count(), Compare);
1178
1180
1181 for(size_t i=0; i<Get_Size(); i++)
1182 {
1183 m_Strings[i] = Strings[Index[i]];
1184 }
1185
1186 return( true );
1187}
1188
1189
1191// //
1192// //
1193// //
1195
1196//---------------------------------------------------------
1197bool SG_is_Character_Numeric(int Character)
1198{
1199 switch( Character )
1200 {
1201 case '0':
1202 case '1':
1203 case '2':
1204 case '3':
1205 case '4':
1206 case '5':
1207 case '6':
1208 case '7':
1209 case '8':
1210 case '9':
1211 case '-':
1212 case '+':
1213 case '.':
1214 case ',':
1215 case 'e':
1216 case 'E':
1217 return( true );
1218 }
1219
1220 return( false );
1221}
1222
1223
1225// //
1226// //
1227// //
1229
1230//---------------------------------------------------------
1232{
1233 CSG_String s; wxDateTime t; t.SetToCurrent();
1234
1235 if( bWithDate )
1236 {
1237 s += t.FormatISODate().wc_str(); s += "/";
1238 }
1239
1240 s += t.FormatISOTime().wc_str();
1241
1242 return( s );
1243}
1244
1245
1247// //
1248// //
1249// //
1251
1252//---------------------------------------------------------
1254{
1255 int deg, min; double sec; char sig = Value < 0. ? '-' : '+';
1256
1257 if( Value < 0. )
1258 {
1259 Value = -Value;
1260 }
1261
1262 Value = fmod(Value, 360.);
1263 deg = (int)Value;
1264 Value = 60. * (Value - deg);
1265 min = (int)Value;
1266 Value = 60. * (Value - min);
1267 sec = Value;
1268
1269 return( CSG_String::Format(SG_T("%c%03d\xb0%02d'%02.*f''"), sig, deg, min, SG_Get_Significant_Decimals(sec), sec) );
1270}
1271
1272//---------------------------------------------------------
1273double SG_Degree_To_Double(const CSG_String &String)
1274{
1275 double sig = 1., deg = 0., min = 0., sec = 0.;
1276
1277 if( String.BeforeFirst(SG_T('\xb0')).asDouble(deg) )
1278 {
1279 if( deg < 0. )
1280 {
1281 sig = -1.; deg = -deg;
1282 }
1283
1284 String.AfterFirst(SG_T('\xb0')).asDouble(min);
1285 String.AfterFirst(SG_T('\'' )).asDouble(sec);
1286 }
1287 else
1288 {
1289 String.asDouble(deg);
1290 }
1291
1292 return( sig * (deg + min / 60. + sec / 3600.) );
1293}
1294
1295
1297// //
1298// //
1299// //
1301
1302//---------------------------------------------------------
1303int SG_Get_Significant_Decimals(double Value, int maxDecimals)
1304{
1305 int decimals;
1306
1307 Value = fabs(Value);
1308
1309 for(decimals=0; decimals<maxDecimals; decimals++)
1310 {
1311 double Remainder = Value - floor(Value);
1312
1313 if( Remainder == 0. )
1314 {
1315 return( decimals );
1316 }
1317
1318 Value *= 10.;
1319 }
1320
1321 return( maxDecimals );
1322}
1323
1324
1326// //
1327// //
1328// //
1330
1331//---------------------------------------------------------
1333{
1334 for(size_t i=0; i<String.Length(); i++)
1335 {
1336 switch( String[i] )
1337 {
1338 case SG_T('.'): String.Set_Char(i, ','); break;
1339 case SG_T(','): String.Set_Char(i, '.'); break;
1340 }
1341 }
1342}
1343
1344
1346// //
1347// //
1348// //
1350
1351//---------------------------------------------------------
1366//---------------------------------------------------------
1367CSG_String SG_Get_String(double Value, int Precision)
1368{
1369 CSG_String s;
1370
1371 if ( Precision == -99 )
1372 {
1373 s.Printf("%f", Value);
1374 }
1375 else if( Precision == -98 )
1376 {
1377 s.Printf("%e", Value);
1378 }
1379 else if( Precision == -97 )
1380 {
1381 s.Printf("%g", Value);
1382 }
1383 else if( Precision == 0 )
1384 {
1385 s.Printf("%d", (int)Value);
1386 }
1387 else if( Precision > 0 )
1388 {
1389 s.Printf("%.*f", Precision, Value);
1390 }
1391 else // if( Precision < 0 )
1392 {
1393 int Decimals = SG_Get_Significant_Decimals(Value, 18); Precision = abs(Precision);
1394
1395 if( Decimals == 0 )
1396 {
1397 s.Printf("%d", (int)Value);
1398 }
1399 else if( Decimals > Precision )
1400 {
1401 s.Printf("%g", Value);
1402 }
1403 else // if( Decimals <= Precision )
1404 {
1405 s.Printf("%.*f", Decimals, Value);
1406
1407 while( s.Length() > 1 && s[s.Length() - 1] == '0' )
1408 {
1409 s = s.Left(s.Length() - 1);
1410 }
1411
1412 if( s.Length() > 1 && (s[s.Length() - 1] == '.' || s[s.Length() - 1] == ',') )
1413 {
1414 s = s.Left(s.Length() - 1);
1415 }
1416 }
1417 }
1418
1419 s.Replace(",", ".");
1420
1421 return( s );
1422}
1423
1424//---------------------------------------------------------
1425CSG_String SG_Get_String(int Value, int Precision)
1426{
1427 if( Precision > 0 )
1428 {
1429 return( SG_Get_String((double)Value, Precision) );
1430 }
1431
1432 if( Precision < 0 )
1433 {
1434 return( CSG_String::Format("%0*d", Precision, Value) );
1435 }
1436
1437 return( CSG_String::Format("%d", Value) );
1438}
1439
1440
1442// //
1444
1445//---------------------------------------------------------
1447{
1448 const CSG_String Tags[][3] =
1449 {
1450 { "table", "\n============\n", "============\n" },
1451 { "tr" , "" , "\n" },
1452 { "th" , "" , "\t" },
1453 { "td" , "" , "\t" },
1454 { "a" , "" , "" },
1455 { "b" , "[" , "]" },
1456 { "i" , "'" , "'" },
1457 { "code" , "`" , "`" },
1458 { "br" , "\n" , "" },
1459 { "p" , "" , "\n" },
1460 { "hr" , "\n____________\n", "\n" },
1461 { "h1" , "\n############\n", "\n" },
1462 { "h2" , "\n============\n", "\n" },
1463 { "h3" , "\n------------\n", "\n" },
1464 { "h4" , "\n" , "\n" },
1465 { "ol" , "\n" , "\n" },
1466 { "ul" , "\n" , "\n" },
1467 { "li" , "(-) " , "\n" },
1468 { "", "", "" }
1469 };
1470
1471 CSG_String _Text(Text);
1472
1473 for(int i=0, n; !Tags[i][0].is_Empty(); i++)
1474 {
1475 _Text.Replace("<" + Tags[i][0] + ">", Tags[i][1]);
1476
1477 while( (n = _Text.Find("<" + Tags[i][0])) >= 0 )
1478 {
1479 CSG_String Left(_Text.Left(n)), Right(_Text.Right(_Text.Length() - (n + 1 + Tags[i][0].Length())));
1480
1481 if( Tags[i][0].Cmp("a") == 0 && (n = Right.BeforeFirst('>').Find("href=\"")) >= 0 )
1482 {
1483 CSG_String href(Right.Right(Right.Length() - n).BeforeFirst('>').AfterFirst('\"').BeforeFirst('\"'));
1484
1485 if( !href.is_Empty() && (n = Right.Find("</a>")) >= 0 )
1486 {
1487 CSG_String text(Right.Left(n).AfterFirst('>'));
1488
1489 if( !text.is_Empty() )
1490 {
1491 _Text = Left + "[" + text + "](" + href + ")" + Right.Right(Right.Length() - n);
1492
1493 continue;
1494 }
1495 }
1496 }
1497
1498 _Text = Left + Tags[i][1] + Right.AfterFirst('>');
1499 }
1500
1501 _Text.Replace("</" + Tags[i][0] + ">", Tags[i][2]);
1502 }
1503
1504 return( _Text );
1505}
1506
1507
1509// //
1510// //
1511// //
1513
1514//---------------------------------------------------------
1516{
1517 m_pTokenizer = new wxStringTokenizer();
1518}
1519
1520//---------------------------------------------------------
1522{
1523 m_pTokenizer = new wxStringTokenizer();
1524
1525 Set_String(String, Delimiters, Mode);
1526}
1527
1528//---------------------------------------------------------
1530{
1531 delete(m_pTokenizer);
1532}
1533
1534//---------------------------------------------------------
1536{
1537 return( m_pTokenizer->CountTokens() );
1538}
1539
1540//---------------------------------------------------------
1542{
1543 return( m_pTokenizer->GetLastDelimiter() );
1544}
1545
1546//---------------------------------------------------------
1548{
1549 wxString s(m_pTokenizer->GetNextToken());
1550
1551 return( &s );
1552}
1553
1554//---------------------------------------------------------
1556{
1557 return( m_pTokenizer->GetPosition() );
1558}
1559
1560//---------------------------------------------------------
1562{
1563 wxString s(m_pTokenizer->GetString());
1564
1565 return( &s );
1566}
1567
1568//---------------------------------------------------------
1570{
1571 return( m_pTokenizer->HasMoreTokens() );
1572}
1573
1574//---------------------------------------------------------
1576{
1577 wxStringTokenizerMode _Mode;
1578
1579 switch( Mode )
1580 {
1581 default: _Mode = wxTOKEN_DEFAULT ; break;
1582 case SG_TOKEN_INVALID: _Mode = wxTOKEN_INVALID ; break;
1583 case SG_TOKEN_RET_EMPTY: _Mode = wxTOKEN_RET_EMPTY ; break;
1584 case SG_TOKEN_RET_EMPTY_ALL: _Mode = wxTOKEN_RET_EMPTY_ALL; break;
1585 case SG_TOKEN_RET_DELIMS: _Mode = wxTOKEN_RET_DELIMS ; break;
1586 case SG_TOKEN_STRTOK: _Mode = wxTOKEN_STRTOK ; break;
1587 }
1588
1589 m_pTokenizer->SetString(String.c_str(), Delimiters.c_str(), _Mode);
1590}
1591
1592
1594// //
1596
1597//---------------------------------------------------------
1599{
1600 CSG_Strings Strings;
1601
1602 CSG_String_Tokenizer Tokenizer(String, Delimiters, Mode);
1603
1604 while( Tokenizer.Has_More_Tokens() )
1605 {
1606 Strings += Tokenizer.Get_Next_Token();
1607 }
1608
1609 return( Strings );
1610}
1611
1612
1614// //
1615// //
1616// //
1618
1619//---------------------------------------------------------
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
signed long long sLong
Definition api_core.h:158
#define SG_T(s)
Definition api_core.h:537
TSG_String_Tokenizer_Mode
Definition api_core.h:750
@ SG_TOKEN_RET_DELIMS
Definition api_core.h:755
@ SG_TOKEN_RET_EMPTY_ALL
Definition api_core.h:754
@ SG_TOKEN_RET_EMPTY
Definition api_core.h:753
@ SG_TOKEN_INVALID
Definition api_core.h:751
@ SG_TOKEN_STRTOK
Definition api_core.h:756
#define SG_Char
Definition api_core.h:536
@ SG_FILE_ENCODING_UTF16LE
Definition api_core.h:553
@ SG_FILE_ENCODING_UTF16BE
Definition api_core.h:554
@ SG_FILE_ENCODING_UTF8
Definition api_core.h:552
@ SG_FILE_ENCODING_UTF7
Definition api_core.h:551
@ SG_FILE_ENCODING_ANSI
Definition api_core.h:550
@ SG_FILE_ENCODING_UTF32BE
Definition api_core.h:556
@ SG_FILE_ENCODING_UTF32LE
Definition api_core.h:555
CSG_String operator+(const char *A, const CSG_String &B)
CSG_String SG_Get_CurrentTimeStr(bool bWithDate)
double SG_Degree_To_Double(const CSG_String &String)
bool SG_is_Character_Numeric(int Character)
CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
int SG_Get_Significant_Decimals(double Value, int maxDecimals)
void SG_Flip_Decimal_Separators(CSG_String &String)
CSG_String SG_Double_To_Degree(double Value)
CSG_String SG_Get_String(double Value, int Precision)
CSG_String SG_HTML_Tag_Replacer(const CSG_String &Text)
size_t Get_Size(void) const
Definition api_core.h:241
bool Set_Data(const char *Data, size_t Size, bool bShrink=true)
char * Get_Data(int Offset=0) const
Definition api_core.h:244
size_t Get_Position(void) const
SG_Char Get_Last_Delimiter(void) const
size_t Get_Tokens_Count(void) const
CSG_String Get_Next_Token(void)
bool Has_More_Tokens(void) const
void Set_String(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
CSG_String Get_String(void) const
size_t Length(void) const
CSG_String AfterFirst(char Character) const
const char * b_str(void) const
CSG_String & Remove(size_t pos)
int CmpNoCase(const CSG_String &String) const
CSG_String AfterLast(char Character) const
int Cmp(const CSG_String &String) const
size_t Replace_Single_Char(const SG_Char Old, const CSG_String &New, bool bReplaceAll=true)
CSG_String & operator=(const CSG_String &String)
void Clear(void)
CSG_String BeforeFirst(char Character) const
void operator+=(const CSG_String &String)
virtual ~CSG_String(void)
void Set_Char(size_t i, char Character)
size_t Replace(const CSG_String &Old, const CSG_String &New, bool bReplaceAll=true)
std::string to_StdString(void) const
CSG_String operator+(const CSG_String &String) const
CSG_String BeforeLast(char Character) const
static CSG_String Format(const char *Format,...)
int Trim(bool fromRight=false)
CSG_String & Append(const CSG_String &String)
int Find(char Character, bool fromEnd=false) const
size_t to_MBChar(char **pString, int Encoding) const
bool is_Same_As(const CSG_String &String, bool bCase=true) const
SG_Char Get_Char(size_t i) const
SG_Char operator[](int i) const
CSG_String Right(size_t count) const
int asInt(void) const
const SG_Char * c_str(void) const
bool to_ASCII(char **pString, char Replace='_') const
CSG_String & Make_Lower(void)
class wxString * m_pString
Definition api_core.h:689
int Trim_Both(void)
int Printf(const char *Format,...)
bool is_Empty(void) const
CSG_String Mid(size_t first, size_t count=0) const
bool Contains(const CSG_String &String) const
CSG_String(void)
CSG_String Left(size_t count) const
static CSG_String from_UTF8(const char *String, size_t Length=0)
CSG_Buffer to_UTF8(void) const
bool is_Number(void) const
std::wstring to_StdWstring(void) const
CSG_String & Make_Upper(void)
double asDouble(void) const
bool Create(const class wxString *pString)
const wchar_t * w_str(void) const
CSG_String & Prepend(const CSG_String &String)
sLong asLongLong(void) const
bool Add(const CSG_Strings &Strings)
CSG_Array_Pointer m_Strings
Definition api_core.h:742
bool Sort(bool Ascending=true)
bool Set_Count(int Count)
Definition api_core.h:712
bool Create(const CSG_Strings &Strings)
size_t Get_Size(void) const
Definition api_core.h:715
int Get_Count(void) const
Definition api_core.h:714
bool Destroy(void)
bool Del(int Index)
Definition api_core.h:721
void Clear(void)
Definition api_core.h:736
virtual ~CSG_Strings(void)
bool Ins(const CSG_String &String, int Index)
Definition api_core.h:719
#define B
#define A