|
SAGA API v2.0.8
|
00001 /********************************************************** 00002 * Version $Id: api_string.cpp 998 2011-04-18 13:41:58Z oconrad $ 00003 *********************************************************/ 00004 00006 // // 00007 // SAGA // 00008 // // 00009 // System for Automated Geoscientific Analyses // 00010 // // 00011 // Application Programming Interface // 00012 // // 00013 // Library: SAGA_API // 00014 // // 00015 //-------------------------------------------------------// 00016 // // 00017 // api_string.cpp // 00018 // // 00019 // Copyright (C) 2005 by Olaf Conrad // 00020 // // 00021 //-------------------------------------------------------// 00022 // // 00023 // This file is part of 'SAGA - System for Automated // 00024 // Geoscientific Analyses'. // 00025 // // 00026 // This library is free software; you can redistribute // 00027 // it and/or modify it under the terms of the GNU Lesser // 00028 // General Public License as published by the Free // 00029 // Software Foundation, version 2.1 of the License. // 00030 // // 00031 // This library is distributed in the hope that it will // 00032 // be useful, but WITHOUT ANY WARRANTY; without even the // 00033 // implied warranty of MERCHANTABILITY or FITNESS FOR A // 00034 // PARTICULAR PURPOSE. See the GNU Lesser General Public // 00035 // License for more details. // 00036 // // 00037 // You should have received a copy of the GNU Lesser // 00038 // General Public License along with this program; if // 00039 // not, write to the Free Software Foundation, Inc., // 00040 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, // 00041 // USA. // 00042 // // 00043 //-------------------------------------------------------// 00044 // // 00045 // contact: Olaf Conrad // 00046 // Institute of Geography // 00047 // University of Goettingen // 00048 // Goldschmidtstr. 5 // 00049 // 37077 Goettingen // 00050 // Germany // 00051 // // 00052 // e-mail: oconrad@saga-gis.org // 00053 // // 00055 00056 //--------------------------------------------------------- 00057 00058 00060 // // 00061 // // 00062 // // 00064 00065 //--------------------------------------------------------- 00066 #include <math.h> 00067 00068 #include <wx/string.h> 00069 #include <wx/datetime.h> 00070 00071 #include "api_core.h" 00072 00073 00075 // // 00076 // // 00077 // // 00079 00080 //--------------------------------------------------------- 00081 #define WXCONV wxConvUTF8 00082 00083 00085 // // 00086 // // 00087 // // 00089 00090 //--------------------------------------------------------- 00091 CSG_String::CSG_String(void) 00092 { 00093 m_pString = new wxString; 00094 #ifdef _SAGA_UNICODE 00095 m_bString = NULL; 00096 #endif 00097 } 00098 00099 CSG_String::CSG_String(const CSG_String &String) 00100 { 00101 m_pString = new wxString(*String.m_pString); 00102 #ifdef _SAGA_UNICODE 00103 m_bString = NULL; 00104 #endif 00105 } 00106 00107 CSG_String::CSG_String(const SG_Char *String) 00108 { 00109 m_pString = new wxString(String); 00110 #ifdef _SAGA_UNICODE 00111 m_bString = NULL; 00112 #endif 00113 } 00114 00115 #ifdef _SAGA_UNICODE 00116 CSG_String::CSG_String(const char *String) 00117 { 00118 m_pString = new wxString(WXCONV.cMB2WC(String)); 00119 m_bString = NULL; 00120 } 00121 #endif 00122 00123 CSG_String::CSG_String(SG_Char Character) 00124 { 00125 m_pString = new wxString(Character); 00126 #ifdef _SAGA_UNICODE 00127 m_bString = NULL; 00128 #endif 00129 } 00130 00131 //--------------------------------------------------------- 00132 CSG_String::~CSG_String(void) 00133 { 00134 delete(m_pString); 00135 00136 #ifdef _SAGA_UNICODE 00137 if( m_bString ) 00138 { 00139 SG_Free(m_bString); 00140 } 00141 #endif 00142 } 00143 00144 00146 // // 00147 // // 00148 // // 00150 00151 //--------------------------------------------------------- 00152 const SG_Char * CSG_String::c_str(void) const 00153 { 00154 return( m_pString->c_str() ); 00155 } 00156 00157 //--------------------------------------------------------- 00158 #ifdef _SAGA_UNICODE 00159 const char * CSG_String::b_str(void) 00160 { 00161 m_bString = (char *)SG_Realloc(m_bString, (1 + strlen(m_pString->mb_str(WXCONV))) * sizeof(char)); 00162 00163 strcpy(m_bString, m_pString->mb_str(WXCONV)); 00164 00165 return( m_bString ); 00166 } 00167 #endif 00168 00169 00171 // // 00172 // // 00173 // // 00175 00176 //--------------------------------------------------------- 00177 size_t CSG_String::Length(void) const 00178 { 00179 return( m_pString->Length() ); 00180 } 00181 00182 //--------------------------------------------------------- 00183 void CSG_String::Clear(void) 00184 { 00185 m_pString->Clear(); 00186 } 00187 00188 //--------------------------------------------------------- 00189 CSG_String CSG_String::Format(const SG_Char *Format, ...) 00190 { 00191 va_list argptr; 00192 CSG_String s; 00193 00194 va_start(argptr, Format); 00195 00196 s.m_pString->PrintfV(Format, argptr); 00197 00198 va_end(argptr); 00199 00200 return( s ); 00201 } 00202 00203 //--------------------------------------------------------- 00204 int CSG_String::Printf(const SG_Char *Format, ...) 00205 { 00206 va_list argptr; 00207 00208 va_start(argptr, Format); 00209 00210 m_pString->PrintfV(Format, argptr); 00211 00212 va_end(argptr); 00213 00214 return( (int)Length() ); 00215 } 00216 00217 //--------------------------------------------------------- 00218 int CSG_String::Scanf(const SG_Char *Format, ...) 00219 { 00220 va_list argptr; 00221 00222 va_start(argptr, Format); 00223 00224 int ret = SG_Sscanf(m_pString->c_str(), Format, argptr); 00225 00226 va_end(argptr); 00227 00228 return( ret ); 00229 } 00230 00231 //--------------------------------------------------------- 00232 CSG_String & CSG_String::Append(const SG_Char *String) 00233 { 00234 m_pString->Append(String); 00235 00236 return( *this ); 00237 } 00238 00239 CSG_String & CSG_String::Append(SG_Char Character) 00240 { 00241 m_pString->Append(Character); 00242 00243 return( *this ); 00244 } 00245 00246 00248 // // 00249 // // 00250 // // 00252 00253 //--------------------------------------------------------- 00254 CSG_String & CSG_String::operator = (const CSG_String &String) 00255 { 00256 *m_pString = *String.m_pString; 00257 00258 return( *this ); 00259 } 00260 00261 CSG_String & CSG_String::operator = (const SG_Char *String) 00262 { 00263 *m_pString = String; 00264 00265 return( *this ); 00266 } 00267 00268 CSG_String & CSG_String::operator = (SG_Char Character) 00269 { 00270 *m_pString = Character; 00271 00272 return( *this ); 00273 } 00274 00275 //--------------------------------------------------------- 00276 CSG_String CSG_String::operator + (const CSG_String &String) const 00277 { 00278 CSG_String s(*this); 00279 00280 s += String; 00281 00282 return( s ); 00283 } 00284 00285 CSG_String CSG_String::operator + (const SG_Char *String) const 00286 { 00287 CSG_String s(*this); 00288 00289 s += String; 00290 00291 return( s ); 00292 } 00293 00294 CSG_String CSG_String::operator + (SG_Char Character) const 00295 { 00296 CSG_String s(*this); 00297 00298 s += Character; 00299 00300 return( s ); 00301 } 00302 00303 CSG_String operator + (const SG_Char *A, const CSG_String &B) 00304 { 00305 CSG_String s(A); 00306 00307 s += B; 00308 00309 return( s ); 00310 } 00311 00312 CSG_String operator + (SG_Char A, const CSG_String &B) 00313 { 00314 CSG_String s(A); 00315 00316 s += B; 00317 00318 return( s ); 00319 } 00320 00321 //--------------------------------------------------------- 00322 void CSG_String::operator += (const CSG_String &String) 00323 { 00324 *m_pString += *String.m_pString; 00325 } 00326 00327 void CSG_String::operator += (const SG_Char *String) 00328 { 00329 *m_pString += String; 00330 } 00331 00332 void CSG_String::operator += (SG_Char Character) 00333 { 00334 *m_pString += Character; 00335 } 00336 00337 //--------------------------------------------------------- 00338 SG_Char & CSG_String::operator [] (int i) 00339 { 00340 return( m_pString->GetWritableChar(i) ); 00341 } 00342 00343 SG_Char CSG_String::operator [] (int i) const 00344 { 00345 return( m_pString->GetChar(i) ); 00346 } 00347 00348 00350 // // 00351 // // 00352 // // 00354 00355 //--------------------------------------------------------- 00356 int CSG_String::Cmp(const CSG_String &String) const 00357 { 00358 return( m_pString->Cmp(String.c_str()) ); 00359 } 00360 00361 //--------------------------------------------------------- 00362 int CSG_String::CmpNoCase(const CSG_String &String) const 00363 { 00364 return( m_pString->CmpNoCase(String.c_str()) ); 00365 } 00366 00367 //--------------------------------------------------------- 00368 CSG_String & CSG_String::Make_Lower(void) 00369 { 00370 m_pString->MakeLower(); 00371 00372 return( *this ); 00373 } 00374 00375 //--------------------------------------------------------- 00376 CSG_String & CSG_String::Make_Upper(void) 00377 { 00378 m_pString->MakeUpper(); 00379 00380 return( *this ); 00381 } 00382 00384 // // 00385 // // 00386 // // 00388 00389 //--------------------------------------------------------- 00390 size_t CSG_String::Replace(const SG_Char *sOld, const SG_Char *sNew, bool replaceAll) 00391 { 00392 return( m_pString->Replace(sOld, sNew, replaceAll) ); 00393 } 00394 00395 //--------------------------------------------------------- 00396 CSG_String & CSG_String::Remove(size_t pos) 00397 { 00398 m_pString->Remove(pos); 00399 00400 return( *this ); 00401 } 00402 00403 //--------------------------------------------------------- 00404 CSG_String & CSG_String::Remove(size_t pos, size_t len) 00405 { 00406 m_pString->Remove(pos, len); 00407 00408 return( *this ); 00409 } 00410 00411 00413 // // 00414 // // 00415 // // 00417 00418 //--------------------------------------------------------- 00419 int CSG_String::Trim(bool fromRight) 00420 { 00421 size_t n = m_pString->Length(); 00422 00423 m_pString->Trim(fromRight); 00424 00425 return( (int)(n - m_pString->Length()) ); 00426 } 00427 00428 00430 // // 00431 // // 00432 // // 00434 00435 //--------------------------------------------------------- 00436 int CSG_String::Find(SG_Char Character, bool fromEnd) const 00437 { 00438 return( m_pString->Find(Character, fromEnd) ); 00439 } 00440 00441 //--------------------------------------------------------- 00442 int CSG_String::Find(const SG_Char *String) const 00443 { 00444 return( m_pString->Find(String) ); 00445 } 00446 00447 //--------------------------------------------------------- 00448 bool CSG_String::Contains(const SG_Char *String) const 00449 { 00450 return( m_pString->Contains(String) ); 00451 } 00452 00453 00455 // // 00456 // // 00457 // // 00459 00460 //--------------------------------------------------------- 00461 CSG_String CSG_String::AfterFirst(SG_Char Character) const 00462 { 00463 return( CSG_String(m_pString->AfterFirst(Character).c_str()) ); 00464 } 00465 00466 //--------------------------------------------------------- 00467 CSG_String CSG_String::AfterLast(SG_Char Character) const 00468 { 00469 return( CSG_String(m_pString->AfterLast(Character).c_str()) ); 00470 } 00471 00472 //--------------------------------------------------------- 00473 CSG_String CSG_String::BeforeFirst(SG_Char Character) const 00474 { 00475 return( CSG_String(m_pString->BeforeFirst(Character).c_str()) ); 00476 } 00477 00478 //--------------------------------------------------------- 00479 CSG_String CSG_String::BeforeLast(SG_Char Character) const 00480 { 00481 return( CSG_String(m_pString->BeforeLast(Character).c_str()) ); 00482 } 00483 00484 00486 // // 00487 // // 00488 // // 00490 00491 //--------------------------------------------------------- 00492 CSG_String CSG_String::Right(size_t count) const 00493 { 00494 return( CSG_String(m_pString->Right(count).c_str()) ); 00495 } 00496 00497 //--------------------------------------------------------- 00498 CSG_String CSG_String::Mid(size_t first, size_t count) const 00499 { 00500 return( CSG_String(m_pString->Mid(first, count <= 0 ? wxSTRING_MAXLEN : count).c_str()) ); 00501 } 00502 00503 //--------------------------------------------------------- 00504 CSG_String CSG_String::Left(size_t count) const 00505 { 00506 return( CSG_String(m_pString->Left(count).c_str()) ); 00507 } 00508 00509 00511 // // 00512 // // 00513 // // 00515 00516 //--------------------------------------------------------- 00517 int CSG_String::asInt(void) const 00518 { 00519 int Value = 0; 00520 00521 asInt(Value); 00522 00523 return( Value ); 00524 } 00525 00526 bool CSG_String::asInt(int &Value) const 00527 { 00528 const wxChar *start = m_pString->c_str(); 00529 wxChar *end; 00530 00531 Value = wxStrtol(start, &end, 10); 00532 00533 return( end > start ); 00534 } 00535 00536 //--------------------------------------------------------- 00537 double CSG_String::asDouble(void) const 00538 { 00539 double Value = 0.0; 00540 00541 asDouble(Value); 00542 00543 return( Value ); 00544 } 00545 00546 bool CSG_String::asDouble(double &Value) const 00547 { 00548 const wxChar *start = m_pString->c_str(); 00549 wxChar *end; 00550 00551 Value = wxStrtod(start, &end); 00552 00553 return( end > start ); 00554 } 00555 00556 00558 // // 00559 // // 00560 // // 00562 00563 //--------------------------------------------------------- 00564 CSG_Strings::CSG_Strings(void) 00565 { 00566 m_nStrings = 0; 00567 m_Strings = NULL; 00568 } 00569 00570 //--------------------------------------------------------- 00571 CSG_Strings::CSG_Strings(const CSG_Strings &Strings) 00572 { 00573 m_nStrings = 0; 00574 m_Strings = NULL; 00575 00576 Assign(Strings); 00577 } 00578 00579 //--------------------------------------------------------- 00580 CSG_Strings::CSG_Strings(int nStrings, const SG_Char **Strings) 00581 { 00582 m_nStrings = 0; 00583 m_Strings = NULL; 00584 00585 for(int i=0; i<nStrings; i++) 00586 { 00587 Add(Strings[i]); 00588 } 00589 } 00590 00591 //--------------------------------------------------------- 00592 CSG_Strings::~CSG_Strings(void) 00593 { 00594 Clear(); 00595 } 00596 00597 //--------------------------------------------------------- 00598 void CSG_Strings::Clear(void) 00599 { 00600 if( m_Strings ) 00601 { 00602 for(int i=0; i<m_nStrings; i++) 00603 { 00604 delete(m_Strings[i]); 00605 } 00606 00607 SG_Free(m_Strings); 00608 00609 m_nStrings = 0; 00610 m_Strings = NULL; 00611 } 00612 } 00613 00614 //--------------------------------------------------------- 00615 bool CSG_Strings::Assign(const CSG_Strings &Strings) 00616 { 00617 Clear(); 00618 00619 for(int i=0; i<Strings.m_nStrings; i++) 00620 { 00621 Add(Strings[i]); 00622 } 00623 00624 return( true ); 00625 } 00626 00627 //--------------------------------------------------------- 00628 CSG_Strings & CSG_Strings::operator = (const CSG_Strings &Strings) 00629 { 00630 Assign(Strings); 00631 00632 return( *this ); 00633 } 00634 00635 //--------------------------------------------------------- 00636 bool CSG_Strings::Add(const CSG_String &String) 00637 { 00638 m_Strings = (CSG_String **)SG_Realloc(m_Strings, (m_nStrings + 1) * sizeof(CSG_String *)); 00639 m_Strings[m_nStrings++] = new CSG_String(String); 00640 00641 return( true ); 00642 } 00643 00644 //--------------------------------------------------------- 00645 CSG_Strings & CSG_Strings::operator += (const CSG_String &String) 00646 { 00647 Add(String); 00648 00649 return( *this ); 00650 } 00651 00652 //--------------------------------------------------------- 00653 bool CSG_Strings::Set_Count(int nStrings) 00654 { 00655 Clear(); 00656 00657 for(int i=0; i<nStrings; i++) 00658 { 00659 Add(SG_T("")); 00660 } 00661 00662 return( true ); 00663 } 00664 00665 00667 // // 00668 // // 00669 // // 00671 00672 //--------------------------------------------------------- 00673 int SG_Printf(const SG_Char *Format, ...) 00674 { 00675 va_list argptr; 00676 00677 va_start(argptr, Format); 00678 00679 int ret = wxVprintf(Format, argptr); 00680 00681 va_end(argptr); 00682 00683 return( ret ); 00684 } 00685 00686 //--------------------------------------------------------- 00687 int SG_FPrintf(FILE* stream,const SG_Char *Format, ...) 00688 { 00689 va_list argptr; 00690 00691 va_start(argptr, Format); 00692 00693 int ret = wxVfprintf(stream, Format, argptr); 00694 00695 va_end(argptr); 00696 00697 return( ret ); 00698 } 00699 00700 //--------------------------------------------------------- 00701 int SG_Sscanf(const SG_Char *Buffer, const SG_Char *Format, ...) 00702 { 00703 va_list argptr; 00704 00705 va_start(argptr, Format); 00706 00707 int ret = 0; // wxVsscanf(Buffer, Format, argptr); 00708 00709 va_end(argptr); 00710 00711 return( ret ); 00712 } 00713 00714 00716 // // 00717 // // 00718 // // 00720 00721 //--------------------------------------------------------- 00722 CSG_String SG_Get_CurrentTimeStr(bool bWithDate) 00723 { 00724 CSG_String s; 00725 wxDateTime t; 00726 00727 t.SetToCurrent(); 00728 00729 if( bWithDate ) 00730 { 00731 s.Append(t.FormatISODate()); 00732 s.Append(SG_T("/")); 00733 } 00734 00735 s.Append(t.FormatISOTime()); 00736 00737 return( s ); 00738 } 00739 00740 00742 // // 00743 // // 00744 // // 00746 00747 //--------------------------------------------------------- 00748 CSG_String SG_UTF8_To_String(const SG_Char *String) 00749 { 00750 #ifdef _SAGA_UNICODE 00751 return( !String && !String[0] ? SG_T("") : String ); 00752 #else 00753 return( !String && !String[0] ? SG_T("") : wxString::FromUTF8(String).c_str() ); 00754 #endif 00755 } 00756 00757 //--------------------------------------------------------- 00758 CSG_String SG_String_To_UTF8(const SG_Char *String) 00759 { 00760 #ifdef _SAGA_UNICODE 00761 return( !String && !String[0] ? SG_T("") : wxString(String, wxConvUTF8).c_str() ); 00762 #else 00763 return( !String && !String[0] ? SG_T("") : wxString(wxString(String).ToUTF8()).c_str() ); 00764 #endif 00765 } 00766 00767 00769 // // 00770 // // 00771 // // 00773 00774 //--------------------------------------------------------- 00775 CSG_String SG_Double_To_Degree(double Value) 00776 { 00777 SG_Char c; 00778 int d, h; 00779 double s; 00780 CSG_String String; 00781 00782 if( Value < 0.0 ) 00783 { 00784 Value = -Value; 00785 c = SG_T('-'); 00786 } 00787 else 00788 { 00789 c = SG_T('+'); 00790 } 00791 00792 Value = fmod(Value, 360.0); 00793 d = (int)Value; 00794 Value = 60.0 * (Value - d); 00795 h = (int)Value; 00796 Value = 60.0 * (Value - h); 00797 s = Value; 00798 00799 String.Printf(SG_T("%c%03d\xb0%02d'%02f''"), c, d, h, s); 00800 00801 return( String ); 00802 } 00803 00804 //--------------------------------------------------------- 00805 double SG_Degree_To_Double(const SG_Char *String) 00806 { 00807 double d, h, s, sig; 00808 CSG_String sVal(String); 00809 00810 sig = 1.0; 00811 d = h = s = 0.0; 00812 00813 if( sVal.BeforeFirst('\xb0').asDouble(d) ) 00814 { 00815 if( d < 0.0 ) 00816 { 00817 sig = -1.0; 00818 d = -d; 00819 } 00820 00821 sVal.AfterFirst('\xb0' ).asDouble(h); 00822 sVal.AfterFirst('\'').asDouble(s); 00823 } 00824 else 00825 { 00826 sVal.asDouble(d); 00827 } 00828 00829 return( sig * (d + h / 60.0 + s / (60.0 * 60.0)) ); 00830 } 00831 00832 //--------------------------------------------------------- 00833 CSG_String SG_Number_To_Date(int Value) 00834 { 00835 return( SG_Number_To_Date((double)Value) ); 00836 } 00837 00838 CSG_String SG_Number_To_Date(double Value) 00839 { 00840 int y, m, d; 00841 00842 y = (int)(Value / 10000); Value -= y * 10000; 00843 m = (int)(Value / 100); Value -= m * 100; 00844 d = (int)(Value / 1); 00845 00846 return( CSG_String::Format(SG_T("%02d.%02d.%04d"), d, m, y) ); 00847 } 00848 00849 //--------------------------------------------------------- 00850 int SG_Date_To_Number(const SG_Char *String) 00851 { 00852 if( String && String[0] ) 00853 { 00854 CSG_String s(String), sValue; 00855 00856 sValue = s.AfterLast ('.'); 00857 int y = sValue.asInt(); 00858 sValue = s.BeforeLast ('.'); s = sValue; 00859 00860 sValue = s.AfterLast ('.'); 00861 int m = sValue.asInt(); 00862 sValue = s.BeforeLast ('.'); s = sValue; 00863 int d = sValue.asInt(); 00864 00865 if( d < 1 ) d = 1; else if( d > 31 ) d = 31; 00866 if( m < 1 ) m = 1; else if( m > 12 ) m = 12; 00867 00868 return( 10000 * y + 100 * m + 1 * d ); 00869 } 00870 00871 return( 0.0 ); 00872 } 00873 00874 00876 // // 00877 // // 00878 // // 00880 00881 //--------------------------------------------------------- 00882 int SG_Get_Significant_Decimals(double Value, int maxDecimals) 00883 { 00884 int Decimals; 00885 double Reminder; 00886 00887 Value = fabs(Value); 00888 00889 for(Decimals=0; Decimals<maxDecimals; Decimals++) 00890 { 00891 Reminder = Value - floor(Value); 00892 00893 if( Reminder == 0.0 ) 00894 { 00895 return( Decimals ); 00896 } 00897 00898 Value = 10.0 * Value; 00899 } 00900 00901 return( maxDecimals ); 00902 } 00903 00904 00906 // // 00907 // // 00908 // // 00910 00911 //--------------------------------------------------------- 00912 void SG_Flip_Decimal_Separators(CSG_String &String) 00913 { 00914 for(int i=0; i<(int)String.Length(); i++) 00915 { 00916 switch( String[i] ) 00917 { 00918 case '.': String[i] = ','; break; 00919 case ',': String[i] = '.'; break; 00920 } 00921 } 00922 } 00923 00924 00926 // // 00927 // // 00928 // // 00930 00931 //--------------------------------------------------------- 00932 CSG_String SG_Get_String(double Value, int Precision, bool bScientific) 00933 { 00934 CSG_String s; 00935 00936 if( Precision >= 0 ) 00937 { 00938 s.Printf(SG_T("%.*f"), Precision, Value); 00939 } 00940 else if( Precision == -1 ) 00941 { 00942 s.Printf(SG_T("%f"), Value); 00943 } 00944 else // if( Precision == -2 ) 00945 { 00946 s.Printf(SG_T("%.*f"), SG_Get_Significant_Decimals(Value, abs(Precision)), Value); 00947 } 00948 00949 s.Replace(SG_T(","), SG_T(".")); 00950 00951 return( s ); 00952 } 00953 00954 00956 // // 00957 // // 00958 // // 00960 00961 //---------------------------------------------------------