SAGA API  v9.6
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 
83 CSG_String::CSG_String(const char *String)
84 {
85  m_pString = String ? new wxString(String) : new wxString;
86 }
87 
88 CSG_String::CSG_String(const wchar_t *String)
89 {
90  m_pString = String ? new wxString(String) : new wxString;
91 }
92 
93 CSG_String::CSG_String(char Character, size_t nRepeat)
94 {
95  m_pString = new wxString(Character, nRepeat);
96 }
97 
98 CSG_String::CSG_String(wchar_t Character, size_t nRepeat)
99 {
100  m_pString = new wxString(Character, nRepeat);
101 }
102 
103 //---------------------------------------------------------
104 CSG_String::CSG_String(const class wxString *String)
105 {
106  m_pString = String ? new wxString(*String) : new wxString;
107 }
108 
109 bool 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 
138 CSG_String & CSG_String::operator = (const char *String)
139 {
140  *m_pString = String;
141 
142  return( *this );
143 }
144 
145 CSG_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 //---------------------------------------------------------
172 size_t CSG_String::Length(void) const
173 {
174  return( m_pString->Length() );
175 }
176 
177 //---------------------------------------------------------
178 bool 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 //---------------------------------------------------------
220 void CSG_String::Set_Char(size_t i, char Character)
221 {
222  m_pString->SetChar(i, Character);
223 }
224 
225 void CSG_String::Set_Char(size_t i, wchar_t Character)
226 {
227  m_pString->SetChar(i, Character);
228 }
229 
230 
232 // //
234 
235 //---------------------------------------------------------
236 const SG_Char * CSG_String::c_str(void) const
237 {
238  return( m_pString->c_str() );
239 }
240 
241 //---------------------------------------------------------
242 const char * CSG_String::b_str(void) const
243 {
244  return( *m_pString );
245 }
246 
247 //---------------------------------------------------------
248 const 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 //---------------------------------------------------------
270 CSG_String CSG_String::Format(const char *Format, ...)
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 //---------------------------------------------------------
289 CSG_String CSG_String::Format(const wchar_t *Format, ...)
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 //---------------------------------------------------------
308 int 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 //---------------------------------------------------------
325 int 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 //---------------------------------------------------------
363 CSG_String & CSG_String::Append(const char *String)
364 {
365  m_pString->Append(String);
366 
367  return( *this );
368 }
369 
370 //---------------------------------------------------------
371 CSG_String & CSG_String::Append(const wchar_t *String)
372 {
373  m_pString->Append(String);
374 
375  return( *this );
376 }
377 
378 //---------------------------------------------------------
379 CSG_String & CSG_String::Append(char Character, size_t nRepeat)
380 {
381  m_pString->Append(Character, nRepeat);
382 
383  return( *this );
384 }
385 
386 //---------------------------------------------------------
387 CSG_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 
400 void CSG_String::operator += (const char *String)
401 {
402  *m_pString += String;
403 }
404 
405 void CSG_String::operator += (const wchar_t *String)
406 {
407  *m_pString += String;
408 }
409 
410 void CSG_String::operator += (char Character)
411 {
412  *m_pString += Character;
413 }
414 
415 void 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 
435 CSG_String CSG_String::operator + (const char *String) const
436 {
437  CSG_String s(*this);
438 
439  s += String;
440 
441  return( s );
442 }
443 
444 CSG_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 //---------------------------------------------------------
454 CSG_String CSG_String::operator + (char Character) const
455 {
456  CSG_String s(*this);
457 
458  s += Character;
459 
460  return( s );
461 }
462 
463 CSG_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 //---------------------------------------------------------
473 CSG_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 
482 CSG_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 //---------------------------------------------------------
515 int CSG_String::Cmp(const CSG_String &String) const
516 {
517  return( m_pString->Cmp(String.c_str()) );
518 }
519 
520 //---------------------------------------------------------
521 int CSG_String::CmpNoCase(const CSG_String &String) const
522 {
523  return( m_pString->CmpNoCase(String.c_str()) );
524 }
525 
526 //---------------------------------------------------------
527 bool CSG_String::is_Same_As(const CSG_String &String, bool bCase) const
528 {
529  return( m_pString->IsSameAs(*String.m_pString, bCase) );
530 }
531 
532 bool CSG_String::is_Same_As(char Character, bool bCase) const
533 {
534  return( m_pString->IsSameAs(Character, bCase) );
535 }
536 
537 bool 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 //---------------------------------------------------------
563 size_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 //---------------------------------------------------------
570 {
571  m_pString->Remove(pos);
572 
573  return( *this );
574 }
575 
576 //---------------------------------------------------------
577 CSG_String & CSG_String::Remove(size_t pos, size_t len)
578 {
579  m_pString->Remove(pos, len);
580 
581  return( *this );
582 }
583 
584 
586 // //
588 
589 //---------------------------------------------------------
590 int CSG_String::Trim(bool fromRight)
591 {
592  size_t n = m_pString->Length();
593 
594  m_pString->Trim(fromRight);
595 
596  return( (int)(n - m_pString->Length()) );
597 }
598 
599 //---------------------------------------------------------
601 {
602  size_t n = m_pString->Length();
603 
604  m_pString->Trim( true);
605  m_pString->Trim(false);
606 
607  return( (int)(n - m_pString->Length()) );
608 }
609 
610 
612 // //
614 
615 //---------------------------------------------------------
616 int CSG_String::Find(char Character, bool fromEnd) const
617 {
618  return( m_pString->Find(Character, fromEnd) );
619 }
620 
621 int CSG_String::Find(wchar_t Character, bool fromEnd) const
622 {
623  return( m_pString->Find(Character, fromEnd) );
624 }
625 
626 //---------------------------------------------------------
627 int CSG_String::Find(const CSG_String &String) const
628 {
629  return( m_pString->Find(*String.m_pString) );
630 }
631 
632 //---------------------------------------------------------
633 bool CSG_String::Contains(const CSG_String &String) const
634 {
635  return( m_pString->Contains(*String.m_pString) );
636 }
637 
638 
640 // //
642 
643 //---------------------------------------------------------
644 CSG_String CSG_String::AfterFirst(char Character) const
645 {
646  return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
647 }
648 
649 CSG_String CSG_String::AfterFirst(wchar_t Character) const
650 {
651  return( CSG_String(m_pString->AfterFirst(Character).c_str().AsWChar()) );
652 }
653 
654 //---------------------------------------------------------
655 CSG_String CSG_String::AfterLast(char Character) const
656 {
657  return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
658 }
659 
660 CSG_String CSG_String::AfterLast(wchar_t Character) const
661 {
662  return( CSG_String(m_pString->AfterLast(Character).c_str().AsWChar()) );
663 }
664 
665 //---------------------------------------------------------
666 CSG_String CSG_String::BeforeFirst(char Character) const
667 {
668  return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
669 }
670 
671 CSG_String CSG_String::BeforeFirst(wchar_t Character) const
672 {
673  return( CSG_String(m_pString->BeforeFirst(Character).c_str().AsWChar()) );
674 }
675 
676 //---------------------------------------------------------
677 CSG_String CSG_String::BeforeLast(char Character) const
678 {
679  return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
680 }
681 
682 CSG_String CSG_String::BeforeLast(wchar_t Character) const
683 {
684  return( CSG_String(m_pString->BeforeLast(Character).c_str().AsWChar()) );
685 }
686 
687 
689 // //
691 
692 //---------------------------------------------------------
693 CSG_String CSG_String::Right(size_t count) const
694 {
695  return( CSG_String(m_pString->Right(count).c_str().AsWChar()) );
696 }
697 
698 //---------------------------------------------------------
699 CSG_String CSG_String::Mid(size_t first, size_t count) const
700 {
701  return( CSG_String(m_pString->Mid(first, count <= 0 ? Length() : count).c_str().AsWChar()) );
702 }
703 
704 //---------------------------------------------------------
705 CSG_String CSG_String::Left(size_t count) const
706 {
707  return( CSG_String(m_pString->Left(count).c_str().AsWChar()) );
708 }
709 
710 
712 // //
714 
715 //---------------------------------------------------------
716 bool CSG_String::is_Number(void) const
717 {
718  return( m_pString->IsNumber() );
719 }
720 
721 //---------------------------------------------------------
722 int CSG_String::asInt(void) const
723 {
724  int Value; return( asInt(Value) ? Value : 0 );
725 }
726 
727 bool CSG_String::asInt(int &Value) const
728 {
729  const wxChar *start = m_pString->c_str(); wxChar *end;
730 
731  int value = wxStrtol(start, &end, 10);
732 
733  if( end > start )
734  {
735  Value = value;
736 
737  return( true );
738  }
739 
740  return( false );
741 }
742 
743 //---------------------------------------------------------
745 {
746  sLong Value; return( asLongLong(Value) ? Value : 0 );
747 }
748 
749 bool CSG_String::asLongLong(sLong &Value) const
750 {
751  if( m_pString->ToLongLong(&Value) )
752  {
753  return( true );
754  }
755 
756  return( false );
757 }
758 
759 //---------------------------------------------------------
760 double CSG_String::asDouble(void) const
761 {
762  double Value; return( asDouble(Value) ? Value : 0. );
763 }
764 
765 bool CSG_String::asDouble(double &Value) const
766 {
767  const wxChar *start = m_pString->c_str(); wxChar *end;
768 
769  double value = wxStrtod(start, &end);
770 
771  if( end > start )
772  {
773  Value = value;
774 
775  return( true );
776  }
777 
778  return( false );
779 }
780 
781 
783 // //
785 
786 //---------------------------------------------------------
787 CSG_String CSG_String::from_UTF8(const char *String, size_t Length)
788 {
789  CSG_String s;
790 
791  if( String )
792  {
793  if( !Length )
794  {
795  Length = strlen(String);
796  }
797 
798  *s.m_pString = wxString::FromUTF8(String, Length);
799  }
800 
801  return( s );
802 }
803 
804 //---------------------------------------------------------
812 //---------------------------------------------------------
813 size_t CSG_String::to_UTF8(char **pString) const
814 {
815  CSG_Buffer String(to_UTF8());
816 
817  if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
818  {
819  memcpy(*pString, String.Get_Data(), String.Get_Size());
820 
821  return( String.Get_Size() - 1 );
822  }
823 
824  *pString = NULL;
825 
826  return( 0 );
827 }
828 
829 //---------------------------------------------------------
831 {
832  CSG_Buffer String;
833 
834  const wxScopedCharBuffer Buffer = m_pString->utf8_str();
835 
836  String.Set_Data(Buffer.data(), Buffer.length() + 1);
837 
838  return( String );
839 }
840 
841 
843 // //
845 
846 //---------------------------------------------------------
854 //---------------------------------------------------------
855 size_t CSG_String::to_MBChar(char **pString, int Encoding) const
856 {
857  CSG_Buffer String(to_MBChar(Encoding));
858 
859  if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
860  {
861  memcpy(*pString, String.Get_Data(), String.Get_Size());
862 
863  return( String.Get_Size() - 1 );
864  }
865 
866  *pString = NULL;
867 
868  return( 0 );
869 }
870 
871 //---------------------------------------------------------
873 {
874  CSG_Buffer String;
875 
876  wxScopedCharBuffer Buffer;
877 
878  switch( Encoding ) // selecting the appropriate wxMBConv class
879  {
880  case SG_FILE_ENCODING_ANSI : Buffer = m_pString->mb_str(wxConvLibc ); break;
881  case SG_FILE_ENCODING_UTF7 : Buffer = m_pString->mb_str(wxConvUTF7 ); break;
882  case SG_FILE_ENCODING_UTF8 : Buffer = m_pString->mb_str(wxConvUTF8 ); break;
883  case SG_FILE_ENCODING_UTF16LE: Buffer = m_pString->mb_str(wxMBConvUTF16LE()); break;
884  case SG_FILE_ENCODING_UTF16BE: Buffer = m_pString->mb_str(wxMBConvUTF16BE()); break;
885  case SG_FILE_ENCODING_UTF32LE: Buffer = m_pString->mb_str(wxMBConvUTF32LE()); break;
886  case SG_FILE_ENCODING_UTF32BE: Buffer = m_pString->mb_str(wxMBConvUTF32BE()); break;
887  default : Buffer = m_pString->mb_str(wxConvAuto ()); break;
888  }
889 
890  String.Set_Data(Buffer.data(), Buffer.length() + 1);
891 
892  return( String );
893 }
894 
895 
897 // //
899 
900 //---------------------------------------------------------
908 //---------------------------------------------------------
909 bool CSG_String::to_ASCII(char **pString, char Replace) const
910 {
911  CSG_Buffer String(to_ASCII());
912 
913  if( String.Get_Size() > 1 && (*pString = (char *)SG_Malloc(String.Get_Size())) != NULL )
914  {
915  memcpy(*pString, String.Get_Data(), String.Get_Size());
916 
917  return( true );
918  }
919 
920  *pString = NULL;
921 
922  return( false );
923 }
924 
925 //---------------------------------------------------------
926 CSG_Buffer CSG_String::to_ASCII(char Replace) const
927 {
928  CSG_Buffer String;
929 
930  #if wxCHECK_VERSION(3, 1, 0)
931  const wxScopedCharBuffer Buffer = m_pString->ToAscii(Replace);
932  #else
933  const wxScopedCharBuffer Buffer = m_pString->ToAscii();
934  #endif
935 
936  String.Set_Data(Buffer.data(), Buffer.length() + 1);
937 
938  return( String );
939 }
940 
941 
943 // //
945 
946 //---------------------------------------------------------
953 //---------------------------------------------------------
954 std::string CSG_String::to_StdString(void) const
955 {
956  return( m_pString->ToStdString() );
957 }
958 
959 //---------------------------------------------------------
963 //---------------------------------------------------------
964 std::wstring CSG_String::to_StdWstring(void) const
965 {
966  return( m_pString->ToStdWstring() );
967 }
968 
969 
971 // //
972 // //
973 // //
975 
976 //---------------------------------------------------------
978 {}
979 
980 //---------------------------------------------------------
982 {
983  Create(Strings);
984 }
985 
986 bool CSG_Strings::Create(const CSG_Strings &Strings)
987 {
988  Destroy();
989 
990  return( Add(Strings) );
991 }
992 
993 //---------------------------------------------------------
994 CSG_Strings::CSG_Strings(int nStrings, const SG_Char **Strings)
995 {
996  for(int i=0; i<nStrings; i++)
997  {
998  Add(Strings[i]);
999  }
1000 }
1001 
1002 //---------------------------------------------------------
1004 {
1005  Clear();
1006 }
1007 
1008 //---------------------------------------------------------
1010 {
1011  for(size_t i=0; i<Get_Size(); i++)
1012  {
1013  delete((CSG_String *)m_Strings[i]);
1014  }
1015 
1016  m_Strings.Destroy();
1017 
1018  return( true );
1019 }
1020 
1021 //---------------------------------------------------------
1022 bool CSG_Strings::Add(const CSG_Strings &Strings)
1023 {
1024  for(size_t i=0; i<Strings.Get_Size(); i++)
1025  {
1026  Add(Strings[i]);
1027  }
1028 
1029  return( true );
1030 }
1031 
1032 //---------------------------------------------------------
1033 bool CSG_Strings::Add(const CSG_String &String)
1034 {
1035  size_t i = Get_Size();
1036 
1037  if( m_Strings.Inc_Array() )
1038  {
1039  m_Strings[i] = new CSG_String(String);
1040 
1041  return( true );
1042  }
1043 
1044  return( false );
1045 }
1046 
1047 //---------------------------------------------------------
1048 bool CSG_Strings::Ins(const CSG_String &String, size_t Index)
1049 {
1050  if( Index >= Get_Size() )
1051  {
1052  return( Add(String) );
1053  }
1054 
1055  if( m_Strings.Inc_Array() )
1056  {
1057  for(size_t i=Get_Size()-1; i>Index; i--)
1058  {
1059  m_Strings[i] = m_Strings[i - 1];
1060  }
1061 
1062  m_Strings[Index] = new CSG_String(String);
1063 
1064  return( true );
1065  }
1066 
1067  return( false );
1068 }
1069 
1070 //---------------------------------------------------------
1071 bool CSG_Strings::Del(size_t Index)
1072 {
1073  if( Index >= Get_Size() )
1074  {
1075  return( false );
1076  }
1077 
1078  delete((CSG_String *)m_Strings[Index]);
1079 
1080  for(size_t i=Index+1; i<Get_Size(); i++)
1081  {
1082  m_Strings[i - 1] = m_Strings[i];
1083  }
1084 
1085  m_Strings.Dec_Array();
1086 
1087  return( true );
1088 }
1089 
1090 //---------------------------------------------------------
1091 bool CSG_Strings::Set_Count(size_t Count)
1092 {
1093  while( Del(Count) ) {}
1094 
1095  for(size_t i=Get_Size(); i<Count; i++)
1096  {
1097  Add("");
1098  }
1099 
1100  return( true );
1101 }
1102 
1103 //---------------------------------------------------------
1104 class CSG_Index_Compare_Strings : public CSG_Index::CSG_Index_Compare
1105 {
1106 public:
1107  CSG_String **m_Values; bool m_Ascending;
1108 
1109  CSG_Index_Compare_Strings(CSG_String **Values, bool Ascending) : m_Values(Values), m_Ascending(Ascending) {}
1110 
1111  virtual int Compare (const sLong _a, const sLong _b)
1112  {
1113  sLong a = m_Ascending ? _a : _b;
1114  sLong b = m_Ascending ? _b : _a;
1115 
1116  return( m_Values[a]->Cmp(*m_Values[b]) );
1117  }
1118 };
1119 
1120 //---------------------------------------------------------
1121 bool CSG_Strings::Sort(bool Ascending)
1122 {
1123  if( Get_Size() < 2 )
1124  {
1125  return( true );
1126  }
1127 
1128  CSG_Index_Compare_Strings Compare((CSG_String **)m_Strings.Get_Array(), Ascending);
1129 
1130  CSG_Index Index(Get_Count(), Compare);
1131 
1132  CSG_Array_Pointer Strings(m_Strings);
1133 
1134  for(size_t i=0; i<Get_Size(); i++)
1135  {
1136  m_Strings[i] = Strings[Index[i]];
1137  }
1138 
1139  return( true );
1140 }
1141 
1142 
1144 // //
1145 // //
1146 // //
1148 
1149 //---------------------------------------------------------
1150 bool SG_is_Character_Numeric(int Character)
1151 {
1152  switch( Character )
1153  {
1154  case '0':
1155  case '1':
1156  case '2':
1157  case '3':
1158  case '4':
1159  case '5':
1160  case '6':
1161  case '7':
1162  case '8':
1163  case '9':
1164  case '-':
1165  case '+':
1166  case '.':
1167  case ',':
1168  case 'e':
1169  case 'E':
1170  return( true );
1171  }
1172 
1173  return( false );
1174 }
1175 
1176 
1178 // //
1179 // //
1180 // //
1182 
1183 //---------------------------------------------------------
1185 {
1186  CSG_String s; wxDateTime t; t.SetToCurrent();
1187 
1188  if( bWithDate )
1189  {
1190  s += t.FormatISODate().wc_str(); s += "/";
1191  }
1192 
1193  s += t.FormatISOTime().wc_str();
1194 
1195  return( s );
1196 }
1197 
1198 
1200 // //
1201 // //
1202 // //
1204 
1205 //---------------------------------------------------------
1207 {
1208  int deg, min; double sec; char sig = Value < 0. ? '-' : '+';
1209 
1210  if( Value < 0. )
1211  {
1212  Value = -Value;
1213  }
1214 
1215  Value = fmod(Value, 360.);
1216  deg = (int)Value;
1217  Value = 60. * (Value - deg);
1218  min = (int)Value;
1219  Value = 60. * (Value - min);
1220  sec = Value;
1221 
1222  return( CSG_String::Format(SG_T("%c%03d\xb0%02d'%02.*f''"), sig, deg, min, SG_Get_Significant_Decimals(sec), sec) );
1223 }
1224 
1225 //---------------------------------------------------------
1226 double SG_Degree_To_Double(const CSG_String &String)
1227 {
1228  double sig = 1., deg = 0., min = 0., sec = 0.;
1229 
1230  if( String.BeforeFirst(SG_T('\xb0')).asDouble(deg) )
1231  {
1232  if( deg < 0. )
1233  {
1234  sig = -1.; deg = -deg;
1235  }
1236 
1237  String.AfterFirst(SG_T('\xb0')).asDouble(min);
1238  String.AfterFirst(SG_T('\'' )).asDouble(sec);
1239  }
1240  else
1241  {
1242  String.asDouble(deg);
1243  }
1244 
1245  return( sig * (deg + min / 60. + sec / 3600.) );
1246 }
1247 
1248 
1250 // //
1251 // //
1252 // //
1254 
1255 //---------------------------------------------------------
1256 int SG_Get_Significant_Decimals(double Value, int maxDecimals)
1257 {
1258  int decimals;
1259 
1260  Value = fabs(Value);
1261 
1262  for(decimals=0; decimals<maxDecimals; decimals++)
1263  {
1264  double Remainder = Value - floor(Value);
1265 
1266  if( Remainder == 0. )
1267  {
1268  return( decimals );
1269  }
1270 
1271  Value *= 10.;
1272  }
1273 
1274  return( maxDecimals );
1275 }
1276 
1277 
1279 // //
1280 // //
1281 // //
1283 
1284 //---------------------------------------------------------
1286 {
1287  for(size_t i=0; i<String.Length(); i++)
1288  {
1289  switch( String[i] )
1290  {
1291  case SG_T('.'): String.Set_Char(i, ','); break;
1292  case SG_T(','): String.Set_Char(i, '.'); break;
1293  }
1294  }
1295 }
1296 
1297 
1299 // //
1300 // //
1301 // //
1303 
1304 //---------------------------------------------------------
1317 //---------------------------------------------------------
1318 CSG_String SG_Get_String(double Value, int Precision)
1319 {
1320  CSG_String s;
1321 
1322  if ( Precision == -99 )
1323  {
1324  s.Printf("%f", Value);
1325  }
1326  else if( Precision == -98 )
1327  {
1328  s.Printf("%e", Value);
1329  }
1330  else if( Precision == 0 )
1331  {
1332  s.Printf("%d", (int)Value);
1333  }
1334  else if( Precision > 0 )
1335  {
1336  s.Printf("%.*f", Precision, Value);
1337  }
1338  else // if( Precision < 0 )
1339  {
1340  Precision = SG_Get_Significant_Decimals(Value, abs(Precision));
1341 
1342  if( Precision == 0 )
1343  {
1344  s.Printf("%.0f", Value);
1345  }
1346  else // if( Precision > 0 )
1347  {
1348  s.Printf("%.*f", Precision, Value);
1349 
1350  while( s.Length() > 1 && s[s.Length() - 1] == '0' )
1351  {
1352  s = s.Left(s.Length() - 1);
1353  }
1354 
1355  if( s.Length() > 1 && (s[s.Length() - 1] == '.' || s[s.Length() - 1] == ',') )
1356  {
1357  s = s.Left(s.Length() - 1);
1358  }
1359  }
1360  }
1361 
1362  s.Replace(",", ".");
1363 
1364  return( s );
1365 }
1366 
1367 //---------------------------------------------------------
1368 CSG_String SG_Get_String(int Value, int Precision)
1369 {
1370  if( Precision > 0 )
1371  {
1372  return( SG_Get_String((double)Value, Precision) );
1373  }
1374 
1375  if( Precision < 0 )
1376  {
1377  return( CSG_String::Format("%0*d", Precision, Value) );
1378  }
1379 
1380  return( CSG_String::Format("%d", Value) );
1381 }
1382 
1383 
1385 // //
1387 
1388 //---------------------------------------------------------
1390 {
1391  const CSG_String Tags[][3] =
1392  {
1393  { "table", "\n============\n", "============\n" },
1394  { "tr" , "" , "\n" },
1395  { "th" , "" , "\t" },
1396  { "td" , "" , "\t" },
1397  { "a" , "" , "" },
1398  { "b" , "[" , "]" },
1399  { "i" , "'" , "'" },
1400  { "br" , "\n" , "" },
1401  { "p" , "" , "\n" },
1402  { "hr" , "\n____________\n", "\n" },
1403  { "h1" , "\n############\n", "\n" },
1404  { "h2" , "\n============\n", "\n" },
1405  { "h3" , "\n------------\n", "\n" },
1406  { "h4" , "\n" , "\n" },
1407  { "ol" , "\n" , "\n" },
1408  { "ul" , "\n" , "\n" },
1409  { "li" , "(-) " , "\n" },
1410  { "", "", "" }
1411  };
1412 
1413  CSG_String _Text(Text);
1414 
1415  for(int i=0, n; !Tags[i][0].is_Empty(); i++)
1416  {
1417  _Text.Replace("<" + Tags[i][0] + ">", Tags[i][1]);
1418 
1419  while( (n = _Text.Find("<" + Tags[i][0])) >= 0 )
1420  {
1421  CSG_String Left(_Text.Left(n)), Right(_Text.Right(_Text.Length() - (n + 1 + Tags[i][0].Length())));
1422 
1423  if( Tags[i][0].Cmp("a") == 0 && (n = Right.BeforeFirst('>').Find("href=\"")) >= 0 )
1424  {
1425  CSG_String href(Right.Right(Right.Length() - n).BeforeFirst('>').AfterFirst('\"').BeforeFirst('\"'));
1426 
1427  if( !href.is_Empty() && (n = Right.Find("</a>")) >= 0 )
1428  {
1429  CSG_String text(Right.Left(n).AfterFirst('>'));
1430 
1431  if( !text.is_Empty() )
1432  {
1433  _Text = Left + "[" + text + "](" + href + ")" + Right.Right(Right.Length() - n);
1434 
1435  continue;
1436  }
1437  }
1438  }
1439 
1440  _Text = Left + Tags[i][1] + Right.AfterFirst('>');
1441  }
1442 
1443  _Text.Replace("</" + Tags[i][0] + ">", Tags[i][2]);
1444  }
1445 
1446  return( _Text );
1447 }
1448 
1449 
1451 // //
1452 // //
1453 // //
1455 
1456 //---------------------------------------------------------
1458 {
1459  m_pTokenizer = new wxStringTokenizer();
1460 }
1461 
1462 //---------------------------------------------------------
1464 {
1465  m_pTokenizer = new wxStringTokenizer();
1466 
1467  Set_String(String, Delimiters, Mode);
1468 }
1469 
1470 //---------------------------------------------------------
1472 {
1473  delete(m_pTokenizer);
1474 }
1475 
1476 //---------------------------------------------------------
1478 {
1479  return( m_pTokenizer->CountTokens() );
1480 }
1481 
1482 //---------------------------------------------------------
1484 {
1485  return( m_pTokenizer->GetLastDelimiter() );
1486 }
1487 
1488 //---------------------------------------------------------
1490 {
1491  wxString s(m_pTokenizer->GetNextToken());
1492 
1493  return( &s );
1494 }
1495 
1496 //---------------------------------------------------------
1498 {
1499  return( m_pTokenizer->GetPosition() );
1500 }
1501 
1502 //---------------------------------------------------------
1504 {
1505  wxString s(m_pTokenizer->GetString());
1506 
1507  return( &s );
1508 }
1509 
1510 //---------------------------------------------------------
1512 {
1513  return( m_pTokenizer->HasMoreTokens() );
1514 }
1515 
1516 //---------------------------------------------------------
1518 {
1519  wxStringTokenizerMode _Mode;
1520 
1521  switch( Mode )
1522  {
1523  default: _Mode = wxTOKEN_DEFAULT ; break;
1524  case SG_TOKEN_INVALID: _Mode = wxTOKEN_INVALID ; break;
1525  case SG_TOKEN_RET_EMPTY: _Mode = wxTOKEN_RET_EMPTY ; break;
1526  case SG_TOKEN_RET_EMPTY_ALL: _Mode = wxTOKEN_RET_EMPTY_ALL; break;
1527  case SG_TOKEN_RET_DELIMS: _Mode = wxTOKEN_RET_DELIMS ; break;
1528  case SG_TOKEN_STRTOK: _Mode = wxTOKEN_STRTOK ; break;
1529  }
1530 
1531  m_pTokenizer->SetString(String.c_str(), Delimiters.c_str(), _Mode);
1532 }
1533 
1534 
1536 // //
1538 
1539 //---------------------------------------------------------
1541 {
1542  CSG_Strings Strings;
1543 
1544  CSG_String_Tokenizer Tokenizer(String, Delimiters, Mode);
1545 
1546  while( Tokenizer.Has_More_Tokens() )
1547  {
1548  Strings += Tokenizer.Get_Next_Token();
1549  }
1550 
1551  return( Strings );
1552 }
1553 
1554 
1556 // //
1557 // //
1558 // //
1560 
1561 //---------------------------------------------------------
CSG_Index
Definition: mat_tools.h:200
CSG_String::BeforeFirst
CSG_String BeforeFirst(char Character) const
Definition: api_string.cpp:666
SG_TOKEN_INVALID
@ SG_TOKEN_INVALID
Definition: api_core.h:749
CSG_String_Tokenizer::Get_Tokens_Count
size_t Get_Tokens_Count(void) const
Definition: api_string.cpp:1477
SG_T
#define SG_T(s)
Definition: api_core.h:537
CSG_String::Printf
int Printf(const char *Format,...)
Definition: api_string.cpp:308
CSG_String_Tokenizer::Has_More_Tokens
bool Has_More_Tokens(void) const
Definition: api_string.cpp:1511
CSG_String_Tokenizer::Get_String
CSG_String Get_String(void) const
Definition: api_string.cpp:1503
CSG_String::Append
CSG_String & Append(const CSG_String &String)
Definition: api_string.cpp:355
CSG_String::Make_Lower
CSG_String & Make_Lower(void)
Definition: api_string.cpp:543
CSG_String::to_ASCII
bool to_ASCII(char **pString, char Replace='_') const
Definition: api_string.cpp:909
SG_Flip_Decimal_Separators
void SG_Flip_Decimal_Separators(CSG_String &String)
Definition: api_string.cpp:1285
CSG_String::w_str
const wchar_t * w_str(void) const
Definition: api_string.cpp:248
CSG_String::is_Number
bool is_Number(void) const
Definition: api_string.cpp:716
CSG_String::Length
size_t Length(void) const
Definition: api_string.cpp:172
SG_Get_CurrentTimeStr
CSG_String SG_Get_CurrentTimeStr(bool bWithDate)
Definition: api_string.cpp:1184
CSG_String::b_str
const char * b_str(void) const
Definition: api_string.cpp:242
CSG_Strings::Del
bool Del(int Index)
Definition: api_core.h:719
SG_Double_To_Degree
CSG_String SG_Double_To_Degree(double Value)
Definition: api_string.cpp:1206
CSG_String::~CSG_String
virtual ~CSG_String(void)
Definition: api_string.cpp:120
CSG_String::Remove
CSG_String & Remove(size_t pos)
Definition: api_string.cpp:569
SG_TOKEN_RET_EMPTY_ALL
@ SG_TOKEN_RET_EMPTY_ALL
Definition: api_core.h:752
A
#define A
CSG_String::Mid
CSG_String Mid(size_t first, size_t count=0) const
Definition: api_string.cpp:699
CSG_Index::CSG_Index_Compare
Definition: mat_tools.h:203
CSG_String::asInt
int asInt(void) const
Definition: api_string.cpp:722
CSG_String::operator+
CSG_String operator+(const CSG_String &String) const
Definition: api_string.cpp:426
SG_Malloc
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
Definition: api_memory.cpp:65
CSG_Strings::Ins
bool Ins(const CSG_String &String, int Index)
Definition: api_core.h:717
CSG_String::from_UTF8
static CSG_String from_UTF8(const char *String, size_t Length=0)
Definition: api_string.cpp:787
CSG_String::is_Same_As
bool is_Same_As(const CSG_String &String, bool bCase=true) const
Definition: api_string.cpp:527
CSG_Index::CSG_Index_Compare::Compare
virtual int Compare(const sLong a, const sLong b)=0
CSG_String::Make_Upper
CSG_String & Make_Upper(void)
Definition: api_string.cpp:551
SG_FILE_ENCODING_UTF32BE
@ SG_FILE_ENCODING_UTF32BE
Definition: api_core.h:556
CSG_String::Get_Char
SG_Char Get_Char(size_t i) const
Definition: api_string.cpp:209
api_core.h
CSG_String::CSG_String
CSG_String(void)
Definition: api_string.cpp:73
CSG_String::Prepend
CSG_String & Prepend(const CSG_String &String)
Definition: api_string.cpp:347
SG_String_Tokenize
CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters, TSG_String_Tokenizer_Mode Mode)
Definition: api_string.cpp:1540
CSG_Strings::Create
bool Create(const CSG_Strings &Strings)
Definition: api_string.cpp:986
CSG_String::Replace
size_t Replace(const CSG_String &sOld, const CSG_String &sNew, bool bReplaceAll=true)
Definition: api_string.cpp:563
CSG_String::Create
bool Create(const class wxString *pString)
Definition: api_string.cpp:109
CSG_Array_Pointer::Inc_Array
bool Inc_Array(sLong nValues=1)
Definition: api_core.h:388
CSG_String::Cmp
int Cmp(const CSG_String &String) const
Definition: api_string.cpp:515
SG_FILE_ENCODING_UTF7
@ SG_FILE_ENCODING_UTF7
Definition: api_core.h:551
CSG_String::to_UTF8
CSG_Buffer to_UTF8(void) const
Definition: api_string.cpp:830
CSG_String::BeforeLast
CSG_String BeforeLast(char Character) const
Definition: api_string.cpp:677
mat_tools.h
CSG_Strings::Clear
void Clear(void)
Definition: api_core.h:734
CSG_Buffer
Definition: api_core.h:224
CSG_String::operator[]
SG_Char operator[](int i) const
Definition: api_string.cpp:189
CSG_String::Trim
int Trim(bool fromRight=false)
Definition: api_string.cpp:590
CSG_String::to_StdString
std::string to_StdString(void) const
Definition: api_string.cpp:954
CSG_Strings::Add
bool Add(const CSG_Strings &Strings)
Definition: api_string.cpp:1022
CSG_Strings::m_Strings
CSG_Array_Pointer m_Strings
Definition: api_core.h:740
CSG_Strings::Get_Size
size_t Get_Size(void) const
Definition: api_core.h:713
SG_TOKEN_RET_EMPTY
@ SG_TOKEN_RET_EMPTY
Definition: api_core.h:751
operator+
CSG_String operator+(const char *A, const CSG_String &B)
Definition: api_string.cpp:473
sLong
signed long long sLong
Definition: api_core.h:158
CSG_Array_Pointer::Dec_Array
bool Dec_Array(bool bShrink=true)
Definition: api_core.h:389
SG_FILE_ENCODING_UTF32LE
@ SG_FILE_ENCODING_UTF32LE
Definition: api_core.h:555
SG_HTML_Tag_Replacer
CSG_String SG_HTML_Tag_Replacer(const CSG_String &Text)
Definition: api_string.cpp:1389
CSG_Buffer::Get_Size
size_t Get_Size(void) const
Definition: api_core.h:241
CSG_String::Trim_Both
int Trim_Both(void)
Definition: api_string.cpp:600
CSG_Strings::Destroy
bool Destroy(void)
Definition: api_string.cpp:1009
CSG_String::to_StdWstring
std::wstring to_StdWstring(void) const
Definition: api_string.cpp:964
CSG_Strings::~CSG_Strings
virtual ~CSG_Strings(void)
Definition: api_string.cpp:1003
CSG_Strings
Definition: api_core.h:699
CSG_Strings::Set_Count
bool Set_Count(int Count)
Definition: api_core.h:710
CSG_Buffer::Get_Data
char * Get_Data(int Offset=0) const
Definition: api_core.h:244
CSG_String::operator=
CSG_String & operator=(const CSG_String &String)
Definition: api_string.cpp:131
CSG_String::Format
static CSG_String Format(const char *Format,...)
Definition: api_string.cpp:270
CSG_String::to_MBChar
size_t to_MBChar(char **pString, int Encoding) const
Definition: api_string.cpp:855
CSG_String::Find
int Find(char Character, bool fromEnd=false) const
Definition: api_string.cpp:616
SG_FILE_ENCODING_UTF16LE
@ SG_FILE_ENCODING_UTF16LE
Definition: api_core.h:553
CSG_String_Tokenizer::CSG_String_Tokenizer
CSG_String_Tokenizer(void)
Definition: api_string.cpp:1457
CSG_Buffer::Set_Data
bool Set_Data(const char *Data, size_t Size, bool bShrink=true)
Definition: api_memory.cpp:755
SG_is_Character_Numeric
bool SG_is_Character_Numeric(int Character)
Definition: api_string.cpp:1150
CSG_String::Left
CSG_String Left(size_t count) const
Definition: api_string.cpp:705
CSG_String::CmpNoCase
int CmpNoCase(const CSG_String &String) const
Definition: api_string.cpp:521
CSG_String::AfterFirst
CSG_String AfterFirst(char Character) const
Definition: api_string.cpp:644
CSG_String::Clear
void Clear(void)
Definition: api_string.cpp:259
CSG_String::operator+=
void operator+=(const CSG_String &String)
Definition: api_string.cpp:395
SG_TOKEN_STRTOK
@ SG_TOKEN_STRTOK
Definition: api_core.h:754
CSG_Array_Pointer::Destroy
void Destroy(void)
Definition: api_core.h:376
SG_Char
#define SG_Char
Definition: api_core.h:536
CSG_String_Tokenizer::~CSG_String_Tokenizer
~CSG_String_Tokenizer(void)
Definition: api_string.cpp:1471
CSG_String::Contains
bool Contains(const CSG_String &String) const
Definition: api_string.cpp:633
B
#define B
CSG_String
Definition: api_core.h:563
CSG_Array_Pointer
Definition: api_core.h:368
CSG_String::Set_Char
void Set_Char(size_t i, char Character)
Definition: api_string.cpp:220
CSG_String_Tokenizer::Get_Last_Delimiter
SG_Char Get_Last_Delimiter(void) const
Definition: api_string.cpp:1483
SG_Get_Significant_Decimals
int SG_Get_Significant_Decimals(double Value, int maxDecimals)
Definition: api_string.cpp:1256
CSG_String_Tokenizer::Set_String
void Set_String(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
Definition: api_string.cpp:1517
CSG_Strings::Sort
bool Sort(bool Ascending=true)
Definition: api_string.cpp:1121
SG_Degree_To_Double
double SG_Degree_To_Double(const CSG_String &String)
Definition: api_string.cpp:1226
CSG_String::is_Empty
bool is_Empty(void) const
Definition: api_string.cpp:178
SG_FILE_ENCODING_UTF16BE
@ SG_FILE_ENCODING_UTF16BE
Definition: api_core.h:554
CSG_String::asLongLong
sLong asLongLong(void) const
Definition: api_string.cpp:744
SG_TOKEN_RET_DELIMS
@ SG_TOKEN_RET_DELIMS
Definition: api_core.h:753
TSG_String_Tokenizer_Mode
TSG_String_Tokenizer_Mode
Definition: api_core.h:748
CSG_Array_Pointer::Get_Array
void ** Get_Array(void) const
Definition: api_core.h:384
CSG_String::AfterLast
CSG_String AfterLast(char Character) const
Definition: api_string.cpp:655
CSG_String::m_pString
class wxString * m_pString
Definition: api_core.h:687
CSG_String::asDouble
double asDouble(void) const
Definition: api_string.cpp:760
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
CSG_Strings::Get_Count
int Get_Count(void) const
Definition: api_core.h:712
CSG_String_Tokenizer::Get_Position
size_t Get_Position(void) const
Definition: api_string.cpp:1497
SG_Get_String
CSG_String SG_Get_String(double Value, int Precision)
Definition: api_string.cpp:1318
CSG_String_Tokenizer
Definition: api_core.h:760
SG_FILE_ENCODING_ANSI
@ SG_FILE_ENCODING_ANSI
Definition: api_core.h:550
SG_FILE_ENCODING_UTF8
@ SG_FILE_ENCODING_UTF8
Definition: api_core.h:552
CSG_String_Tokenizer::Get_Next_Token
CSG_String Get_Next_Token(void)
Definition: api_string.cpp:1489
CSG_String::Right
CSG_String Right(size_t count) const
Definition: api_string.cpp:693
CSG_Strings::CSG_Strings
CSG_Strings(void)
Definition: api_string.cpp:977