1// Common/String.h 2 3#ifndef __COMMON_STRING_H 4#define __COMMON_STRING_H 5 6#include <string.h> 7 8#ifndef _WIN32 9#include <wctype.h> 10#include <wchar.h> 11#endif 12 13#include "MyTypes.h" 14#include "MyVector.h" 15 16inline unsigned MyStringLen(const char *s) 17{ 18 unsigned i; 19 for (i = 0; s[i] != 0; i++); 20 return i; 21} 22 23inline void MyStringCopy(char *dest, const char *src) 24{ 25 while ((*dest++ = *src++) != 0); 26} 27 28inline char *MyStpCpy(char *dest, const char *src) 29{ 30 for (;;) 31 { 32 char c = *src; 33 *dest = c; 34 if (c == 0) 35 return dest; 36 src++; 37 dest++; 38 } 39} 40 41inline unsigned MyStringLen(const wchar_t *s) 42{ 43 unsigned i; 44 for (i = 0; s[i] != 0; i++); 45 return i; 46} 47 48inline void MyStringCopy(wchar_t *dest, const wchar_t *src) 49{ 50 while ((*dest++ = *src++) != 0); 51} 52 53int FindCharPosInString(const char *s, char c) throw(); 54int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); 55 56#ifdef _WIN32 57 #ifndef _UNICODE 58 #define STRING_UNICODE_THROW 59 #endif 60#endif 61 62#ifndef STRING_UNICODE_THROW 63 #define STRING_UNICODE_THROW throw() 64#endif 65 66/* 67inline char MyCharUpper_Ascii(char c) 68{ 69 if (c >= 'a' && c <= 'z') 70 return (char)(c - 0x20); 71 return c; 72} 73inline wchar_t MyCharUpper_Ascii(wchar_t c) 74{ 75 if (c >= 'a' && c <= 'z') 76 return (wchar_t)(c - 0x20); 77 return c; 78} 79*/ 80 81inline char MyCharLower_Ascii(char c) 82{ 83 if (c >= 'A' && c <= 'Z') 84 return (char)(c + 0x20); 85 return c; 86} 87 88inline wchar_t MyCharLower_Ascii(wchar_t c) 89{ 90 if (c >= 'A' && c <= 'Z') 91 return (wchar_t)(c + 0x20); 92 return c; 93} 94 95wchar_t MyCharUpper_WIN(wchar_t c) throw(); 96 97inline wchar_t MyCharUpper(wchar_t c) throw() 98{ 99 if (c < 'a') return c; 100 if (c <= 'z') return (wchar_t)(c - 0x20); 101 if (c <= 0x7F) return c; 102 #ifdef _WIN32 103 #ifdef _UNICODE 104 return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); 105 #else 106 return (wchar_t)MyCharUpper_WIN(c); 107 #endif 108 #else 109 return (wchar_t)towupper(c); 110 #endif 111} 112 113/* 114wchar_t MyCharLower_WIN(wchar_t c) throw(); 115 116inline wchar_t MyCharLower(wchar_t c) throw() 117{ 118 if (c < 'A') return c; 119 if (c <= 'Z') return (wchar_t)(c + 0x20); 120 if (c <= 0x7F) return c; 121 #ifdef _WIN32 122 #ifdef _UNICODE 123 return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); 124 #else 125 return (wchar_t)MyCharLower_WIN(c); 126 #endif 127 #else 128 return (wchar_t)tolower(c); 129 #endif 130} 131*/ 132 133// char *MyStringUpper(char *s) throw(); 134// char *MyStringLower(char *s) throw(); 135 136// void MyStringUpper_Ascii(wchar_t *s) throw(); 137void MyStringLower_Ascii(wchar_t *s) throw(); 138// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; 139// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; 140 141bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 142 143bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); 144bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); 145 146int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 147int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); 148 149// ---------- ASCII ---------- 150// char values in ASCII strings must be less then 128 151bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); 152bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); 153bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); 154bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); 155 156#define MY_STRING_DELETE(_p_) delete []_p_; 157// #define MY_STRING_DELETE(_p_) my_delete(_p_); 158 159class AString 160{ 161 char *_chars; 162 unsigned _len; 163 unsigned _limit; 164 165 void MoveItems(unsigned dest, unsigned src) 166 { 167 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); 168 } 169 170 void InsertSpace(unsigned &index, unsigned size); 171 172 void ReAlloc(unsigned newLimit); 173 void SetStartLen(unsigned len); 174 void Grow_1(); 175 void Grow(unsigned n); 176 177 // AString(unsigned num, const char *s); 178 AString(unsigned num, const AString &s); 179 AString(const AString &s, char c); // it's for String + char 180 AString(const char *s1, unsigned num1, const char *s2, unsigned num2); 181 182 friend AString operator+(const AString &s, char c) { return AString(s, c); } ; 183 // friend AString operator+(char c, const AString &s); // is not supported 184 185 friend AString operator+(const AString &s1, const AString &s2); 186 friend AString operator+(const AString &s1, const char *s2); 187 friend AString operator+(const char *s1, const AString &s2); 188 189public: 190 AString(); 191 AString(char c); 192 AString(const char *s); 193 AString(const AString &s); 194 ~AString() { MY_STRING_DELETE(_chars); } 195 196 unsigned Len() const { return _len; } 197 bool IsEmpty() const { return _len == 0; } 198 void Empty() { _len = 0; _chars[0] = 0; } 199 200 operator const char *() const { return _chars; } 201 const char *Ptr() const { return _chars; } 202 const char *Ptr(unsigned pos) const { return _chars + pos; } 203 const char *RightPtr(unsigned num) const { return _chars + _len - num; } 204 char Back() const { return _chars[_len - 1]; } 205 206 void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } 207 208 // The minimum size of the character buffer in characters. 209 // This value does not include space for a null terminator. 210 char *GetBuffer(unsigned minBufLen) 211 { 212 if (minBufLen > _limit) 213 ReAlloc(minBufLen); 214 return _chars; 215 } 216 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } 217 void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 218 219 AString &operator=(char c); 220 AString &operator=(const char *s); 221 AString &operator=(const AString &s); 222 223 AString &operator+=(char c) 224 { 225 if (_limit == _len) 226 Grow_1(); 227 unsigned len = _len; 228 char *chars = _chars; 229 chars[len++] = c; 230 chars[len] = 0; 231 _len = len; 232 return *this; 233 } 234 235 AString &operator+=(const char *s); 236 AString &operator+=(const AString &s); 237 238 void SetFrom(const char *s, unsigned len); // no check 239 // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); } 240 AString Left(unsigned count) const { return AString(count, *this); } 241 242 // void MakeUpper() { MyStringUpper(_chars); } 243 // void MakeLower() { MyStringLower(_chars); } 244 245 246 // int Compare(const char *s) const { return MyStringCompare(_chars, s); } 247 // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } 248 // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } 249 // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 250 bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } 251 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 252 253 int Find(char c) const { return FindCharPosInString(_chars, c); } 254 int Find(char c, unsigned startIndex) const 255 { 256 int pos = FindCharPosInString(_chars + startIndex, c); 257 return pos < 0 ? -1 : (int)startIndex + pos; 258 } 259 int ReverseFind(char c) const throw(); 260 int Find(const AString &s) const { return Find(s, 0); } 261 int Find(const AString &s, unsigned startIndex) const throw(); 262 263 void TrimLeft() throw(); 264 void TrimRight() throw(); 265 void Trim() 266 { 267 TrimRight(); 268 TrimLeft(); 269 } 270 271 void InsertAtFront(char c); 272 // void Insert(unsigned index, char c); 273 void Insert(unsigned index, const char *s); 274 void Insert(unsigned index, const AString &s); 275 276 void RemoveChar(char ch) throw(); 277 void Replace(char oldChar, char newChar) throw(); 278 void Replace(const AString &oldString, const AString &newString); 279 280 void Delete(unsigned index) throw(); 281 void Delete(unsigned index, unsigned count) throw(); 282 void DeleteFrontal(unsigned num) throw(); 283 void DeleteBack() { _chars[--_len] = 0; } 284 void DeleteFrom(unsigned index) 285 { 286 if (index < _len) 287 { 288 _len = index; 289 _chars[index] = 0; 290 } 291 } 292}; 293 294bool operator<(const AString &s1, const AString &s2); 295bool operator>(const AString &s1, const AString &s2); 296 297/* 298bool operator==(const AString &s1, const AString &s2); 299bool operator==(const AString &s1, const char *s2); 300bool operator==(const char *s1, const AString &s2); 301 302bool operator!=(const AString &s1, const AString &s2); 303bool operator!=(const AString &s1, const char *s2); 304bool operator!=(const char *s1, const AString &s2); 305*/ 306 307inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } 308inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } 309inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } 310 311inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } 312inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } 313inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } 314 315 316 317class UString 318{ 319 wchar_t *_chars; 320 unsigned _len; 321 unsigned _limit; 322 323 void MoveItems(unsigned dest, unsigned src) 324 { 325 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); 326 } 327 328 void InsertSpace(unsigned index, unsigned size); 329 330 void ReAlloc(unsigned newLimit); 331 void SetStartLen(unsigned len); 332 void Grow_1(); 333 void Grow(unsigned n); 334 335 UString(unsigned num, const wchar_t *s); // for Mid 336 UString(unsigned num, const UString &s); // for Left 337 UString(const UString &s, wchar_t c); // it's for String + char 338 UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); 339 340 friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; 341 // friend UString operator+(wchar_t c, const UString &s); // is not supported 342 343 friend UString operator+(const UString &s1, const UString &s2); 344 friend UString operator+(const UString &s1, const wchar_t *s2); 345 friend UString operator+(const wchar_t *s1, const UString &s2); 346 347public: 348 UString(); 349 UString(wchar_t c); 350 UString(const wchar_t *s); 351 UString(const UString &s); 352 ~UString() { MY_STRING_DELETE(_chars); } 353 354 unsigned Len() const { return _len; } 355 bool IsEmpty() const { return _len == 0; } 356 void Empty() { _len = 0; _chars[0] = 0; } 357 358 operator const wchar_t *() const { return _chars; } 359 const wchar_t *Ptr() const { return _chars; } 360 const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } 361 const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } 362 wchar_t Back() const { return _chars[_len - 1]; } 363 364 void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } 365 366 // The minimum size of the character buffer in characters. 367 // This value does not include space for a null terminator. 368 wchar_t *GetBuffer(unsigned minBufLen) 369 { 370 if (minBufLen > _limit) 371 ReAlloc(minBufLen); 372 return _chars; 373 } 374 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } 375 void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 376 377 UString &operator=(wchar_t c); 378 UString &operator=(const wchar_t *s); 379 UString &operator=(const UString &s); 380 381 UString &operator+=(wchar_t c) 382 { 383 if (_limit == _len) 384 Grow_1(); 385 unsigned len = _len; 386 wchar_t *chars = _chars; 387 chars[len++] = c; 388 chars[len] = 0; 389 _len = len; 390 return *this; 391 } 392 393 UString &operator+=(const wchar_t *s); 394 UString &operator+=(const UString &s); 395 396 void SetFrom(const wchar_t *s, unsigned len); // no check 397 398 void SetFromAscii(const char *s); 399 void AddAsciiStr(const char *s); 400 401 UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } 402 UString Left(unsigned count) const { return UString(count, *this); } 403 404 // void MakeUpper() { MyStringUpper(_chars); } 405 // void MakeUpper() { MyStringUpper_Ascii(_chars); } 406 // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } 407 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } 408 409 bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } 410 bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } 411 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } 412 // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } 413 // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } 414 // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 415 bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }; 416 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 417 418 int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } 419 int Find(wchar_t c, unsigned startIndex) const 420 { 421 int pos = FindCharPosInString(_chars + startIndex, c); 422 return pos < 0 ? -1 : (int)startIndex + pos; 423 } 424 int Find(const UString &s) const { return Find(s, 0); } 425 int Find(const UString &s, unsigned startIndex) const throw(); 426 int ReverseFind(wchar_t c) const throw(); 427 428 void TrimLeft() throw(); 429 void TrimRight() throw(); 430 void Trim() 431 { 432 TrimRight(); 433 TrimLeft(); 434 } 435 436 void InsertAtFront(wchar_t c); 437 // void Insert(unsigned index, wchar_t c); 438 void Insert(unsigned index, const wchar_t *s); 439 void Insert(unsigned index, const UString &s); 440 441 void RemoveChar(wchar_t ch) throw(); 442 void Replace(wchar_t oldChar, wchar_t newChar) throw(); 443 void Replace(const UString &oldString, const UString &newString); 444 445 void Delete(unsigned index) throw(); 446 void Delete(unsigned index, unsigned count) throw(); 447 void DeleteFrontal(unsigned num) throw(); 448 void DeleteBack() { _chars[--_len] = 0; } 449 void DeleteFrom(unsigned index) 450 { 451 if (index < _len) 452 { 453 _len = index; 454 _chars[index] = 0; 455 } 456 } 457}; 458 459bool operator<(const UString &s1, const UString &s2); 460bool operator>(const UString &s1, const UString &s2); 461 462inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } 463inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } 464inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } 465 466inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } 467inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } 468inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } 469 470 471typedef CObjectVector<AString> AStringVector; 472typedef CObjectVector<UString> UStringVector; 473 474#ifdef _UNICODE 475 typedef UString CSysString; 476#else 477 typedef AString CSysString; 478#endif 479 480typedef CObjectVector<CSysString> CSysStringVector; 481 482 483// ---------- FString ---------- 484 485#ifdef _WIN32 486 #define USE_UNICODE_FSTRING 487#endif 488 489#ifdef USE_UNICODE_FSTRING 490 491 #define __FTEXT(quote) L##quote 492 493 typedef wchar_t FChar; 494 typedef UString FString; 495 496 #define fs2us(_x_) (_x_) 497 #define us2fs(_x_) (_x_) 498 FString fas2fs(const AString &s); 499 AString fs2fas(const FChar *s); 500 501#else 502 503 #define __FTEXT(quote) quote 504 505 typedef char FChar; 506 typedef AString FString; 507 508 UString fs2us(const FString &s); 509 FString us2fs(const wchar_t *s); 510 #define fas2fs(_x_) (_x_) 511 #define fs2fas(_x_) (_x_) 512 513#endif 514 515#define FTEXT(quote) __FTEXT(quote) 516 517#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) 518#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) 519#define FCHAR_ANY_MASK FTEXT('*') 520#define FSTRING_ANY_MASK FTEXT("*") 521typedef const FChar *CFSTR; 522 523typedef CObjectVector<FString> FStringVector; 524 525#endif 526