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