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