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 "MyWindows.h" 14 #include "MyTypes.h" 15 #include "MyVector.h" 16 17 18 #ifdef _MSC_VER 19 #ifdef _NATIVE_WCHAR_T_DEFINED 20 #define MY_NATIVE_WCHAR_T_DEFINED 21 #endif 22 #else 23 #define MY_NATIVE_WCHAR_T_DEFINED 24 #endif 25 26 /* 27 native support for wchar_t: 28 _MSC_VER == 1600 : /Zc:wchar_t is not supported 29 _MSC_VER == 1310 (VS2003) 30 ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short 31 /Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED 32 _MSC_VER > 1400 (VS2008+) 33 /Zc:wchar_t[-] 34 /Zc:wchar_t is on by default 35 */ 36 37 #ifdef _WIN32 38 #define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/') 39 #else 40 #define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR) 41 #endif 42 43 inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); } 44 inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); } 45 46 inline unsigned MyStringLen(const char *s) 47 { 48 unsigned i; 49 for (i = 0; s[i] != 0; i++); 50 return i; 51 } 52 53 inline void MyStringCopy(char *dest, const char *src) 54 { 55 while ((*dest++ = *src++) != 0); 56 } 57 58 inline char *MyStpCpy(char *dest, const char *src) 59 { 60 for (;;) 61 { 62 char c = *src; 63 *dest = c; 64 if (c == 0) 65 return dest; 66 src++; 67 dest++; 68 } 69 } 70 71 inline unsigned MyStringLen(const wchar_t *s) 72 { 73 unsigned i; 74 for (i = 0; s[i] != 0; i++); 75 return i; 76 } 77 78 inline void MyStringCopy(wchar_t *dest, const wchar_t *src) 79 { 80 while ((*dest++ = *src++) != 0); 81 } 82 83 inline void MyStringCat(wchar_t *dest, const wchar_t *src) 84 { 85 MyStringCopy(dest + MyStringLen(dest), src); 86 } 87 88 89 /* 90 inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src) 91 { 92 for (;;) 93 { 94 wchar_t c = *src; 95 *dest = c; 96 if (c == 0) 97 return dest; 98 src++; 99 dest++; 100 } 101 } 102 */ 103 104 int FindCharPosInString(const char *s, char c) throw(); 105 int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); 106 107 #ifdef _WIN32 108 #ifndef _UNICODE 109 #define STRING_UNICODE_THROW 110 #endif 111 #endif 112 113 #ifndef STRING_UNICODE_THROW 114 #define STRING_UNICODE_THROW throw() 115 #endif 116 117 118 inline char MyCharUpper_Ascii(char c) 119 { 120 if (c >= 'a' && c <= 'z') 121 return (char)((unsigned char)c - 0x20); 122 return c; 123 } 124 125 /* 126 inline wchar_t MyCharUpper_Ascii(wchar_t c) 127 { 128 if (c >= 'a' && c <= 'z') 129 return (wchar_t)(c - 0x20); 130 return c; 131 } 132 */ 133 134 inline char MyCharLower_Ascii(char c) 135 { 136 if (c >= 'A' && c <= 'Z') 137 return (char)((unsigned char)c + 0x20); 138 return c; 139 } 140 141 inline wchar_t MyCharLower_Ascii(wchar_t c) 142 { 143 if (c >= 'A' && c <= 'Z') 144 return (wchar_t)(c + 0x20); 145 return c; 146 } 147 148 wchar_t MyCharUpper_WIN(wchar_t c) throw(); 149 150 inline wchar_t MyCharUpper(wchar_t c) throw() 151 { 152 if (c < 'a') return c; 153 if (c <= 'z') return (wchar_t)(c - 0x20); 154 if (c <= 0x7F) return c; 155 #ifdef _WIN32 156 #ifdef _UNICODE 157 return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); 158 #else 159 return (wchar_t)MyCharUpper_WIN(c); 160 #endif 161 #else 162 return (wchar_t)towupper(c); 163 #endif 164 } 165 166 /* 167 wchar_t MyCharLower_WIN(wchar_t c) throw(); 168 169 inline wchar_t MyCharLower(wchar_t c) throw() 170 { 171 if (c < 'A') return c; 172 if (c <= 'Z') return (wchar_t)(c + 0x20); 173 if (c <= 0x7F) return c; 174 #ifdef _WIN32 175 #ifdef _UNICODE 176 return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); 177 #else 178 return (wchar_t)MyCharLower_WIN(c); 179 #endif 180 #else 181 return (wchar_t)tolower(c); 182 #endif 183 } 184 */ 185 186 // char *MyStringUpper(char *s) throw(); 187 // char *MyStringLower(char *s) throw(); 188 189 // void MyStringUpper_Ascii(char *s) throw(); 190 // void MyStringUpper_Ascii(wchar_t *s) throw(); 191 void MyStringLower_Ascii(char *s) throw(); 192 void MyStringLower_Ascii(wchar_t *s) throw(); 193 // wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; 194 // wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; 195 196 bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 197 198 bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); 199 bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); 200 bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw(); 201 bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw(); 202 bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw(); 203 204 #define MyStringCompare(s1, s2) wcscmp(s1, s2) 205 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 206 // int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); 207 208 // ---------- ASCII ---------- 209 // char values in ASCII strings must be less then 128 210 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); 211 bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); 212 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); 213 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); 214 215 #define MY_STRING_DELETE(_p_) delete []_p_; 216 // #define MY_STRING_DELETE(_p_) my_delete(_p_); 217 218 219 #define FORBID_STRING_OPS_2(cls, t) \ 220 void Find(t) const; \ 221 void Find(t, unsigned startIndex) const; \ 222 void ReverseFind(t) const; \ 223 void InsertAtFront(t); \ 224 void RemoveChar(t); \ 225 void Replace(t, t); \ 226 227 #define FORBID_STRING_OPS(cls, t) \ 228 explicit cls(t); \ 229 explicit cls(const t *); \ 230 cls &operator=(t); \ 231 cls &operator=(const t *); \ 232 cls &operator+=(t); \ 233 cls &operator+=(const t *); \ 234 FORBID_STRING_OPS_2(cls, t); \ 235 236 /* 237 cls &operator+(t); \ 238 cls &operator+(const t *); \ 239 */ 240 241 #define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t) 242 #define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t) 243 #define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t) 244 245 class AString 246 { 247 char *_chars; 248 unsigned _len; 249 unsigned _limit; 250 251 void MoveItems(unsigned dest, unsigned src) 252 { 253 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); 254 } 255 256 void InsertSpace(unsigned &index, unsigned size); 257 258 void ReAlloc(unsigned newLimit); 259 void ReAlloc2(unsigned newLimit); 260 void SetStartLen(unsigned len); 261 void Grow_1(); 262 void Grow(unsigned n); 263 264 AString(unsigned num, const char *s); 265 AString(unsigned num, const AString &s); 266 AString(const AString &s, char c); // it's for String + char 267 AString(const char *s1, unsigned num1, const char *s2, unsigned num2); 268 269 friend AString operator+(const AString &s, char c) { return AString(s, c); } ; 270 // friend AString operator+(char c, const AString &s); // is not supported 271 272 friend AString operator+(const AString &s1, const AString &s2); 273 friend AString operator+(const AString &s1, const char *s2); 274 friend AString operator+(const char *s1, const AString &s2); 275 276 // ---------- forbidden functions ---------- 277 278 #ifdef MY_NATIVE_WCHAR_T_DEFINED 279 FORBID_STRING_OPS_AString(wchar_t) 280 #endif 281 282 FORBID_STRING_OPS_AString(signed char) 283 FORBID_STRING_OPS_AString(unsigned char) 284 FORBID_STRING_OPS_AString(short) 285 FORBID_STRING_OPS_AString(unsigned short) 286 FORBID_STRING_OPS_AString(int) 287 FORBID_STRING_OPS_AString(unsigned) 288 FORBID_STRING_OPS_AString(long) 289 FORBID_STRING_OPS_AString(unsigned long) 290 291 public: 292 explicit AString(); 293 explicit AString(char c); 294 explicit AString(const char *s); 295 AString(const AString &s); 296 ~AString() { MY_STRING_DELETE(_chars); } 297 298 unsigned Len() const { return _len; } 299 bool IsEmpty() const { return _len == 0; } 300 void Empty() { _len = 0; _chars[0] = 0; } 301 302 operator const char *() const { return _chars; } 303 const char *Ptr() const { return _chars; } 304 const char *Ptr(unsigned pos) const { return _chars + pos; } 305 const char *RightPtr(unsigned num) const { return _chars + _len - num; } 306 char Back() const { return _chars[(size_t)_len - 1]; } 307 308 void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } 309 310 char *GetBuf() { return _chars; } 311 /* GetBuf(minLen): provides the buffer that can store 312 at least (minLen) characters and additional null terminator. 313 9.35: GetBuf doesn't preserve old characters and terminator */ 314 char *GetBuf(unsigned minLen) 315 { 316 if (minLen > _limit) 317 ReAlloc2(minLen); 318 return _chars; 319 } 320 char *GetBuf_SetEnd(unsigned minLen) 321 { 322 if (minLen > _limit) 323 ReAlloc2(minLen); 324 char *chars = _chars; 325 chars[minLen] = 0; 326 _len = minLen; 327 return chars; 328 } 329 330 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } 331 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 332 void ReleaseBuf_CalcLen(unsigned maxLen) 333 { 334 char *chars = _chars; 335 chars[maxLen] = 0; 336 _len = MyStringLen(chars); 337 } 338 339 AString &operator=(char c); 340 AString &operator=(const char *s); 341 AString &operator=(const AString &s); 342 void SetFromWStr_if_Ascii(const wchar_t *s); 343 // void SetFromBstr_if_Ascii(BSTR s); 344 345 AString &operator+=(char c) 346 { 347 if (_limit == _len) 348 Grow_1(); 349 unsigned len = _len; 350 char *chars = _chars; 351 chars[len++] = c; 352 chars[len] = 0; 353 _len = len; 354 return *this; 355 } 356 357 void Add_Space(); 358 void Add_Space_if_NotEmpty(); 359 void Add_OptSpaced(const char *s); 360 void Add_LF(); 361 void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); } 362 363 AString &operator+=(const char *s); 364 AString &operator+=(const AString &s); 365 366 void Add_UInt32(UInt32 v); 367 368 void SetFrom(const char *s, unsigned len); // no check 369 void SetFrom_CalcLen(const char *s, unsigned len); 370 371 AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); } 372 AString Left(unsigned count) const { return AString(count, *this); } 373 374 // void MakeUpper() { MyStringUpper(_chars); } 375 // void MakeLower() { MyStringLower(_chars); } 376 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } 377 378 379 bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; } 380 bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } 381 // int Compare(const char *s) const { return MyStringCompare(_chars, s); } 382 // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } 383 // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } 384 // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 385 bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } 386 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 387 388 bool IsAscii() const 389 { 390 unsigned len = Len(); 391 const char *s = _chars; 392 for (unsigned i = 0; i < len; i++) 393 if ((unsigned char)s[i] >= 0x80) 394 return false; 395 return true; 396 } 397 int Find(char c) const { return FindCharPosInString(_chars, c); } 398 int Find(char c, unsigned startIndex) const 399 { 400 int pos = FindCharPosInString(_chars + startIndex, c); 401 return pos < 0 ? -1 : (int)startIndex + pos; 402 } 403 404 int ReverseFind(char c) const throw(); 405 int ReverseFind_Dot() const throw() { return ReverseFind('.'); } 406 int ReverseFind_PathSepar() const throw(); 407 408 int Find(const char *s) const { return Find(s, 0); } 409 int Find(const char *s, unsigned startIndex) const throw(); 410 411 void TrimLeft() throw(); 412 void TrimRight() throw(); 413 void Trim() 414 { 415 TrimRight(); 416 TrimLeft(); 417 } 418 419 void InsertAtFront(char c); 420 // void Insert(unsigned index, char c); 421 void Insert(unsigned index, const char *s); 422 void Insert(unsigned index, const AString &s); 423 424 void RemoveChar(char ch) throw(); 425 426 void Replace(char oldChar, char newChar) throw(); 427 void Replace(const AString &oldString, const AString &newString); 428 429 void Delete(unsigned index) throw(); 430 void Delete(unsigned index, unsigned count) throw(); 431 void DeleteFrontal(unsigned num) throw(); 432 void DeleteBack() { _chars[--_len] = 0; } 433 void DeleteFrom(unsigned index) 434 { 435 if (index < _len) 436 { 437 _len = index; 438 _chars[index] = 0; 439 } 440 } 441 }; 442 443 bool operator<(const AString &s1, const AString &s2); 444 bool operator>(const AString &s1, const AString &s2); 445 446 /* 447 bool operator==(const AString &s1, const AString &s2); 448 bool operator==(const AString &s1, const char *s2); 449 bool operator==(const char *s1, const AString &s2); 450 451 bool operator!=(const AString &s1, const AString &s2); 452 bool operator!=(const AString &s1, const char *s2); 453 bool operator!=(const char *s1, const AString &s2); 454 */ 455 456 inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } 457 inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } 458 inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } 459 460 inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } 461 inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } 462 inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } 463 464 // ---------- forbidden functions ---------- 465 466 void operator==(char c1, const AString &s2); 467 void operator==(const AString &s1, char c2); 468 469 void operator+(char c, const AString &s); // this function can be OK, but we don't use it 470 471 void operator+(const AString &s, int c); 472 void operator+(const AString &s, unsigned c); 473 void operator+(int c, const AString &s); 474 void operator+(unsigned c, const AString &s); 475 void operator-(const AString &s, int c); 476 void operator-(const AString &s, unsigned c); 477 478 479 class UString 480 { 481 wchar_t *_chars; 482 unsigned _len; 483 unsigned _limit; 484 485 void MoveItems(unsigned dest, unsigned src) 486 { 487 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); 488 } 489 490 void InsertSpace(unsigned index, unsigned size); 491 492 void ReAlloc(unsigned newLimit); 493 void ReAlloc2(unsigned newLimit); 494 void SetStartLen(unsigned len); 495 void Grow_1(); 496 void Grow(unsigned n); 497 498 UString(unsigned num, const wchar_t *s); // for Mid 499 UString(unsigned num, const UString &s); // for Left 500 UString(const UString &s, wchar_t c); // it's for String + char 501 UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); 502 503 friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; 504 // friend UString operator+(wchar_t c, const UString &s); // is not supported 505 506 friend UString operator+(const UString &s1, const UString &s2); 507 friend UString operator+(const UString &s1, const wchar_t *s2); 508 friend UString operator+(const wchar_t *s1, const UString &s2); 509 510 // ---------- forbidden functions ---------- 511 512 FORBID_STRING_OPS_UString(signed char) 513 FORBID_STRING_OPS_UString(unsigned char) 514 FORBID_STRING_OPS_UString(short) 515 516 #ifdef MY_NATIVE_WCHAR_T_DEFINED 517 FORBID_STRING_OPS_UString(unsigned short) 518 #endif 519 520 FORBID_STRING_OPS_UString(int) 521 FORBID_STRING_OPS_UString(unsigned) 522 FORBID_STRING_OPS_UString(long) 523 FORBID_STRING_OPS_UString(unsigned long) 524 525 FORBID_STRING_OPS_2(UString, char) 526 527 public: 528 UString(); 529 explicit UString(wchar_t c); 530 explicit UString(char c); 531 explicit UString(const char *s); 532 // UString(const AString &s); 533 UString(const wchar_t *s); 534 UString(const UString &s); 535 ~UString() { MY_STRING_DELETE(_chars); } 536 537 unsigned Len() const { return _len; } 538 bool IsEmpty() const { return _len == 0; } 539 void Empty() { _len = 0; _chars[0] = 0; } 540 541 operator const wchar_t *() const { return _chars; } 542 const wchar_t *Ptr() const { return _chars; } 543 const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } 544 const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } 545 wchar_t Back() const { return _chars[(size_t)_len - 1]; } 546 547 void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } 548 549 wchar_t *GetBuf() { return _chars; } 550 551 wchar_t *GetBuf(unsigned minLen) 552 { 553 if (minLen > _limit) 554 ReAlloc2(minLen); 555 return _chars; 556 } 557 wchar_t *GetBuf_SetEnd(unsigned minLen) 558 { 559 if (minLen > _limit) 560 ReAlloc2(minLen); 561 wchar_t *chars = _chars; 562 chars[minLen] = 0; 563 _len = minLen; 564 return chars; 565 } 566 567 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } 568 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 569 void ReleaseBuf_CalcLen(unsigned maxLen) 570 { 571 wchar_t *chars = _chars; 572 chars[maxLen] = 0; 573 _len = MyStringLen(chars); 574 } 575 576 UString &operator=(wchar_t c); 577 UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); } 578 UString &operator=(const wchar_t *s); 579 UString &operator=(const UString &s); 580 void SetFrom(const wchar_t *s, unsigned len); // no check 581 void SetFromBstr(BSTR s); 582 UString &operator=(const char *s); 583 UString &operator=(const AString &s) { return operator=(s.Ptr()); } 584 585 UString &operator+=(wchar_t c) 586 { 587 if (_limit == _len) 588 Grow_1(); 589 unsigned len = _len; 590 wchar_t *chars = _chars; 591 chars[len++] = c; 592 chars[len] = 0; 593 _len = len; 594 return *this; 595 } 596 597 UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); } 598 599 void Add_Space(); 600 void Add_Space_if_NotEmpty(); 601 void Add_LF(); 602 void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); } 603 604 UString &operator+=(const wchar_t *s); 605 UString &operator+=(const UString &s); 606 UString &operator+=(const char *s); 607 UString &operator+=(const AString &s) { return operator+=(s.Ptr()); } 608 609 void Add_UInt32(UInt32 v); 610 611 UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } 612 UString Left(unsigned count) const { return UString(count, *this); } 613 614 // void MakeUpper() { MyStringUpper(_chars); } 615 // void MakeUpper() { MyStringUpper_Ascii(_chars); } 616 // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } 617 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } 618 619 bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } 620 bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } 621 bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } 622 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } 623 // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } 624 // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } 625 // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 626 bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); } 627 bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); } 628 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 629 630 bool IsAscii() const 631 { 632 unsigned len = Len(); 633 const wchar_t *s = _chars; 634 for (unsigned i = 0; i < len; i++) 635 if (s[i] >= 0x80) 636 return false; 637 return true; 638 } 639 int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } 640 int Find(wchar_t c, unsigned startIndex) const 641 { 642 int pos = FindCharPosInString(_chars + startIndex, c); 643 return pos < 0 ? -1 : (int)startIndex + pos; 644 } 645 646 int ReverseFind(wchar_t c) const throw(); 647 int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); } 648 int ReverseFind_PathSepar() const throw(); 649 650 int Find(const wchar_t *s) const { return Find(s, 0); } 651 int Find(const wchar_t *s, unsigned startIndex) const throw(); 652 653 void TrimLeft() throw(); 654 void TrimRight() throw(); 655 void Trim() 656 { 657 TrimRight(); 658 TrimLeft(); 659 } 660 661 void InsertAtFront(wchar_t c); 662 // void Insert(unsigned index, wchar_t c); 663 void Insert(unsigned index, const wchar_t *s); 664 void Insert(unsigned index, const UString &s); 665 666 void RemoveChar(wchar_t ch) throw(); 667 668 void Replace(wchar_t oldChar, wchar_t newChar) throw(); 669 void Replace(const UString &oldString, const UString &newString); 670 671 void Delete(unsigned index) throw(); 672 void Delete(unsigned index, unsigned count) throw(); 673 void DeleteFrontal(unsigned num) throw(); 674 void DeleteBack() { _chars[--_len] = 0; } 675 void DeleteFrom(unsigned index) 676 { 677 if (index < _len) 678 { 679 _len = index; 680 _chars[index] = 0; 681 } 682 } 683 }; 684 685 bool operator<(const UString &s1, const UString &s2); 686 bool operator>(const UString &s1, const UString &s2); 687 688 inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } 689 inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } 690 inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } 691 692 inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } 693 inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } 694 inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } 695 696 697 // ---------- forbidden functions ---------- 698 699 void operator==(wchar_t c1, const UString &s2); 700 void operator==(const UString &s1, wchar_t c2); 701 702 void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it 703 704 void operator+(const AString &s1, const UString &s2); 705 void operator+(const UString &s1, const AString &s2); 706 707 void operator+(const UString &s1, const char *s2); 708 void operator+(const char *s1, const UString &s2); 709 710 void operator+(const UString &s, char c); 711 void operator+(const UString &s, unsigned char c); 712 void operator+(char c, const UString &s); 713 void operator+(unsigned char c, const UString &s); 714 void operator-(const UString &s1, wchar_t c); 715 716 #ifdef _WIN32 717 // can we forbid these functions, if wchar_t is 32-bit ? 718 void operator+(const UString &s, int c); 719 void operator+(const UString &s, unsigned c); 720 void operator+(int c, const UString &s); 721 void operator+(unsigned c, const UString &s); 722 void operator-(const UString &s1, int c); 723 void operator-(const UString &s1, unsigned c); 724 #endif 725 726 727 728 729 730 731 732 class UString2 733 { 734 wchar_t *_chars; 735 unsigned _len; 736 737 void ReAlloc2(unsigned newLimit); 738 void SetStartLen(unsigned len); 739 740 // ---------- forbidden functions ---------- 741 742 FORBID_STRING_OPS_UString2(char) 743 FORBID_STRING_OPS_UString2(signed char) 744 FORBID_STRING_OPS_UString2(unsigned char) 745 FORBID_STRING_OPS_UString2(short) 746 747 UString2 &operator=(wchar_t c); 748 UString2(wchar_t c); 749 750 public: 751 UString2(): _chars(NULL), _len(0) {} 752 UString2(const wchar_t *s); 753 UString2(const UString2 &s); 754 ~UString2() { if (_chars) MY_STRING_DELETE(_chars); } 755 756 unsigned Len() const { return _len; } 757 bool IsEmpty() const { return _len == 0; } 758 // void Empty() { _len = 0; _chars[0] = 0; } 759 760 // operator const wchar_t *() const { return _chars; } 761 const wchar_t *GetRawPtr() const { return _chars; } 762 763 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } 764 765 wchar_t *GetBuf(unsigned minLen) 766 { 767 if (!_chars || minLen > _len) 768 ReAlloc2(minLen); 769 return _chars; 770 } 771 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } 772 773 UString2 &operator=(const wchar_t *s); 774 UString2 &operator=(const UString2 &s); 775 void SetFromAscii(const char *s); 776 }; 777 778 bool operator==(const UString2 &s1, const UString2 &s2); 779 bool operator==(const UString2 &s1, const wchar_t *s2); 780 bool operator==(const wchar_t *s1, const UString2 &s2); 781 782 inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); } 783 inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); } 784 inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); } 785 786 787 // ---------- forbidden functions ---------- 788 789 void operator==(wchar_t c1, const UString2 &s2); 790 void operator==(const UString2 &s1, wchar_t c2); 791 bool operator<(const UString2 &s1, const UString2 &s2); 792 bool operator>(const UString2 &s1, const UString2 &s2); 793 794 void operator+(const UString2 &s1, const UString2 &s2); 795 void operator+(const UString2 &s1, const wchar_t *s2); 796 void operator+(const wchar_t *s1, const UString2 &s2); 797 void operator+(wchar_t c, const UString2 &s); 798 void operator+(const UString2 &s, wchar_t c); 799 void operator+(const UString2 &s, char c); 800 void operator+(const UString2 &s, unsigned char c); 801 void operator+(char c, const UString2 &s); 802 void operator+(unsigned char c, const UString2 &s); 803 void operator-(const UString2 &s1, wchar_t c); 804 805 806 807 808 809 810 typedef CObjectVector<AString> AStringVector; 811 typedef CObjectVector<UString> UStringVector; 812 813 #ifdef _UNICODE 814 typedef UString CSysString; 815 #else 816 typedef AString CSysString; 817 #endif 818 819 typedef CObjectVector<CSysString> CSysStringVector; 820 821 822 // ---------- FString ---------- 823 824 #ifdef _WIN32 825 #define USE_UNICODE_FSTRING 826 #endif 827 828 #ifdef USE_UNICODE_FSTRING 829 830 #define __FTEXT(quote) L##quote 831 832 typedef wchar_t FChar; 833 typedef UString FString; 834 835 #define fs2us(_x_) (_x_) 836 #define us2fs(_x_) (_x_) 837 FString fas2fs(const char *s); 838 FString fas2fs(const AString &s); 839 AString fs2fas(const FChar *s); 840 841 #else 842 843 #define __FTEXT(quote) quote 844 845 typedef char FChar; 846 typedef AString FString; 847 848 UString fs2us(const FChar *s); 849 UString fs2us(const FString &s); 850 FString us2fs(const wchar_t *s); 851 #define fas2fs(_x_) (_x_) 852 #define fs2fas(_x_) (_x_) 853 854 #endif 855 856 #define FTEXT(quote) __FTEXT(quote) 857 858 #define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) 859 #define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) 860 861 // #define FCHAR_ANY_MASK FTEXT('*') 862 // #define FSTRING_ANY_MASK FTEXT("*") 863 864 typedef const FChar *CFSTR; 865 866 typedef CObjectVector<FString> FStringVector; 867 868 #endif 869