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(VL_PLATFORM_WINDOWS)
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 #if defined(VL_PLATFORM_WINDOWS)
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 fromPointer(const void* value);
00289
00291 static String fromInt(int value);
00292
00294 static String fromUInt(unsigned int value);
00295
00297 static String fromLongLong(long long value);
00298
00300 static String fromULongLong(unsigned long long value);
00301
00304 static String fromDouble(double value, int decimals=6);
00305
00307 static String fromStdString(const std::string& str, bool utf8=true);
00308
00310 static String fromStdWString(const std::wstring& str);
00311
00313 static String fromAscii(const char* str, int size=-1);
00314
00318 static String fromUTF16BE(const unsigned short* str, int byte_count=-1);
00319
00323 static String fromUTF16LE(const unsigned short* str, int byte_count=-1);
00324
00327 static String fromUTF16(const unsigned short* str, int byte_count=-1);
00328
00330 static String fromUTF8(const char* str, int byte_count=-1);
00331
00333 static String fromLatin1(const char* str, int character_count=-1);
00334
00336 int toInt(bool hex=false) const;
00337
00339 double toDouble() const;
00340
00342 float toFloat() const { return (float)toDouble(); }
00343
00345 static String printf(const char* fmt, ...);
00346
00348 std::string toStdString() const;
00349
00351 std::wstring toStdWString() const;
00352
00354 void toAscii(std::string& ascii, bool translate_non_ascii_chars=true) const;
00355
00357 void toUTF8(std::vector<unsigned char>& utf8, bool include_utf8_signature=true) const;
00358
00360 void toUTF8(std::string& utf8, bool include_utf8_signature=true) const;
00361
00363 void toUTF16BE(std::vector<unsigned char>& utf16, bool include_utf16be_signature=true) const;
00364
00366 void toUTF16LE(std::vector<unsigned char>& utf16, bool include_utf16le_signature=true) const;
00367
00369 void toLatin1(std::vector<unsigned char>& latin1) const;
00370
00372 String toLowerCase() const;
00373
00375 String toUpperCase() const;
00376
00378 bool operator<(const String& other) const
00379 {
00380 return compare(other) < 0;
00381 }
00382
00384 String& operator=(const char* str)
00385 {
00386 *this = fromUTF8(str);
00387 return *this;
00388 }
00389
00391 String& operator=(const std::string& str)
00392 {
00393 *this = fromUTF8(str.c_str());
00394 return *this;
00395 }
00396
00397 String& operator=(const wchar_t* wstr)
00398 {
00399 acquireData();
00400
00401 mString->clear();
00402 if (wstr)
00403 {
00404 for(int i=0; wstr[i]; ++i)
00405 mString->push_back(wstr[i]);
00406 }
00407 return *this;
00408 }
00409
00410 String& operator=(const std::wstring& str)
00411 {
00412 return operator=(str.c_str());
00413 }
00414
00415 #if VL_STRING_COPY_ON_WRITE == 0
00416 String& operator=(const String& other)
00417 {
00418 other.acquireData();
00419 mString = new StringData(*other.mString);
00420 return *this;
00421 }
00422 #endif
00423
00424 bool operator==(const String& other) const
00425 {
00426 if ( empty() && other.empty() )
00427 return true;
00428 if ( empty() && !other.empty() )
00429 return false;
00430 if ( !empty() && other.empty() )
00431 return false;
00432
00433 createData();
00434
00435 if (mString == other.mString)
00436 return true;
00437 else
00438 if ( other.length() == length() )
00439 {
00440 return memcmp( ptr(), other.ptr(), sizeof(wchar_t)*length() ) == 0;
00441 }
00442 else
00443 return false;
00444 }
00445
00446 bool operator==(const std::string& other) const
00447 {
00448 createData();
00449
00450 if ( (int)other.length() == length() )
00451 {
00452 for(int i=0; i<length(); ++i)
00453 if ((*mString)[i] != (wchar_t)other[i])
00454 return false;
00455 return true;
00456 }
00457 else
00458 return false;
00459 }
00460
00461 bool operator==(const std::wstring& other) const
00462 {
00463 createData();
00464
00465 if ( (int)other.length() == length() )
00466 {
00467 for(int i=0; i<length(); ++i)
00468 if ((*mString)[i] != other[i])
00469 return false;
00470 return true;
00471 }
00472 else
00473 return false;
00474 }
00475
00476 bool operator==(const char* other) const
00477 {
00478 createData();
00479
00480 int i=0;
00481 for(; other[i] && i<length(); ++i)
00482 if ( (*mString)[i] != (wchar_t)other[i] )
00483 return false;
00484 return i == length() && other[i] == 0;
00485 }
00486
00487 bool operator==(const wchar_t* other) const
00488 {
00489 createData();
00490
00491 int i=0;
00492 for(; other[i] && i<length(); ++i)
00493 if ( (*mString)[i] != other[i] )
00494 return false;
00495 return i == length() && other[i] == 0;
00496 }
00497
00498 bool operator!=(const String& other) const
00499 {
00500 return !this->operator==(other);
00501 }
00502
00503 bool operator!=(const std::string& other) const
00504 {
00505 return !this->operator==(other);
00506 }
00507
00508 bool operator!=(const std::wstring& other) const
00509 {
00510 return !this->operator==(other);
00511 }
00512
00513 bool operator!=(const char* other) const
00514 {
00515 return !this->operator==(other);
00516 }
00517
00518 bool operator!=(const wchar_t* other) const
00519 {
00520 return !this->operator==(other);
00521 }
00522
00523 String& operator+=(wchar_t ch)
00524 {
00525 acquireData();
00526 mString->push_back(ch);
00527 return *this;
00528 }
00529
00530 String operator+(wchar_t ch) const
00531 {
00532 String tmp = *this;
00533 tmp += ch;
00534 return tmp;
00535 }
00536
00537 String& operator+=(const String& other)
00538 {
00539 return append(other);
00540 }
00541
00542 String operator+(const String& other) const
00543 {
00544 String tmp = *this;
00545 tmp.append(other);
00546 return tmp;
00547 }
00548
00550 void acquireData() const
00551 {
00552 createData();
00553
00554 if (mString->referenceCount() > 1)
00555 mString = new StringData(*mString);
00556 }
00557
00558 protected:
00559 void createData() const { if (!mString) mString = new StringData; }
00560
00561 private:
00562 class StringData: public Object
00563 {
00564 public:
00565 void clear() { mWString.clear(); }
00566 void push_back(wchar_t a) { mWString.push_back(a); }
00567 const wchar_t& operator[](int i) const { return mWString[i]; }
00568 wchar_t& operator[](int i) { return mWString[i]; }
00569 int length() const { return (int)mWString.length(); }
00570 void resize(int size) { mWString.resize(size); }
00571 void squeeze()
00572 {
00573 std::wstring new_string = mWString;
00574 mWString.swap( new_string );
00575 }
00576 protected:
00577 std::wstring mWString;
00578 };
00579
00580 mutable ref<StringData> mString;
00581 };
00582
00583 inline String operator+(const wchar_t* pstr, const String& str)
00584 {
00585 return String(pstr) + str;
00586 }
00587
00588 inline String operator+(const char* pstr, const String& str)
00589 {
00590 return String(pstr) + str;
00591 }
00592
00593 inline String operator+(wchar_t ch, const String& str)
00594 {
00595 return String(ch,1) + str;
00596 }
00597
00598 inline String operator+(char ch, const String& str)
00599 {
00600 return String(ch,1) + str;
00601 }
00602
00603 }
00604
00605 #endif