00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef String_INCLUDE_ONCE
00033 #define String_INCLUDE_ONCE
00034
00035 #include <vlCore/vlnamespace.hpp>
00036 #include <vlCore/Object.hpp>
00037 #include <vector>
00038 #include <string.h>
00039
00040 #if defined(_WIN32)
00041 #define VL_PLATFORM_DEFAULT_ENCODING SE_LATIN1
00042 #else
00043 #define VL_PLATFORM_DEFAULT_ENCODING SE_UTF8
00044 #endif
00045
00046 namespace vl
00047 {
00048 class VirtualFile;
00049
00062 class VLCORE_EXPORT String
00063 {
00064 public:
00066 static EStringEncoding detectEncoding(const void* str, int byte_count, EStringEncoding encoding = VL_PLATFORM_DEFAULT_ENCODING);
00067
00069 static String loadText(const String& path, EStringEncoding encoding = VL_PLATFORM_DEFAULT_ENCODING);
00070
00072 static String loadText(const char* path, EStringEncoding encoding = VL_PLATFORM_DEFAULT_ENCODING) { return loadText(String(path),encoding); }
00073
00075 static String loadText(VirtualFile* file, EStringEncoding encoding = VL_PLATFORM_DEFAULT_ENCODING);
00076
00078 static String loadText(void* data, int bytes, EStringEncoding encoding = VL_PLATFORM_DEFAULT_ENCODING);
00079
00081 static unsigned short getUpperCase(unsigned short ch);
00082
00084 static unsigned short getLowerCase(unsigned short ch);
00085
00087 static unsigned short getTitleCase(unsigned short ch);
00088
00090 static void filterStrings(std::vector<String>& strings, const String& filter);
00091
00093 static wchar_t platformSlash()
00094 {
00095 #ifdef _WIN32
00096 return '\\';
00097 #else
00098 return '/';
00099 #endif
00100 }
00101
00103 static std::string trimStdString(const std::string& text);
00104
00106 String();
00107
00109 String(const String& other);
00110
00112 String(const wchar_t* wstr);
00113
00115 String(const char* str);
00116
00118 explicit String(wchar_t ch, int count=1);
00119
00121 const wchar_t* ptr() const { createData(); return &(*mString)[0]; }
00122
00124 wchar_t* ptr() { acquireData(); return &(*mString)[0]; }
00125
00127 int length() const { if (!mString) return 0; createData(); return (int)mString->length(); };
00128
00130 bool empty() const { return length() == 0; }
00131
00133 bool null() const { return !mString; }
00134
00136 String& clear() { acquireData(); mString->clear(); return *this; }
00137
00139 const wchar_t& operator[](int i) const { createData(); return (*mString)[i]; }
00140
00142 wchar_t& operator[](int i) { acquireData(); return (*mString)[i]; }
00143
00145 String& replace( wchar_t old_ch, wchar_t new_ch );
00146
00148 String& replace( int start, int count, wchar_t ch );
00149
00151 String& replace( int start, int count, const String& str );
00152
00154 String& replace( const String& oldstr, const String& newstr, bool case_sensitive=true );
00155
00158 String& remove(wchar_t ch, int start=0, int count=-1);
00159
00162 String& remove(const String& str, int start=0, int count=-1);
00163
00165 String& remove( int start, int count );
00166
00168 String& reverse();
00169
00171 String& normalizeSlashes();
00172
00174 int count(wchar_t ch, int start=0) const;
00175
00177 int count(const String& str, int start=0) const;
00178
00183 int compare(const String& other) const;
00184
00186 bool endsWith(const String& str) const;
00187
00189 bool startsWith(const String& str) const;
00190
00192 bool endsWith(wchar_t ch) const;
00193
00195 bool startsWith(wchar_t ch) const;
00196
00198 String& insert(int pos, const String& str);
00199
00201 String& insert(int pos, wchar_t ch, int count=1);
00202
00204 String left(int count) const;
00205
00207 String right(int count) const;
00208
00210 String extractPath() const;
00211
00213 String extractFileName() const;
00214
00216 String extractFileExtension(bool require_dot=true) const;
00217
00219 String& resize(int character_count);
00220
00222 String substring(int start, int count=-1) const;
00223
00225 String& fill(wchar_t ch);
00226
00228 String& trim(wchar_t ch);
00229
00231 String& trim(const String& chars);
00232
00234 String& trim();
00235
00237 void split(wchar_t separator, std::vector<String>& fields, bool remove_empty_fields=false) const;
00238
00240 void split(const String& separator_list, std::vector<String>& fields, bool remove_empty_fields=false) const;
00241
00243 void splitLines(std::vector<String>& lines) const;
00244
00246 String field(wchar_t separator, int field_index) const;
00247
00249 String& append(const String& other);
00250
00252 String& append(wchar_t ch, int count=1);
00253
00255 String& prepend(const String& str);
00256
00258 String& prepend(wchar_t ch, int count);
00259
00261 int find(wchar_t ch, int start=0) const;
00262
00264 int find(const String& substr, int start=0) const;
00265
00268 int findInLargeText(const String& substr, int start=0) const;
00269
00271 int findBackwards(wchar_t ch) const;
00272
00274 int findBackwards(const String& str) const;
00275
00277 bool contains(wchar_t ch) const;
00278
00280 bool contains(const String& str) const;
00281
00283 void squeeze();
00284
00285
00286
00288 static String fromInt(int value);
00289
00291 static String fromUInt(unsigned int value);
00292
00294 static String fromLongLong(long long value);
00295
00297 static String fromULongLong(unsigned long long value);
00298
00301 static String fromDouble(double value, int decimals=6);
00302
00304 static String fromStdString(const std::string& str);
00305
00307 static String fromStdWString(const std::wstring& str);
00308
00310 static String fromAscii(const char* str, int size=-1);
00311
00315 static String fromUTF16BE(const unsigned short* str, int byte_count=-1);
00316
00320 static String fromUTF16LE(const unsigned short* str, int byte_count=-1);
00321
00324 static String fromUTF16(const unsigned short* str, int byte_count=-1);
00325
00327 static String fromUTF8(const char* str, int byte_count=-1);
00328
00330 static String fromLatin1(const char* str, int character_count=-1);
00331
00333 int toInt(bool hex=false) const;
00334
00336 double toDouble() const;
00337
00339 float toFloat() const { return (float)toDouble(); }
00340
00342 std::string toStdString() const;
00343
00345 std::wstring toStdWString() const;
00346
00348 void toAscii(std::string& ascii, bool translate_non_ascii_chars=true) const;
00349
00351 void toUTF8(std::vector<unsigned char>& utf8, bool include_utf8_signature=true) const;
00352
00354 void toUTF8(std::string& utf8, bool include_utf8_signature=true) const;
00355
00357 void toUTF16BE(std::vector<unsigned char>& utf16, bool include_utf16be_signature=true) const;
00358
00360 void toUTF16LE(std::vector<unsigned char>& utf16, bool include_utf16le_signature=true) const;
00361
00363 void toLatin1(std::vector<unsigned char>& latin1) const;
00364
00366 String toLowerCase() const;
00367
00369 String toUpperCase() const;
00370
00372 bool operator<(const String& other) const
00373 {
00374 return compare(other) < 0;
00375 }
00376
00378 String& operator=(const char* str)
00379 {
00380 *this = fromUTF8(str);
00381 return *this;
00382 }
00383
00385 String& operator=(const std::string& str)
00386 {
00387 *this = fromUTF8(str.c_str());
00388 return *this;
00389 }
00390
00391 String& operator=(const wchar_t* wstr)
00392 {
00393 acquireData();
00394
00395 mString->clear();
00396 if (wstr)
00397 {
00398 for(int i=0; wstr[i]; ++i)
00399 mString->push_back(wstr[i]);
00400 }
00401 return *this;
00402 }
00403
00404 String& operator=(const std::wstring& str)
00405 {
00406 return operator=(str.c_str());
00407 }
00408
00409 #if VL_STRING_COPY_ON_WRITE == 0
00410 String& operator=(const String& other)
00411 {
00412 other.acquireData();
00413 mString = new StringData(*other.mString);
00414 return *this;
00415 }
00416 #endif
00417
00418 bool operator==(const String& other) const
00419 {
00420 if ( empty() && other.empty() )
00421 return true;
00422 if ( empty() && !other.empty() )
00423 return false;
00424 if ( !empty() && other.empty() )
00425 return false;
00426
00427 createData();
00428
00429 if (mString == other.mString)
00430 return true;
00431 else
00432 if ( other.length() == length() )
00433 {
00434 return memcmp( ptr(), other.ptr(), sizeof(wchar_t)*length() ) == 0;
00435 }
00436 else
00437 return false;
00438 }
00439
00440 bool operator==(const std::string& other) const
00441 {
00442 createData();
00443
00444 if ( (int)other.length() == length() )
00445 {
00446 for(int i=0; i<length(); ++i)
00447 if ((*mString)[i] != (wchar_t)other[i])
00448 return false;
00449 return true;
00450 }
00451 else
00452 return false;
00453 }
00454
00455 bool operator==(const std::wstring& other) const
00456 {
00457 createData();
00458
00459 if ( (int)other.length() == length() )
00460 {
00461 for(int i=0; i<length(); ++i)
00462 if ((*mString)[i] != other[i])
00463 return false;
00464 return true;
00465 }
00466 else
00467 return false;
00468 }
00469
00470 bool operator==(const char* other) const
00471 {
00472 createData();
00473
00474 int i=0;
00475 for(; other[i] && i<length(); ++i)
00476 if ( (*mString)[i] != (wchar_t)other[i] )
00477 return false;
00478 return i == length() && other[i] == 0;
00479 }
00480
00481 bool operator==(const wchar_t* other) const
00482 {
00483 createData();
00484
00485 int i=0;
00486 for(; other[i] && i<length(); ++i)
00487 if ( (*mString)[i] != other[i] )
00488 return false;
00489 return i == length() && other[i] == 0;
00490 }
00491
00492 bool operator!=(const String& other) const
00493 {
00494 return !this->operator==(other);
00495 }
00496
00497 bool operator!=(const std::string& other) const
00498 {
00499 return !this->operator==(other);
00500 }
00501
00502 bool operator!=(const std::wstring& other) const
00503 {
00504 return !this->operator==(other);
00505 }
00506
00507 bool operator!=(const char* other) const
00508 {
00509 return !this->operator==(other);
00510 }
00511
00512 bool operator!=(const wchar_t* other) const
00513 {
00514 return !this->operator==(other);
00515 }
00516
00517 String& operator+=(wchar_t ch)
00518 {
00519 acquireData();
00520 mString->push_back(ch);
00521 return *this;
00522 }
00523
00524 String operator+(wchar_t ch) const
00525 {
00526 String tmp = *this;
00527 tmp += ch;
00528 return tmp;
00529 }
00530
00531 String& operator+=(const String& other)
00532 {
00533 return append(other);
00534 }
00535
00536 String operator+(const String& other) const
00537 {
00538 String tmp = *this;
00539 tmp.append(other);
00540 return tmp;
00541 }
00542
00544 void acquireData() const
00545 {
00546 createData();
00547
00548 if (mString->referenceCount() > 1)
00549 mString = new StringData(*mString);
00550 }
00551
00552 protected:
00553 void createData() const { if (!mString) mString = new StringData; }
00554
00555 private:
00556 class StringData: public Object
00557 {
00558 public:
00559 void clear() { mWString.clear(); }
00560 void push_back(wchar_t a) { mWString.push_back(a); }
00561 const wchar_t& operator[](int i) const { return mWString[i]; }
00562 wchar_t& operator[](int i) { return mWString[i]; }
00563 int length() const { return (int)mWString.length(); }
00564 void resize(int size) { mWString.resize(size); }
00565 void squeeze()
00566 {
00567 std::wstring new_string = mWString;
00568 mWString.swap( new_string );
00569 }
00570 protected:
00571 std::wstring mWString;
00572 };
00573
00574 mutable ref<StringData> mString;
00575 };
00576
00577 inline String operator+(const wchar_t* pstr, const String& str)
00578 {
00579 return String(pstr) + str;
00580 }
00581
00582 inline String operator+(const char* pstr, const String& str)
00583 {
00584 return String(pstr) + str;
00585 }
00586
00587 inline String operator+(wchar_t ch, const String& str)
00588 {
00589 return String(ch,1) + str;
00590 }
00591
00592 inline String operator+(char ch, const String& str)
00593 {
00594 return String(ch,1) + str;
00595 }
00596
00597 }
00598
00599 #endif