1 // Common/MyString.cpp 2 3 #include "StdAfx.h" 4 5 #ifdef _WIN32 6 #include <wchar.h> 7 #else 8 #include <ctype.h> 9 #endif 10 11 #if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING) 12 #include "StringConvert.h" 13 #endif 14 15 #include "MyString.h" 16 17 #define MY_STRING_NEW(_T_, _size_) new _T_[_size_] 18 // #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_))) 19 20 /* 21 inline const char* MyStringGetNextCharPointer(const char *p) throw() 22 { 23 #if defined(_WIN32) && !defined(UNDER_CE) 24 return CharNextA(p); 25 #else 26 return p + 1; 27 #endif 28 } 29 */ 30 31 int FindCharPosInString(const char *s, char c) throw() 32 { 33 for (const char *p = s;; p++) 34 { 35 if (*p == c) 36 return (int)(p - s); 37 if (*p == 0) 38 return -1; 39 // MyStringGetNextCharPointer(p); 40 } 41 } 42 43 int FindCharPosInString(const wchar_t *s, wchar_t c) throw() 44 { 45 for (const wchar_t *p = s;; p++) 46 { 47 if (*p == c) 48 return (int)(p - s); 49 if (*p == 0) 50 return -1; 51 } 52 } 53 54 /* 55 void MyStringUpper_Ascii(wchar_t *s) 56 { 57 for (;;) 58 { 59 wchar_t c = *s; 60 if (c == 0) 61 return; 62 *s++ = MyCharUpper_Ascii(c); 63 } 64 } 65 */ 66 67 void MyStringLower_Ascii(char *s) throw() 68 { 69 for (;;) 70 { 71 char c = *s; 72 if (c == 0) 73 return; 74 *s++ = MyCharLower_Ascii(c); 75 } 76 } 77 78 void MyStringLower_Ascii(wchar_t *s) throw() 79 { 80 for (;;) 81 { 82 wchar_t c = *s; 83 if (c == 0) 84 return; 85 *s++ = MyCharLower_Ascii(c); 86 } 87 } 88 89 #ifdef _WIN32 90 91 #ifdef _UNICODE 92 93 // wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } 94 // wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } 95 // for WinCE - FString - char 96 // const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; } 97 98 #else 99 100 // const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); } 101 // char * MyStringUpper(char *s) { return CharUpperA(s); } 102 // char * MyStringLower(char *s) { return CharLowerA(s); } 103 104 wchar_t MyCharUpper_WIN(wchar_t c) throw() 105 { 106 wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); 107 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 108 return (wchar_t)(unsigned)(UINT_PTR)res; 109 const int kBufSize = 4; 110 char s[kBufSize + 1]; 111 int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); 112 if (numChars == 0 || numChars > kBufSize) 113 return c; 114 s[numChars] = 0; 115 ::CharUpperA(s); 116 ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); 117 return c; 118 } 119 120 /* 121 wchar_t MyCharLower_WIN(wchar_t c) 122 { 123 wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); 124 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 125 return (wchar_t)(unsigned)(UINT_PTR)res; 126 const int kBufSize = 4; 127 char s[kBufSize + 1]; 128 int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); 129 if (numChars == 0 || numChars > kBufSize) 130 return c; 131 s[numChars] = 0; 132 ::CharLowerA(s); 133 ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); 134 return c; 135 } 136 */ 137 138 /* 139 wchar_t * MyStringUpper(wchar_t *s) 140 { 141 if (s == 0) 142 return 0; 143 wchar_t *res = CharUpperW(s); 144 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 145 return res; 146 AString a = UnicodeStringToMultiByte(s); 147 a.MakeUpper(); 148 MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); 149 return s; 150 } 151 */ 152 153 /* 154 wchar_t * MyStringLower(wchar_t *s) 155 { 156 if (s == 0) 157 return 0; 158 wchar_t *res = CharLowerW(s); 159 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 160 return res; 161 AString a = UnicodeStringToMultiByte(s); 162 a.MakeLower(); 163 MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); 164 return s; 165 } 166 */ 167 168 #endif 169 170 #endif 171 172 bool IsString1PrefixedByString2(const char *s1, const char *s2) throw() 173 { 174 for (;;) 175 { 176 unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true; 177 unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false; 178 } 179 } 180 181 bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() 182 { 183 for (;;) 184 { 185 wchar_t c1 = *s1++; 186 wchar_t c2 = *s2++; 187 if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; 188 if (c1 == 0) return true; 189 } 190 } 191 192 // ---------- ASCII ---------- 193 194 bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() 195 { 196 const char *s1 = _chars; 197 for (;;) 198 { 199 char c2 = *s++; 200 if (c2 == 0) 201 return true; 202 char c1 = *s1++; 203 if (MyCharLower_Ascii(c1) != 204 MyCharLower_Ascii(c2)) 205 return false; 206 } 207 } 208 209 bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() 210 { 211 const wchar_t *s1 = _chars; 212 for (;;) 213 { 214 char c2 = *s++; 215 if (c2 == 0) 216 return true; 217 wchar_t c1 = *s1++; 218 if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) 219 return false; 220 } 221 } 222 223 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() 224 { 225 for (;;) 226 { 227 unsigned char c = *a; 228 if (c != *u) 229 return false; 230 if (c == 0) 231 return true; 232 a++; 233 u++; 234 } 235 } 236 237 bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() 238 { 239 for (;;) 240 { 241 char c1 = *s1++; 242 char c2 = *s2++; 243 if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) 244 return false; 245 if (c1 == 0) 246 return true; 247 } 248 } 249 250 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() 251 { 252 for (;;) 253 { 254 wchar_t c1 = *s1++; 255 wchar_t c2 = *s2++; 256 if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) 257 return false; 258 if (c1 == 0) 259 return true; 260 } 261 } 262 263 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() 264 { 265 for (;;) 266 { 267 wchar_t c1 = *s1++; 268 char c2 = *s2++; 269 if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))) 270 return false; 271 if (c1 == 0) 272 return true; 273 } 274 } 275 276 bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw() 277 { 278 for (;;) 279 { 280 wchar_t c2 = *s2++; if (c2 == 0) return true; 281 wchar_t c1 = *s1++; if (c1 != c2) return false; 282 } 283 } 284 285 bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw() 286 { 287 for (;;) 288 { 289 wchar_t c2 = *s2++; if (c2 == 0) return true; 290 wchar_t c1 = *s1++; 291 if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) 292 return false; 293 } 294 } 295 296 // NTFS order: uses upper case 297 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() 298 { 299 for (;;) 300 { 301 wchar_t c1 = *s1++; 302 wchar_t c2 = *s2++; 303 if (c1 != c2) 304 { 305 wchar_t u1 = MyCharUpper(c1); 306 wchar_t u2 = MyCharUpper(c2); 307 if (u1 < u2) return -1; 308 if (u1 > u2) return 1; 309 } 310 if (c1 == 0) return 0; 311 } 312 } 313 314 /* 315 int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) 316 { 317 for (; num != 0; num--) 318 { 319 wchar_t c1 = *s1++; 320 wchar_t c2 = *s2++; 321 if (c1 != c2) 322 { 323 wchar_t u1 = MyCharUpper(c1); 324 wchar_t u2 = MyCharUpper(c2); 325 if (u1 < u2) return -1; 326 if (u1 > u2) return 1; 327 } 328 if (c1 == 0) return 0; 329 } 330 return 0; 331 } 332 */ 333 334 // ---------- AString ---------- 335 336 void AString::InsertSpace(unsigned &index, unsigned size) 337 { 338 Grow(size); 339 MoveItems(index + size, index); 340 } 341 342 #define k_Alloc_Len_Limit 0x40000000 343 344 void AString::ReAlloc(unsigned newLimit) 345 { 346 if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220; 347 // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1); 348 char *newBuf = MY_STRING_NEW(char, newLimit + 1); 349 memcpy(newBuf, _chars, (size_t)(_len + 1)); \ 350 MY_STRING_DELETE(_chars); 351 _chars = newBuf; 352 _limit = newLimit; 353 } 354 355 void AString::ReAlloc2(unsigned newLimit) 356 { 357 if (newLimit >= k_Alloc_Len_Limit) throw 20130220; 358 // MY_STRING_REALLOC(_chars, char, newLimit + 1, 0); 359 char *newBuf = MY_STRING_NEW(char, newLimit + 1); 360 newBuf[0] = 0; 361 MY_STRING_DELETE(_chars); 362 _chars = newBuf; 363 _limit = newLimit; 364 } 365 366 void AString::SetStartLen(unsigned len) 367 { 368 _chars = 0; 369 _chars = MY_STRING_NEW(char, len + 1); 370 _len = len; 371 _limit = len; 372 } 373 374 void AString::Grow_1() 375 { 376 unsigned next = _len; 377 next += next / 2; 378 next += 16; 379 next &= ~(unsigned)15; 380 ReAlloc(next - 1); 381 } 382 383 void AString::Grow(unsigned n) 384 { 385 unsigned freeSize = _limit - _len; 386 if (n <= freeSize) 387 return; 388 389 unsigned next = _len + n; 390 next += next / 2; 391 next += 16; 392 next &= ~(unsigned)15; 393 ReAlloc(next - 1); 394 } 395 396 /* 397 AString::AString(unsigned num, const char *s) 398 { 399 unsigned len = MyStringLen(s); 400 if (num > len) 401 num = len; 402 SetStartLen(num); 403 memcpy(_chars, s, num); 404 _chars[num] = 0; 405 } 406 */ 407 408 AString::AString(unsigned num, const AString &s) 409 { 410 if (num > s._len) 411 num = s._len; 412 SetStartLen(num); 413 memcpy(_chars, s._chars, num); 414 _chars[num] = 0; 415 } 416 417 AString::AString(const AString &s, char c) 418 { 419 SetStartLen(s.Len() + 1); 420 char *chars = _chars; 421 unsigned len = s.Len(); 422 memcpy(chars, s, len); 423 chars[len] = c; 424 chars[len + 1] = 0; 425 } 426 427 AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) 428 { 429 SetStartLen(num1 + num2); 430 char *chars = _chars; 431 memcpy(chars, s1, num1); 432 memcpy(chars + num1, s2, num2 + 1); 433 } 434 435 AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); } 436 AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); } 437 AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); } 438 439 AString::AString() 440 { 441 _chars = 0; 442 _chars = MY_STRING_NEW(char, 4); 443 _len = 0; 444 _limit = 4 - 1; 445 _chars[0] = 0; 446 } 447 448 AString::AString(char c) 449 { 450 SetStartLen(1); 451 _chars[0] = c; 452 _chars[1] = 0; 453 } 454 455 AString::AString(const char *s) 456 { 457 SetStartLen(MyStringLen(s)); 458 MyStringCopy(_chars, s); 459 } 460 461 AString::AString(const AString &s) 462 { 463 SetStartLen(s._len); 464 MyStringCopy(_chars, s._chars); 465 } 466 467 AString &AString::operator=(char c) 468 { 469 if (1 > _limit) 470 { 471 char *newBuf = MY_STRING_NEW(char, 1 + 1); 472 MY_STRING_DELETE(_chars); 473 _chars = newBuf; 474 _limit = 1; 475 } 476 _len = 1; 477 _chars[0] = c; 478 _chars[1] = 0; 479 return *this; 480 } 481 482 AString &AString::operator=(const char *s) 483 { 484 unsigned len = MyStringLen(s); 485 if (len > _limit) 486 { 487 char *newBuf = MY_STRING_NEW(char, len + 1); 488 MY_STRING_DELETE(_chars); 489 _chars = newBuf; 490 _limit = len; 491 } 492 _len = len; 493 MyStringCopy(_chars, s); 494 return *this; 495 } 496 497 AString &AString::operator=(const AString &s) 498 { 499 if (&s == this) 500 return *this; 501 unsigned len = s._len; 502 if (len > _limit) 503 { 504 char *newBuf = MY_STRING_NEW(char, len + 1); 505 MY_STRING_DELETE(_chars); 506 _chars = newBuf; 507 _limit = len; 508 } 509 _len = len; 510 MyStringCopy(_chars, s._chars); 511 return *this; 512 } 513 514 void AString::SetFromWStr_if_Ascii(const wchar_t *s) 515 { 516 unsigned len = 0; 517 { 518 for (;; len++) 519 { 520 wchar_t c = s[len]; 521 if (c == 0) 522 break; 523 if (c >= 0x80) 524 return; 525 } 526 } 527 if (len > _limit) 528 { 529 char *newBuf = MY_STRING_NEW(char, len + 1); 530 MY_STRING_DELETE(_chars); 531 _chars = newBuf; 532 _limit = len; 533 } 534 _len = len; 535 char *dest = _chars; 536 unsigned i; 537 for (i = 0; i < len; i++) 538 dest[i] = (char)s[i]; 539 dest[i] = 0; 540 } 541 542 /* 543 void AString::SetFromBstr_if_Ascii(BSTR s) 544 { 545 unsigned len = ::SysStringLen(s); 546 { 547 for (unsigned i = 0; i < len; i++) 548 if (s[i] <= 0 || s[i] >= 0x80) 549 return; 550 } 551 if (len > _limit) 552 { 553 char *newBuf = MY_STRING_NEW(char, len + 1); 554 MY_STRING_DELETE(_chars); 555 _chars = newBuf; 556 _limit = len; 557 } 558 _len = len; 559 char *dest = _chars; 560 unsigned i; 561 for (i = 0; i < len; i++) 562 dest[i] = (char)s[i]; 563 dest[i] = 0; 564 } 565 */ 566 567 void AString::Add_Space() { operator+=(' '); } 568 void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } 569 void AString::Add_LF() { operator+=('\n'); } 570 571 AString &AString::operator+=(const char *s) 572 { 573 unsigned len = MyStringLen(s); 574 Grow(len); 575 MyStringCopy(_chars + _len, s); 576 _len += len; 577 return *this; 578 } 579 580 AString &AString::operator+=(const AString &s) 581 { 582 Grow(s._len); 583 MyStringCopy(_chars + _len, s._chars); 584 _len += s._len; 585 return *this; 586 } 587 588 void AString::SetFrom(const char *s, unsigned len) // no check 589 { 590 if (len > _limit) 591 { 592 char *newBuf = MY_STRING_NEW(char, len + 1); 593 MY_STRING_DELETE(_chars); 594 _chars = newBuf; 595 _limit = len; 596 } 597 if (len != 0) 598 memcpy(_chars, s, len); 599 _chars[len] = 0; 600 _len = len; 601 } 602 603 void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check 604 { 605 unsigned i; 606 for (i = 0; i < len; i++) 607 if (s[i] == 0) 608 break; 609 SetFrom(s, i); 610 } 611 612 int AString::Find(const char *s, unsigned startIndex) const throw() 613 { 614 const char *fs = strstr(_chars + startIndex, s); 615 if (!fs) 616 return -1; 617 return (int)(fs - _chars); 618 619 /* 620 if (s[0] == 0) 621 return startIndex; 622 unsigned len = MyStringLen(s); 623 const char *p = _chars + startIndex; 624 for (;; p++) 625 { 626 const char c = *p; 627 if (c != s[0]) 628 { 629 if (c == 0) 630 return -1; 631 continue; 632 } 633 unsigned i; 634 for (i = 1; i < len; i++) 635 if (p[i] != s[i]) 636 break; 637 if (i == len) 638 return (int)(p - _chars); 639 } 640 */ 641 } 642 643 int AString::ReverseFind(char c) const throw() 644 { 645 if (_len == 0) 646 return -1; 647 const char *p = _chars + _len - 1; 648 for (;;) 649 { 650 if (*p == c) 651 return (int)(p - _chars); 652 if (p == _chars) 653 return -1; 654 p--; // p = GetPrevCharPointer(_chars, p); 655 } 656 } 657 658 int AString::ReverseFind_PathSepar() const throw() 659 { 660 if (_len == 0) 661 return -1; 662 const char *p = _chars + _len - 1; 663 for (;;) 664 { 665 char c = *p; 666 if (IS_PATH_SEPAR(c)) 667 return (int)(p - _chars); 668 if (p == _chars) 669 return -1; 670 p--; 671 } 672 } 673 674 void AString::TrimLeft() throw() 675 { 676 const char *p = _chars; 677 for (;; p++) 678 { 679 char c = *p; 680 if (c != ' ' && c != '\n' && c != '\t') 681 break; 682 } 683 unsigned pos = (unsigned)(p - _chars); 684 if (pos != 0) 685 { 686 MoveItems(0, pos); 687 _len -= pos; 688 } 689 } 690 691 void AString::TrimRight() throw() 692 { 693 const char *p = _chars; 694 unsigned i; 695 for (i = _len; i != 0; i--) 696 { 697 char c = p[i - 1]; 698 if (c != ' ' && c != '\n' && c != '\t') 699 break; 700 } 701 if (i != _len) 702 { 703 _chars[i] = 0; 704 _len = i; 705 } 706 } 707 708 void AString::InsertAtFront(char c) 709 { 710 if (_limit == _len) 711 Grow_1(); 712 MoveItems(1, 0); 713 _chars[0] = c; 714 _len++; 715 } 716 717 /* 718 void AString::Insert(unsigned index, char c) 719 { 720 InsertSpace(index, 1); 721 _chars[index] = c; 722 _len++; 723 } 724 */ 725 726 void AString::Insert(unsigned index, const char *s) 727 { 728 unsigned num = MyStringLen(s); 729 if (num != 0) 730 { 731 InsertSpace(index, num); 732 memcpy(_chars + index, s, num); 733 _len += num; 734 } 735 } 736 737 void AString::Insert(unsigned index, const AString &s) 738 { 739 unsigned num = s.Len(); 740 if (num != 0) 741 { 742 InsertSpace(index, num); 743 memcpy(_chars + index, s, num); 744 _len += num; 745 } 746 } 747 748 void AString::RemoveChar(char ch) throw() 749 { 750 char *src = _chars; 751 752 for (;;) 753 { 754 char c = *src++; 755 if (c == 0) 756 return; 757 if (c == ch) 758 break; 759 } 760 761 char *dest = src - 1; 762 763 for (;;) 764 { 765 char c = *src++; 766 if (c == 0) 767 break; 768 if (c != ch) 769 *dest++ = c; 770 } 771 772 *dest = 0; 773 _len = (unsigned)(dest - _chars); 774 } 775 776 // !!!!!!!!!!!!!!! test it if newChar = '\0' 777 void AString::Replace(char oldChar, char newChar) throw() 778 { 779 if (oldChar == newChar) 780 return; // 0; 781 // unsigned number = 0; 782 int pos = 0; 783 while ((unsigned)pos < _len) 784 { 785 pos = Find(oldChar, pos); 786 if (pos < 0) 787 break; 788 _chars[(unsigned)pos] = newChar; 789 pos++; 790 // number++; 791 } 792 return; // number; 793 } 794 795 void AString::Replace(const AString &oldString, const AString &newString) 796 { 797 if (oldString.IsEmpty()) 798 return; // 0; 799 if (oldString == newString) 800 return; // 0; 801 unsigned oldLen = oldString.Len(); 802 unsigned newLen = newString.Len(); 803 // unsigned number = 0; 804 int pos = 0; 805 while ((unsigned)pos < _len) 806 { 807 pos = Find(oldString, pos); 808 if (pos < 0) 809 break; 810 Delete(pos, oldLen); 811 Insert(pos, newString); 812 pos += newLen; 813 // number++; 814 } 815 // return number; 816 } 817 818 void AString::Delete(unsigned index) throw() 819 { 820 MoveItems(index, index + 1); 821 _len--; 822 } 823 824 void AString::Delete(unsigned index, unsigned count) throw() 825 { 826 if (index + count > _len) 827 count = _len - index; 828 if (count > 0) 829 { 830 MoveItems(index, index + count); 831 _len -= count; 832 } 833 } 834 835 void AString::DeleteFrontal(unsigned num) throw() 836 { 837 if (num != 0) 838 { 839 MoveItems(0, num); 840 _len -= num; 841 } 842 } 843 844 /* 845 AString operator+(const AString &s1, const AString &s2) 846 { 847 AString result(s1); 848 result += s2; 849 return result; 850 } 851 852 AString operator+(const AString &s, const char *chars) 853 { 854 AString result(s); 855 result += chars; 856 return result; 857 } 858 859 AString operator+(const char *chars, const AString &s) 860 { 861 AString result(chars); 862 result += s; 863 return result; 864 } 865 866 AString operator+(const AString &s, char c) 867 { 868 AString result(s); 869 result += c; 870 return result; 871 } 872 */ 873 874 /* 875 AString operator+(char c, const AString &s) 876 { 877 AString result(c); 878 result += s; 879 return result; 880 } 881 */ 882 883 884 885 886 // ---------- UString ---------- 887 888 void UString::InsertSpace(unsigned index, unsigned size) 889 { 890 Grow(size); 891 MoveItems(index + size, index); 892 } 893 894 void UString::ReAlloc(unsigned newLimit) 895 { 896 if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221; 897 // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1); 898 wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1); 899 wmemcpy(newBuf, _chars, _len + 1); 900 MY_STRING_DELETE(_chars); 901 _chars = newBuf; 902 _limit = newLimit; 903 } 904 905 void UString::ReAlloc2(unsigned newLimit) 906 { 907 if (newLimit >= k_Alloc_Len_Limit) throw 20130221; 908 // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); 909 wchar_t *newBuf = MY_STRING_NEW(wchar_t, newLimit + 1); 910 newBuf[0] = 0; 911 MY_STRING_DELETE(_chars); 912 _chars = newBuf; 913 _limit = newLimit; 914 } 915 916 void UString::SetStartLen(unsigned len) 917 { 918 _chars = 0; 919 _chars = MY_STRING_NEW(wchar_t, len + 1); 920 _len = len; 921 _limit = len; 922 } 923 924 void UString::Grow_1() 925 { 926 unsigned next = _len; 927 next += next / 2; 928 next += 16; 929 next &= ~(unsigned)15; 930 ReAlloc(next - 1); 931 } 932 933 void UString::Grow(unsigned n) 934 { 935 unsigned freeSize = _limit - _len; 936 if (n <= freeSize) 937 return; 938 939 unsigned next = _len + n; 940 next += next / 2; 941 next += 16; 942 next &= ~(unsigned)15; 943 ReAlloc(next - 1); 944 } 945 946 947 UString::UString(unsigned num, const wchar_t *s) 948 { 949 unsigned len = MyStringLen(s); 950 if (num > len) 951 num = len; 952 SetStartLen(num); 953 wmemcpy(_chars, s, num); 954 _chars[num] = 0; 955 } 956 957 958 UString::UString(unsigned num, const UString &s) 959 { 960 if (num > s._len) 961 num = s._len; 962 SetStartLen(num); 963 wmemcpy(_chars, s._chars, num); 964 _chars[num] = 0; 965 } 966 967 UString::UString(const UString &s, wchar_t c) 968 { 969 SetStartLen(s.Len() + 1); 970 wchar_t *chars = _chars; 971 unsigned len = s.Len(); 972 wmemcpy(chars, s, len); 973 chars[len] = c; 974 chars[len + 1] = 0; 975 } 976 977 UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) 978 { 979 SetStartLen(num1 + num2); 980 wchar_t *chars = _chars; 981 wmemcpy(chars, s1, num1); 982 wmemcpy(chars + num1, s2, num2 + 1); 983 } 984 985 UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); } 986 UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); } 987 UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); } 988 989 UString::UString() 990 { 991 _chars = 0; 992 _chars = MY_STRING_NEW(wchar_t, 4); 993 _len = 0; 994 _limit = 4 - 1; 995 _chars[0] = 0; 996 } 997 998 UString::UString(wchar_t c) 999 { 1000 SetStartLen(1); 1001 _chars[0] = c; 1002 _chars[1] = 0; 1003 } 1004 1005 UString::UString(const wchar_t *s) 1006 { 1007 unsigned len = MyStringLen(s); 1008 SetStartLen(len); 1009 wmemcpy(_chars, s, len + 1); 1010 } 1011 1012 UString::UString(const UString &s) 1013 { 1014 SetStartLen(s._len); 1015 wmemcpy(_chars, s._chars, s._len + 1); 1016 } 1017 1018 UString &UString::operator=(wchar_t c) 1019 { 1020 if (1 > _limit) 1021 { 1022 wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); 1023 MY_STRING_DELETE(_chars); 1024 _chars = newBuf; 1025 _limit = 1; 1026 } 1027 _len = 1; 1028 _chars[0] = c; 1029 _chars[1] = 0; 1030 return *this; 1031 } 1032 1033 UString &UString::operator=(const wchar_t *s) 1034 { 1035 unsigned len = MyStringLen(s); 1036 if (len > _limit) 1037 { 1038 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1039 MY_STRING_DELETE(_chars); 1040 _chars = newBuf; 1041 _limit = len; 1042 } 1043 _len = len; 1044 wmemcpy(_chars, s, len + 1); 1045 return *this; 1046 } 1047 1048 UString &UString::operator=(const UString &s) 1049 { 1050 if (&s == this) 1051 return *this; 1052 unsigned len = s._len; 1053 if (len > _limit) 1054 { 1055 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1056 MY_STRING_DELETE(_chars); 1057 _chars = newBuf; 1058 _limit = len; 1059 } 1060 _len = len; 1061 wmemcpy(_chars, s._chars, len + 1); 1062 return *this; 1063 } 1064 1065 void UString::SetFromBstr(BSTR s) 1066 { 1067 unsigned len = ::SysStringLen(s); 1068 if (len > _limit) 1069 { 1070 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1071 MY_STRING_DELETE(_chars); 1072 _chars = newBuf; 1073 _limit = len; 1074 } 1075 _len = len; 1076 // if (s) 1077 wmemcpy(_chars, s, len + 1); 1078 } 1079 1080 void UString::Add_Space() { operator+=(L' '); } 1081 void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } 1082 1083 void UString::Add_LF() 1084 { 1085 if (_limit == _len) 1086 Grow_1(); 1087 unsigned len = _len; 1088 wchar_t *chars = _chars; 1089 chars[len++] = L'\n'; 1090 chars[len] = 0; 1091 _len = len; 1092 } 1093 1094 UString &UString::operator+=(const wchar_t *s) 1095 { 1096 unsigned len = MyStringLen(s); 1097 Grow(len); 1098 wmemcpy(_chars + _len, s, len + 1); 1099 _len += len; 1100 return *this; 1101 } 1102 1103 UString &UString::operator+=(const UString &s) 1104 { 1105 Grow(s._len); 1106 wmemcpy(_chars + _len, s._chars, s._len + 1); 1107 _len += s._len; 1108 return *this; 1109 } 1110 1111 void UString::SetFrom(const wchar_t *s, unsigned len) // no check 1112 { 1113 if (len > _limit) 1114 { 1115 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1116 MY_STRING_DELETE(_chars); 1117 _chars = newBuf; 1118 _limit = len; 1119 } 1120 if (len != 0) 1121 wmemcpy(_chars, s, len); 1122 _chars[len] = 0; 1123 _len = len; 1124 } 1125 1126 void UString::SetFromAscii(const char *s) 1127 { 1128 unsigned len = MyStringLen(s); 1129 if (len > _limit) 1130 { 1131 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1132 MY_STRING_DELETE(_chars); 1133 _chars = newBuf; 1134 _limit = len; 1135 } 1136 wchar_t *chars = _chars; 1137 for (unsigned i = 0; i < len; i++) 1138 chars[i] = (unsigned char)s[i]; 1139 chars[len] = 0; 1140 _len = len; 1141 } 1142 1143 void UString::AddAscii(const char *s) 1144 { 1145 unsigned len = MyStringLen(s); 1146 Grow(len); 1147 wchar_t *chars = _chars + _len; 1148 for (unsigned i = 0; i < len; i++) 1149 chars[i] = (unsigned char)s[i]; 1150 chars[len] = 0; 1151 _len += len; 1152 } 1153 1154 1155 1156 int UString::Find(const wchar_t *s, unsigned startIndex) const throw() 1157 { 1158 const wchar_t *fs = wcsstr(_chars + startIndex, s); 1159 if (!fs) 1160 return -1; 1161 return (int)(fs - _chars); 1162 1163 /* 1164 if (s[0] == 0) 1165 return startIndex; 1166 unsigned len = MyStringLen(s); 1167 const wchar_t *p = _chars + startIndex; 1168 for (;; p++) 1169 { 1170 const wchar_t c = *p; 1171 if (c != s[0]) 1172 { 1173 if (c == 0) 1174 return -1; 1175 continue; 1176 } 1177 unsigned i; 1178 for (i = 1; i < len; i++) 1179 if (p[i] != s[i]) 1180 break; 1181 if (i == len) 1182 return (int)(p - _chars); 1183 } 1184 */ 1185 } 1186 1187 int UString::ReverseFind(wchar_t c) const throw() 1188 { 1189 if (_len == 0) 1190 return -1; 1191 const wchar_t *p = _chars + _len - 1; 1192 for (;;) 1193 { 1194 if (*p == c) 1195 return (int)(p - _chars); 1196 if (p == _chars) 1197 return -1; 1198 p--; 1199 } 1200 } 1201 1202 int UString::ReverseFind_PathSepar() const throw() 1203 { 1204 if (_len == 0) 1205 return -1; 1206 const wchar_t *p = _chars + _len - 1; 1207 for (;;) 1208 { 1209 wchar_t c = *p; 1210 if (IS_PATH_SEPAR(c)) 1211 return (int)(p - _chars); 1212 if (p == _chars) 1213 return -1; 1214 p--; 1215 } 1216 } 1217 1218 void UString::TrimLeft() throw() 1219 { 1220 const wchar_t *p = _chars; 1221 for (;; p++) 1222 { 1223 wchar_t c = *p; 1224 if (c != ' ' && c != '\n' && c != '\t') 1225 break; 1226 } 1227 unsigned pos = (unsigned)(p - _chars); 1228 if (pos != 0) 1229 { 1230 MoveItems(0, pos); 1231 _len -= pos; 1232 } 1233 } 1234 1235 void UString::TrimRight() throw() 1236 { 1237 const wchar_t *p = _chars; 1238 unsigned i; 1239 for (i = _len; i != 0; i--) 1240 { 1241 wchar_t c = p[i - 1]; 1242 if (c != ' ' && c != '\n' && c != '\t') 1243 break; 1244 } 1245 if (i != _len) 1246 { 1247 _chars[i] = 0; 1248 _len = i; 1249 } 1250 } 1251 1252 void UString::InsertAtFront(wchar_t c) 1253 { 1254 if (_limit == _len) 1255 Grow_1(); 1256 MoveItems(1, 0); 1257 _chars[0] = c; 1258 _len++; 1259 } 1260 1261 /* 1262 void UString::Insert(unsigned index, wchar_t c) 1263 { 1264 InsertSpace(index, 1); 1265 _chars[index] = c; 1266 _len++; 1267 } 1268 */ 1269 1270 void UString::Insert(unsigned index, const wchar_t *s) 1271 { 1272 unsigned num = MyStringLen(s); 1273 if (num != 0) 1274 { 1275 InsertSpace(index, num); 1276 wmemcpy(_chars + index, s, num); 1277 _len += num; 1278 } 1279 } 1280 1281 void UString::Insert(unsigned index, const UString &s) 1282 { 1283 unsigned num = s.Len(); 1284 if (num != 0) 1285 { 1286 InsertSpace(index, num); 1287 wmemcpy(_chars + index, s, num); 1288 _len += num; 1289 } 1290 } 1291 1292 void UString::RemoveChar(wchar_t ch) throw() 1293 { 1294 wchar_t *src = _chars; 1295 1296 for (;;) 1297 { 1298 wchar_t c = *src++; 1299 if (c == 0) 1300 return; 1301 if (c == ch) 1302 break; 1303 } 1304 1305 wchar_t *dest = src - 1; 1306 1307 for (;;) 1308 { 1309 wchar_t c = *src++; 1310 if (c == 0) 1311 break; 1312 if (c != ch) 1313 *dest++ = c; 1314 } 1315 1316 *dest = 0; 1317 _len = (unsigned)(dest - _chars); 1318 } 1319 1320 // !!!!!!!!!!!!!!! test it if newChar = '\0' 1321 void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() 1322 { 1323 if (oldChar == newChar) 1324 return; // 0; 1325 // unsigned number = 0; 1326 int pos = 0; 1327 while ((unsigned)pos < _len) 1328 { 1329 pos = Find(oldChar, pos); 1330 if (pos < 0) 1331 break; 1332 _chars[(unsigned)pos] = newChar; 1333 pos++; 1334 // number++; 1335 } 1336 return; // number; 1337 } 1338 1339 void UString::Replace(const UString &oldString, const UString &newString) 1340 { 1341 if (oldString.IsEmpty()) 1342 return; // 0; 1343 if (oldString == newString) 1344 return; // 0; 1345 unsigned oldLen = oldString.Len(); 1346 unsigned newLen = newString.Len(); 1347 // unsigned number = 0; 1348 int pos = 0; 1349 while ((unsigned)pos < _len) 1350 { 1351 pos = Find(oldString, pos); 1352 if (pos < 0) 1353 break; 1354 Delete(pos, oldLen); 1355 Insert(pos, newString); 1356 pos += newLen; 1357 // number++; 1358 } 1359 // return number; 1360 } 1361 1362 void UString::Delete(unsigned index) throw() 1363 { 1364 MoveItems(index, index + 1); 1365 _len--; 1366 } 1367 1368 void UString::Delete(unsigned index, unsigned count) throw() 1369 { 1370 if (index + count > _len) 1371 count = _len - index; 1372 if (count > 0) 1373 { 1374 MoveItems(index, index + count); 1375 _len -= count; 1376 } 1377 } 1378 1379 void UString::DeleteFrontal(unsigned num) throw() 1380 { 1381 if (num != 0) 1382 { 1383 MoveItems(0, num); 1384 _len -= num; 1385 } 1386 } 1387 1388 1389 // ---------- UString2 ---------- 1390 1391 void UString2::ReAlloc2(unsigned newLimit) 1392 { 1393 if (newLimit >= k_Alloc_Len_Limit) throw 20130221; 1394 // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); 1395 _chars = MY_STRING_NEW(wchar_t, newLimit + 1); 1396 } 1397 1398 void UString2::SetStartLen(unsigned len) 1399 { 1400 _chars = 0; 1401 _chars = MY_STRING_NEW(wchar_t, len + 1); 1402 _len = len; 1403 } 1404 1405 1406 /* 1407 UString2::UString2(wchar_t c) 1408 { 1409 SetStartLen(1); 1410 _chars[0] = c; 1411 _chars[1] = 0; 1412 } 1413 */ 1414 1415 UString2::UString2(const wchar_t *s) 1416 { 1417 unsigned len = MyStringLen(s); 1418 SetStartLen(len); 1419 wmemcpy(_chars, s, len + 1); 1420 } 1421 1422 UString2::UString2(const UString2 &s): _chars(NULL), _len(0) 1423 { 1424 if (s._chars) 1425 { 1426 SetStartLen(s._len); 1427 wmemcpy(_chars, s._chars, s._len + 1); 1428 } 1429 } 1430 1431 /* 1432 UString2 &UString2::operator=(wchar_t c) 1433 { 1434 if (1 > _len) 1435 { 1436 wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); 1437 if (_chars) 1438 MY_STRING_DELETE(_chars); 1439 _chars = newBuf; 1440 } 1441 _len = 1; 1442 _chars[0] = c; 1443 _chars[1] = 0; 1444 return *this; 1445 } 1446 */ 1447 1448 UString2 &UString2::operator=(const wchar_t *s) 1449 { 1450 unsigned len = MyStringLen(s); 1451 if (len > _len) 1452 { 1453 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1454 if (_chars) 1455 MY_STRING_DELETE(_chars); 1456 _chars = newBuf; 1457 } 1458 _len = len; 1459 MyStringCopy(_chars, s); 1460 return *this; 1461 } 1462 1463 void UString2::SetFromAscii(const char *s) 1464 { 1465 unsigned len = MyStringLen(s); 1466 if (len > _len) 1467 { 1468 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1469 if (_chars) 1470 MY_STRING_DELETE(_chars); 1471 _chars = newBuf; 1472 } 1473 wchar_t *chars = _chars; 1474 for (unsigned i = 0; i < len; i++) 1475 chars[i] = (unsigned char)s[i]; 1476 chars[len] = 0; 1477 _len = len; 1478 } 1479 1480 UString2 &UString2::operator=(const UString2 &s) 1481 { 1482 if (&s == this) 1483 return *this; 1484 unsigned len = s._len; 1485 if (len > _len) 1486 { 1487 wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); 1488 if (_chars) 1489 MY_STRING_DELETE(_chars); 1490 _chars = newBuf; 1491 } 1492 _len = len; 1493 MyStringCopy(_chars, s._chars); 1494 return *this; 1495 } 1496 1497 bool operator==(const UString2 &s1, const UString2 &s2) 1498 { 1499 return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0); 1500 } 1501 1502 bool operator==(const UString2 &s1, const wchar_t *s2) 1503 { 1504 if (s1.IsEmpty()) 1505 return (*s2 == 0); 1506 return wcscmp(s1.GetRawPtr(), s2) == 0; 1507 } 1508 1509 bool operator==(const wchar_t *s1, const UString2 &s2) 1510 { 1511 if (s2.IsEmpty()) 1512 return (*s1 == 0); 1513 return wcscmp(s1, s2.GetRawPtr()) == 0; 1514 } 1515 1516 1517 1518 // ---------------------------------------- 1519 1520 /* 1521 int MyStringCompareNoCase(const char *s1, const char *s2) 1522 { 1523 return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); 1524 } 1525 */ 1526 1527 static inline UINT GetCurrentCodePage() 1528 { 1529 #if defined(UNDER_CE) || !defined(_WIN32) 1530 return CP_ACP; 1531 #else 1532 return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; 1533 #endif 1534 } 1535 1536 #ifdef USE_UNICODE_FSTRING 1537 1538 #ifndef _UNICODE 1539 1540 AString fs2fas(CFSTR s) 1541 { 1542 return UnicodeStringToMultiByte(s, GetCurrentCodePage()); 1543 } 1544 1545 FString fas2fs(const AString &s) 1546 { 1547 return MultiByteToUnicodeString(s, GetCurrentCodePage()); 1548 } 1549 1550 #endif 1551 1552 #else 1553 1554 UString fs2us(const FString &s) 1555 { 1556 return MultiByteToUnicodeString((AString)s, GetCurrentCodePage()); 1557 } 1558 1559 FString us2fs(const wchar_t *s) 1560 { 1561 return UnicodeStringToMultiByte(s, GetCurrentCodePage()); 1562 } 1563 1564 #endif 1565