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/* 23inline 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 37int 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 49int 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/* 61void 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 72void 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 84void 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 95void 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 121wchar_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/* 138wchar_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/* 156wchar_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/* 171wchar_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 189bool IsString1PrefixedByString2(const char *s1, const char *s2) throw() 190{ 191 for (;;) 192 { 193 const unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true; 194 const unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false; 195 } 196} 197 198bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() 199{ 200 for (;;) 201 { 202 const wchar_t c1 = *s1++; 203 const 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 211bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() 212{ 213 const char *s1 = _chars; 214 for (;;) 215 { 216 const char c2 = *s++; 217 if (c2 == 0) 218 return true; 219 const char c1 = *s1++; 220 if (MyCharLower_Ascii(c1) != 221 MyCharLower_Ascii(c2)) 222 return false; 223 } 224} 225 226bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() 227{ 228 const wchar_t *s1 = _chars; 229 for (;;) 230 { 231 const char c2 = *s++; 232 if (c2 == 0) 233 return true; 234 const wchar_t c1 = *s1++; 235 if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) 236 return false; 237 } 238} 239 240bool StringsAreEqual_Ascii(const char *u, const char *a) throw() 241{ 242 for (;;) 243 { 244 const char c = *a; 245 if (c != *u) 246 return false; 247 if (c == 0) 248 return true; 249 a++; 250 u++; 251 } 252} 253 254bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() 255{ 256 for (;;) 257 { 258 const unsigned char c = (unsigned char)*a; 259 if (c != *u) 260 return false; 261 if (c == 0) 262 return true; 263 a++; 264 u++; 265 } 266} 267 268bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() 269{ 270 for (;;) 271 { 272 const char c1 = *s1++; 273 const char c2 = *s2++; 274 if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) 275 return false; 276 if (c1 == 0) 277 return true; 278 } 279} 280 281bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() 282{ 283 for (;;) 284 { 285 const wchar_t c1 = *s1++; 286 const wchar_t c2 = *s2++; 287 if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) 288 return false; 289 if (c1 == 0) 290 return true; 291 } 292} 293 294bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() 295{ 296 for (;;) 297 { 298 const wchar_t c1 = *s1++; 299 const char c2 = *s2++; 300 if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))) 301 return false; 302 if (c1 == 0) 303 return true; 304 } 305} 306 307bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw() 308{ 309 for (;;) 310 { 311 const wchar_t c2 = *s2++; if (c2 == 0) return true; 312 const wchar_t c1 = *s1++; if (c1 != c2) return false; 313 } 314} 315 316bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw() 317{ 318 for (;;) 319 { 320 const unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true; 321 const wchar_t c1 = *s1++; if (c1 != c2) return false; 322 } 323} 324 325bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw() 326{ 327 for (;;) 328 { 329 const char c2 = *s2++; if (c2 == 0) return true; 330 const char c1 = *s1++; 331 if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) 332 return false; 333 } 334} 335 336bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw() 337{ 338 for (;;) 339 { 340 const char c2 = *s2++; if (c2 == 0) return true; 341 const wchar_t c1 = *s1++; 342 if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) 343 return false; 344 } 345} 346 347bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw() 348{ 349 for (;;) 350 { 351 const wchar_t c2 = *s2++; if (c2 == 0) return true; 352 const wchar_t c1 = *s1++; 353 if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) 354 return false; 355 } 356} 357 358// NTFS order: uses upper case 359int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() 360{ 361 for (;;) 362 { 363 const wchar_t c1 = *s1++; 364 const wchar_t c2 = *s2++; 365 if (c1 != c2) 366 { 367 const wchar_t u1 = MyCharUpper(c1); 368 const wchar_t u2 = MyCharUpper(c2); 369 if (u1 < u2) return -1; 370 if (u1 > u2) return 1; 371 } 372 if (c1 == 0) return 0; 373 } 374} 375 376/* 377int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) 378{ 379 for (; num != 0; num--) 380 { 381 wchar_t c1 = *s1++; 382 wchar_t c2 = *s2++; 383 if (c1 != c2) 384 { 385 wchar_t u1 = MyCharUpper(c1); 386 wchar_t u2 = MyCharUpper(c2); 387 if (u1 < u2) return -1; 388 if (u1 > u2) return 1; 389 } 390 if (c1 == 0) return 0; 391 } 392 return 0; 393} 394*/ 395 396// ---------- AString ---------- 397 398void AString::InsertSpace(unsigned &index, unsigned size) 399{ 400 Grow(size); 401 MoveItems(index + size, index); 402} 403 404#define k_Alloc_Len_Limit (0x40000000 - 2) 405 406void AString::ReAlloc(unsigned newLimit) 407{ 408 // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, (size_t)_len + 1); 409 char *newBuf = MY_STRING_NEW_char((size_t)newLimit + 1); 410 memcpy(newBuf, _chars, (size_t)_len + 1); 411 MY_STRING_DELETE(_chars) 412 _chars = newBuf; 413 _limit = newLimit; 414} 415 416void AString::ReAlloc2(unsigned newLimit) 417{ 418 if (newLimit > k_Alloc_Len_Limit) throw 20130220; 419 // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, 0); 420 char *newBuf = MY_STRING_NEW_char((size_t)newLimit + 1); 421 newBuf[0] = 0; 422 MY_STRING_DELETE(_chars) 423 _chars = newBuf; 424 _limit = newLimit; 425 _len = 0; 426} 427 428void AString::SetStartLen(unsigned len) 429{ 430 _chars = NULL; 431 _chars = MY_STRING_NEW_char((size_t)len + 1); 432 _len = len; 433 _limit = len; 434} 435 436void AString::Grow_1() 437{ 438 unsigned next = _len; 439 next += next / 2; 440 next += 16; 441 next &= ~(unsigned)15; 442 next--; 443 if (next < _len || next > k_Alloc_Len_Limit) 444 next = k_Alloc_Len_Limit; 445 if (next <= _len) 446 throw 20130220; 447 ReAlloc(next); 448 // Grow(1); 449} 450 451void AString::Grow(unsigned n) 452{ 453 const unsigned freeSize = _limit - _len; 454 if (n <= freeSize) 455 return; 456 unsigned next = _len + n; 457 next += next / 2; 458 next += 16; 459 next &= ~(unsigned)15; 460 next--; 461 if (next < _len || next > k_Alloc_Len_Limit) 462 next = k_Alloc_Len_Limit; 463 if (next <= _len || next - _len < n) 464 throw 20130220; 465 ReAlloc(next); 466} 467 468AString::AString(unsigned num, const char *s) 469{ 470 unsigned len = MyStringLen(s); 471 if (num > len) 472 num = len; 473 SetStartLen(num); 474 memcpy(_chars, s, num); 475 _chars[num] = 0; 476} 477 478AString::AString(unsigned num, const AString &s) 479{ 480 if (num > s._len) 481 num = s._len; 482 SetStartLen(num); 483 memcpy(_chars, s._chars, num); 484 _chars[num] = 0; 485} 486 487AString::AString(const AString &s, char c) 488{ 489 SetStartLen(s.Len() + 1); 490 char *chars = _chars; 491 unsigned len = s.Len(); 492 memcpy(chars, s, len); 493 chars[len] = c; 494 chars[(size_t)len + 1] = 0; 495} 496 497AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) 498{ 499 SetStartLen(num1 + num2); 500 char *chars = _chars; 501 memcpy(chars, s1, num1); 502 memcpy(chars + num1, s2, num2 + 1); 503} 504 505AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); } 506AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); } 507AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); } 508 509static const unsigned kStartStringCapacity = 4; 510 511AString::AString() 512{ 513 _chars = NULL; 514 _chars = MY_STRING_NEW_char(kStartStringCapacity); 515 _len = 0; 516 _limit = kStartStringCapacity - 1; 517 _chars[0] = 0; 518} 519 520AString::AString(char c) 521{ 522 SetStartLen(1); 523 char *chars = _chars; 524 chars[0] = c; 525 chars[1] = 0; 526} 527 528AString::AString(const char *s) 529{ 530 SetStartLen(MyStringLen(s)); 531 MyStringCopy(_chars, s); 532} 533 534AString::AString(const AString &s) 535{ 536 SetStartLen(s._len); 537 MyStringCopy(_chars, s._chars); 538} 539 540AString &AString::operator=(char c) 541{ 542 if (1 > _limit) 543 { 544 char *newBuf = MY_STRING_NEW_char(1 + 1); 545 MY_STRING_DELETE(_chars) 546 _chars = newBuf; 547 _limit = 1; 548 } 549 _len = 1; 550 char *chars = _chars; 551 chars[0] = c; 552 chars[1] = 0; 553 return *this; 554} 555 556AString &AString::operator=(const char *s) 557{ 558 unsigned len = MyStringLen(s); 559 if (len > _limit) 560 { 561 char *newBuf = MY_STRING_NEW_char((size_t)len + 1); 562 MY_STRING_DELETE(_chars) 563 _chars = newBuf; 564 _limit = len; 565 } 566 _len = len; 567 MyStringCopy(_chars, s); 568 return *this; 569} 570 571AString &AString::operator=(const AString &s) 572{ 573 if (&s == this) 574 return *this; 575 unsigned len = s._len; 576 if (len > _limit) 577 { 578 char *newBuf = MY_STRING_NEW_char((size_t)len + 1); 579 MY_STRING_DELETE(_chars) 580 _chars = newBuf; 581 _limit = len; 582 } 583 _len = len; 584 MyStringCopy(_chars, s._chars); 585 return *this; 586} 587 588void AString::SetFromWStr_if_Ascii(const wchar_t *s) 589{ 590 unsigned len = 0; 591 { 592 for (;; len++) 593 { 594 wchar_t c = s[len]; 595 if (c == 0) 596 break; 597 if (c >= 0x80) 598 return; 599 } 600 } 601 if (len > _limit) 602 { 603 char *newBuf = MY_STRING_NEW_char((size_t)len + 1); 604 MY_STRING_DELETE(_chars) 605 _chars = newBuf; 606 _limit = len; 607 } 608 _len = len; 609 char *dest = _chars; 610 unsigned i; 611 for (i = 0; i < len; i++) 612 dest[i] = (char)s[i]; 613 dest[i] = 0; 614} 615 616/* 617void AString::SetFromBstr_if_Ascii(BSTR s) 618{ 619 unsigned len = ::SysStringLen(s); 620 { 621 for (unsigned i = 0; i < len; i++) 622 if (s[i] <= 0 || s[i] >= 0x80) 623 return; 624 } 625 if (len > _limit) 626 { 627 char *newBuf = MY_STRING_NEW_char((size_t)len + 1); 628 MY_STRING_DELETE(_chars) 629 _chars = newBuf; 630 _limit = len; 631 } 632 _len = len; 633 char *dest = _chars; 634 unsigned i; 635 for (i = 0; i < len; i++) 636 dest[i] = (char)s[i]; 637 dest[i] = 0; 638} 639*/ 640 641void AString::Add_Space() { operator+=(' '); } 642void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } 643void AString::Add_LF() { operator+=('\n'); } 644void AString::Add_Slash() { operator+=('/'); } 645void AString::Add_Dot() { operator+=('.'); } 646void AString::Add_Minus() { operator+=('-'); } 647 648AString &AString::operator+=(const char *s) 649{ 650 unsigned len = MyStringLen(s); 651 Grow(len); 652 MyStringCopy(_chars + _len, s); 653 _len += len; 654 return *this; 655} 656 657void AString::Add_OptSpaced(const char *s) 658{ 659 Add_Space_if_NotEmpty(); 660 (*this) += s; 661} 662 663AString &AString::operator+=(const AString &s) 664{ 665 Grow(s._len); 666 MyStringCopy(_chars + _len, s._chars); 667 _len += s._len; 668 return *this; 669} 670 671void AString::Add_UInt32(UInt32 v) 672{ 673 Grow(10); 674 _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); 675} 676 677void UString::Add_UInt64(UInt64 v) 678{ 679 Grow(20); 680 _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars); 681} 682 683void AString::AddFrom(const char *s, unsigned len) // no check 684{ 685 if (len != 0) 686 { 687 Grow(len); 688 memcpy(_chars + _len, s, len); 689 len += _len; 690 _chars[len] = 0; 691 _len = len; 692 } 693} 694 695void AString::SetFrom(const char *s, unsigned len) // no check 696{ 697 if (len > _limit) 698 { 699 char *newBuf = MY_STRING_NEW_char((size_t)len + 1); 700 MY_STRING_DELETE(_chars) 701 _chars = newBuf; 702 _limit = len; 703 } 704 if (len != 0) 705 memcpy(_chars, s, len); 706 _chars[len] = 0; 707 _len = len; 708} 709 710void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check 711{ 712 unsigned i; 713 for (i = 0; i < len; i++) 714 if (s[i] == 0) 715 break; 716 SetFrom(s, i); 717} 718 719int AString::Find(const char *s, unsigned startIndex) const throw() 720{ 721 const char *fs = strstr(_chars + startIndex, s); 722 if (!fs) 723 return -1; 724 return (int)(fs - _chars); 725 726 /* 727 if (s[0] == 0) 728 return startIndex; 729 unsigned len = MyStringLen(s); 730 const char *p = _chars + startIndex; 731 for (;; p++) 732 { 733 const char c = *p; 734 if (c != s[0]) 735 { 736 if (c == 0) 737 return -1; 738 continue; 739 } 740 unsigned i; 741 for (i = 1; i < len; i++) 742 if (p[i] != s[i]) 743 break; 744 if (i == len) 745 return (int)(p - _chars); 746 } 747 */ 748} 749 750int AString::ReverseFind(char c) const throw() 751{ 752 if (_len == 0) 753 return -1; 754 const char *p = _chars + _len - 1; 755 for (;;) 756 { 757 if (*p == c) 758 return (int)(p - _chars); 759 if (p == _chars) 760 return -1; 761 p--; // p = GetPrevCharPointer(_chars, p); 762 } 763} 764 765int AString::ReverseFind_PathSepar() const throw() 766{ 767 if (_len == 0) 768 return -1; 769 const char *p = _chars + _len - 1; 770 for (;;) 771 { 772 const char c = *p; 773 if (IS_PATH_SEPAR(c)) 774 return (int)(p - _chars); 775 if (p == _chars) 776 return -1; 777 p--; 778 } 779} 780 781void AString::TrimLeft() throw() 782{ 783 const char *p = _chars; 784 for (;; p++) 785 { 786 char c = *p; 787 if (c != ' ' && c != '\n' && c != '\t') 788 break; 789 } 790 unsigned pos = (unsigned)(p - _chars); 791 if (pos != 0) 792 { 793 MoveItems(0, pos); 794 _len -= pos; 795 } 796} 797 798void AString::TrimRight() throw() 799{ 800 const char *p = _chars; 801 unsigned i; 802 for (i = _len; i != 0; i--) 803 { 804 char c = p[(size_t)i - 1]; 805 if (c != ' ' && c != '\n' && c != '\t') 806 break; 807 } 808 if (i != _len) 809 { 810 _chars[i] = 0; 811 _len = i; 812 } 813} 814 815void AString::InsertAtFront(char c) 816{ 817 if (_limit == _len) 818 Grow_1(); 819 MoveItems(1, 0); 820 _chars[0] = c; 821 _len++; 822} 823 824/* 825void AString::Insert(unsigned index, char c) 826{ 827 InsertSpace(index, 1); 828 _chars[index] = c; 829 _len++; 830} 831*/ 832 833void AString::Insert(unsigned index, const char *s) 834{ 835 unsigned num = MyStringLen(s); 836 if (num != 0) 837 { 838 InsertSpace(index, num); 839 memcpy(_chars + index, s, num); 840 _len += num; 841 } 842} 843 844void AString::Insert(unsigned index, const AString &s) 845{ 846 unsigned num = s.Len(); 847 if (num != 0) 848 { 849 InsertSpace(index, num); 850 memcpy(_chars + index, s, num); 851 _len += num; 852 } 853} 854 855void AString::RemoveChar(char ch) throw() 856{ 857 char *src = _chars; 858 859 for (;;) 860 { 861 char c = *src++; 862 if (c == 0) 863 return; 864 if (c == ch) 865 break; 866 } 867 868 char *dest = src - 1; 869 870 for (;;) 871 { 872 char c = *src++; 873 if (c == 0) 874 break; 875 if (c != ch) 876 *dest++ = c; 877 } 878 879 *dest = 0; 880 _len = (unsigned)(dest - _chars); 881} 882 883// !!!!!!!!!!!!!!! test it if newChar = '\0' 884void AString::Replace(char oldChar, char newChar) throw() 885{ 886 if (oldChar == newChar) 887 return; // 0; 888 // unsigned number = 0; 889 int pos = 0; 890 char *chars = _chars; 891 while ((unsigned)pos < _len) 892 { 893 pos = Find(oldChar, (unsigned)pos); 894 if (pos < 0) 895 break; 896 chars[(unsigned)pos] = newChar; 897 pos++; 898 // number++; 899 } 900 return; // number; 901} 902 903void AString::Replace(const AString &oldString, const AString &newString) 904{ 905 if (oldString.IsEmpty()) 906 return; // 0; 907 if (oldString == newString) 908 return; // 0; 909 unsigned oldLen = oldString.Len(); 910 unsigned newLen = newString.Len(); 911 // unsigned number = 0; 912 int pos = 0; 913 while ((unsigned)pos < _len) 914 { 915 pos = Find(oldString, (unsigned)pos); 916 if (pos < 0) 917 break; 918 Delete((unsigned)pos, oldLen); 919 Insert((unsigned)pos, newString); 920 pos += newLen; 921 // number++; 922 } 923 // return number; 924} 925 926void AString::Delete(unsigned index) throw() 927{ 928 MoveItems(index, index + 1); 929 _len--; 930} 931 932void AString::Delete(unsigned index, unsigned count) throw() 933{ 934 if (index + count > _len) 935 count = _len - index; 936 if (count > 0) 937 { 938 MoveItems(index, index + count); 939 _len -= count; 940 } 941} 942 943void AString::DeleteFrontal(unsigned num) throw() 944{ 945 if (num != 0) 946 { 947 MoveItems(0, num); 948 _len -= num; 949 } 950} 951 952/* 953AString operator+(const AString &s1, const AString &s2) 954{ 955 AString result(s1); 956 result += s2; 957 return result; 958} 959 960AString operator+(const AString &s, const char *chars) 961{ 962 AString result(s); 963 result += chars; 964 return result; 965} 966 967AString operator+(const char *chars, const AString &s) 968{ 969 AString result(chars); 970 result += s; 971 return result; 972} 973 974AString operator+(const AString &s, char c) 975{ 976 AString result(s); 977 result += c; 978 return result; 979} 980*/ 981 982/* 983AString operator+(char c, const AString &s) 984{ 985 AString result(c); 986 result += s; 987 return result; 988} 989*/ 990 991 992 993 994// ---------- UString ---------- 995 996void UString::InsertSpace(unsigned index, unsigned size) 997{ 998 Grow(size); 999 MoveItems(index + size, index); 1000} 1001 1002void UString::ReAlloc(unsigned newLimit) 1003{ 1004 // MY_STRING_REALLOC(_chars, wchar_t, (size_t)newLimit + 1, (size_t)_len + 1); 1005 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); 1006 wmemcpy(newBuf, _chars, _len + 1); 1007 MY_STRING_DELETE(_chars) 1008 _chars = newBuf; 1009 _limit = newLimit; 1010} 1011 1012void UString::ReAlloc2(unsigned newLimit) 1013{ 1014 if (newLimit > k_Alloc_Len_Limit) throw 20130221; 1015 // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); 1016 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); 1017 newBuf[0] = 0; 1018 MY_STRING_DELETE(_chars) 1019 _chars = newBuf; 1020 _limit = newLimit; 1021 _len = 0; 1022} 1023 1024void UString::SetStartLen(unsigned len) 1025{ 1026 _chars = NULL; 1027 _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); 1028 _len = len; 1029 _limit = len; 1030} 1031 1032void UString::Grow_1() 1033{ 1034 unsigned next = _len; 1035 next += next / 2; 1036 next += 16; 1037 next &= ~(unsigned)15; 1038 next--; 1039 if (next < _len || next > k_Alloc_Len_Limit) 1040 next = k_Alloc_Len_Limit; 1041 if (next <= _len) 1042 throw 20130220; 1043 ReAlloc(next); 1044} 1045 1046void UString::Grow(unsigned n) 1047{ 1048 const unsigned freeSize = _limit - _len; 1049 if (n <= freeSize) 1050 return; 1051 unsigned next = _len + n; 1052 next += next / 2; 1053 next += 16; 1054 next &= ~(unsigned)15; 1055 next--; 1056 if (next < _len || next > k_Alloc_Len_Limit) 1057 next = k_Alloc_Len_Limit; 1058 if (next <= _len || next - _len < n) 1059 throw 20130220; 1060 ReAlloc(next - 1); 1061} 1062 1063 1064UString::UString(unsigned num, const wchar_t *s) 1065{ 1066 unsigned len = MyStringLen(s); 1067 if (num > len) 1068 num = len; 1069 SetStartLen(num); 1070 wmemcpy(_chars, s, num); 1071 _chars[num] = 0; 1072} 1073 1074 1075UString::UString(unsigned num, const UString &s) 1076{ 1077 if (num > s._len) 1078 num = s._len; 1079 SetStartLen(num); 1080 wmemcpy(_chars, s._chars, num); 1081 _chars[num] = 0; 1082} 1083 1084UString::UString(const UString &s, wchar_t c) 1085{ 1086 SetStartLen(s.Len() + 1); 1087 wchar_t *chars = _chars; 1088 unsigned len = s.Len(); 1089 wmemcpy(chars, s, len); 1090 chars[len] = c; 1091 chars[(size_t)len + 1] = 0; 1092} 1093 1094UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) 1095{ 1096 SetStartLen(num1 + num2); 1097 wchar_t *chars = _chars; 1098 wmemcpy(chars, s1, num1); 1099 wmemcpy(chars + num1, s2, num2 + 1); 1100} 1101 1102UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); } 1103UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); } 1104UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); } 1105 1106UString::UString() 1107{ 1108 _chars = NULL; 1109 _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity); 1110 _len = 0; 1111 _limit = kStartStringCapacity - 1; 1112 _chars[0] = 0; 1113} 1114 1115UString::UString(wchar_t c) 1116{ 1117 SetStartLen(1); 1118 wchar_t *chars = _chars; 1119 chars[0] = c; 1120 chars[1] = 0; 1121} 1122 1123UString::UString(char c) 1124{ 1125 SetStartLen(1); 1126 wchar_t *chars = _chars; 1127 chars[0] = (unsigned char)c; 1128 chars[1] = 0; 1129} 1130 1131UString::UString(const wchar_t *s) 1132{ 1133 const unsigned len = MyStringLen(s); 1134 SetStartLen(len); 1135 wmemcpy(_chars, s, len + 1); 1136} 1137 1138UString::UString(const char *s) 1139{ 1140 const unsigned len = MyStringLen(s); 1141 SetStartLen(len); 1142 wchar_t *chars = _chars; 1143 for (unsigned i = 0; i < len; i++) 1144 chars[i] = (unsigned char)s[i]; 1145 chars[len] = 0; 1146} 1147 1148UString::UString(const AString &s) 1149{ 1150 const unsigned len = s.Len(); 1151 SetStartLen(len); 1152 wchar_t *chars = _chars; 1153 const char *s2 = s.Ptr(); 1154 for (unsigned i = 0; i < len; i++) 1155 chars[i] = (unsigned char)s2[i]; 1156 chars[len] = 0; 1157} 1158 1159UString::UString(const UString &s) 1160{ 1161 SetStartLen(s._len); 1162 wmemcpy(_chars, s._chars, s._len + 1); 1163} 1164 1165UString &UString::operator=(wchar_t c) 1166{ 1167 if (1 > _limit) 1168 { 1169 wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); 1170 MY_STRING_DELETE(_chars) 1171 _chars = newBuf; 1172 _limit = 1; 1173 } 1174 _len = 1; 1175 wchar_t *chars = _chars; 1176 chars[0] = c; 1177 chars[1] = 0; 1178 return *this; 1179} 1180 1181UString &UString::operator=(const wchar_t *s) 1182{ 1183 unsigned len = MyStringLen(s); 1184 if (len > _limit) 1185 { 1186 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1187 MY_STRING_DELETE(_chars) 1188 _chars = newBuf; 1189 _limit = len; 1190 } 1191 _len = len; 1192 wmemcpy(_chars, s, len + 1); 1193 return *this; 1194} 1195 1196UString &UString::operator=(const UString &s) 1197{ 1198 if (&s == this) 1199 return *this; 1200 unsigned len = s._len; 1201 if (len > _limit) 1202 { 1203 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1204 MY_STRING_DELETE(_chars) 1205 _chars = newBuf; 1206 _limit = len; 1207 } 1208 _len = len; 1209 wmemcpy(_chars, s._chars, len + 1); 1210 return *this; 1211} 1212 1213void UString::SetFrom(const wchar_t *s, unsigned len) // no check 1214{ 1215 if (len > _limit) 1216 { 1217 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1218 MY_STRING_DELETE(_chars) 1219 _chars = newBuf; 1220 _limit = len; 1221 } 1222 if (len != 0) 1223 wmemcpy(_chars, s, len); 1224 _chars[len] = 0; 1225 _len = len; 1226} 1227 1228void UString::SetFromBstr(LPCOLESTR s) 1229{ 1230 unsigned len = ::SysStringLen((BSTR)(void *)(s)); 1231 1232 /* 1233 #if WCHAR_MAX > 0xffff 1234 size_t num_wchars = 0; 1235 for (size_t i = 0; i < len;) 1236 { 1237 wchar_t c = s[i++]; 1238 if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) 1239 { 1240 wchar_t c2 = s[i]; 1241 if (c2 >= 0xdc00 && c2 < 0x10000) 1242 { 1243 c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); 1244 i++; 1245 } 1246 } 1247 num_wchars++; 1248 } 1249 len = num_wchars; 1250 #endif 1251 */ 1252 1253 if (len > _limit) 1254 { 1255 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1256 MY_STRING_DELETE(_chars) 1257 _chars = newBuf; 1258 _limit = len; 1259 } 1260 _len = len; 1261 1262 /* 1263 #if WCHAR_MAX > 0xffff 1264 1265 wchar_t *chars = _chars; 1266 for (size_t i = 0; i <= len; i++) 1267 { 1268 wchar_t c = *s++; 1269 if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) 1270 { 1271 wchar_t c2 = *s; 1272 if (c2 >= 0xdc00 && c2 < 0x10000) 1273 { 1274 s++; 1275 c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); 1276 } 1277 } 1278 chars[i] = c; 1279 } 1280 1281 #else 1282 */ 1283 1284 // if (s) 1285 wmemcpy(_chars, s, len + 1); 1286 1287 // #endif 1288} 1289 1290UString &UString::operator=(const char *s) 1291{ 1292 unsigned len = MyStringLen(s); 1293 if (len > _limit) 1294 { 1295 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1296 MY_STRING_DELETE(_chars) 1297 _chars = newBuf; 1298 _limit = len; 1299 } 1300 wchar_t *chars = _chars; 1301 for (unsigned i = 0; i < len; i++) 1302 chars[i] = (unsigned char)s[i]; 1303 chars[len] = 0; 1304 _len = len; 1305 return *this; 1306} 1307 1308void UString::Add_Dot() { operator+=(L'.'); } 1309void UString::Add_Space() { operator+=(L' '); } 1310void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } 1311 1312void UString::Add_LF() 1313{ 1314 if (_limit == _len) 1315 Grow_1(); 1316 unsigned len = _len; 1317 wchar_t *chars = _chars; 1318 chars[len++] = L'\n'; 1319 chars[len] = 0; 1320 _len = len; 1321} 1322 1323UString &UString::operator+=(const wchar_t *s) 1324{ 1325 unsigned len = MyStringLen(s); 1326 Grow(len); 1327 wmemcpy(_chars + _len, s, len + 1); 1328 _len += len; 1329 return *this; 1330} 1331 1332UString &UString::operator+=(const UString &s) 1333{ 1334 Grow(s._len); 1335 wmemcpy(_chars + _len, s._chars, s._len + 1); 1336 _len += s._len; 1337 return *this; 1338} 1339 1340UString &UString::operator+=(const char *s) 1341{ 1342 unsigned len = MyStringLen(s); 1343 Grow(len); 1344 wchar_t *chars = _chars + _len; 1345 for (unsigned i = 0; i < len; i++) 1346 chars[i] = (unsigned char)s[i]; 1347 chars[len] = 0; 1348 _len += len; 1349 return *this; 1350} 1351 1352 1353void UString::Add_UInt32(UInt32 v) 1354{ 1355 Grow(10); 1356 _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); 1357} 1358 1359void AString::Add_UInt64(UInt64 v) 1360{ 1361 Grow(20); 1362 _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars); 1363} 1364 1365 1366int UString::Find(const wchar_t *s, unsigned startIndex) const throw() 1367{ 1368 const wchar_t *fs = wcsstr(_chars + startIndex, s); 1369 if (!fs) 1370 return -1; 1371 return (int)(fs - _chars); 1372 1373 /* 1374 if (s[0] == 0) 1375 return startIndex; 1376 unsigned len = MyStringLen(s); 1377 const wchar_t *p = _chars + startIndex; 1378 for (;; p++) 1379 { 1380 const wchar_t c = *p; 1381 if (c != s[0]) 1382 { 1383 if (c == 0) 1384 return -1; 1385 continue; 1386 } 1387 unsigned i; 1388 for (i = 1; i < len; i++) 1389 if (p[i] != s[i]) 1390 break; 1391 if (i == len) 1392 return (int)(p - _chars); 1393 } 1394 */ 1395} 1396 1397int UString::ReverseFind(wchar_t c) const throw() 1398{ 1399 if (_len == 0) 1400 return -1; 1401 const wchar_t *p = _chars + _len; 1402 do 1403 { 1404 if (*(--p) == c) 1405 return (int)(p - _chars); 1406 } 1407 while (p != _chars); 1408 return -1; 1409} 1410 1411int UString::ReverseFind_PathSepar() const throw() 1412{ 1413 const wchar_t *p = _chars + _len; 1414 while (p != _chars) 1415 { 1416 const wchar_t c = *(--p); 1417 if (IS_PATH_SEPAR(c)) 1418 return (int)(p - _chars); 1419 } 1420 return -1; 1421} 1422 1423void UString::TrimLeft() throw() 1424{ 1425 const wchar_t *p = _chars; 1426 for (;; p++) 1427 { 1428 wchar_t c = *p; 1429 if (c != ' ' && c != '\n' && c != '\t') 1430 break; 1431 } 1432 unsigned pos = (unsigned)(p - _chars); 1433 if (pos != 0) 1434 { 1435 MoveItems(0, pos); 1436 _len -= pos; 1437 } 1438} 1439 1440void UString::TrimRight() throw() 1441{ 1442 const wchar_t *p = _chars; 1443 unsigned i; 1444 for (i = _len; i != 0; i--) 1445 { 1446 wchar_t c = p[(size_t)i - 1]; 1447 if (c != ' ' && c != '\n' && c != '\t') 1448 break; 1449 } 1450 if (i != _len) 1451 { 1452 _chars[i] = 0; 1453 _len = i; 1454 } 1455} 1456 1457void UString::InsertAtFront(wchar_t c) 1458{ 1459 if (_limit == _len) 1460 Grow_1(); 1461 MoveItems(1, 0); 1462 _chars[0] = c; 1463 _len++; 1464} 1465 1466/* 1467void UString::Insert_wchar_t(unsigned index, wchar_t c) 1468{ 1469 InsertSpace(index, 1); 1470 _chars[index] = c; 1471 _len++; 1472} 1473*/ 1474 1475void UString::Insert(unsigned index, const wchar_t *s) 1476{ 1477 unsigned num = MyStringLen(s); 1478 if (num != 0) 1479 { 1480 InsertSpace(index, num); 1481 wmemcpy(_chars + index, s, num); 1482 _len += num; 1483 } 1484} 1485 1486void UString::Insert(unsigned index, const UString &s) 1487{ 1488 unsigned num = s.Len(); 1489 if (num != 0) 1490 { 1491 InsertSpace(index, num); 1492 wmemcpy(_chars + index, s, num); 1493 _len += num; 1494 } 1495} 1496 1497void UString::RemoveChar(wchar_t ch) throw() 1498{ 1499 wchar_t *src = _chars; 1500 1501 for (;;) 1502 { 1503 wchar_t c = *src++; 1504 if (c == 0) 1505 return; 1506 if (c == ch) 1507 break; 1508 } 1509 1510 wchar_t *dest = src - 1; 1511 1512 for (;;) 1513 { 1514 wchar_t c = *src++; 1515 if (c == 0) 1516 break; 1517 if (c != ch) 1518 *dest++ = c; 1519 } 1520 1521 *dest = 0; 1522 _len = (unsigned)(dest - _chars); 1523} 1524 1525// !!!!!!!!!!!!!!! test it if newChar = '\0' 1526void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() 1527{ 1528 if (oldChar == newChar) 1529 return; // 0; 1530 // unsigned number = 0; 1531 int pos = 0; 1532 wchar_t *chars = _chars; 1533 while ((unsigned)pos < _len) 1534 { 1535 pos = Find(oldChar, (unsigned)pos); 1536 if (pos < 0) 1537 break; 1538 chars[(unsigned)pos] = newChar; 1539 pos++; 1540 // number++; 1541 } 1542 return; // number; 1543} 1544 1545void UString::Replace(const UString &oldString, const UString &newString) 1546{ 1547 if (oldString.IsEmpty()) 1548 return; // 0; 1549 if (oldString == newString) 1550 return; // 0; 1551 unsigned oldLen = oldString.Len(); 1552 unsigned newLen = newString.Len(); 1553 // unsigned number = 0; 1554 int pos = 0; 1555 while ((unsigned)pos < _len) 1556 { 1557 pos = Find(oldString, (unsigned)pos); 1558 if (pos < 0) 1559 break; 1560 Delete((unsigned)pos, oldLen); 1561 Insert((unsigned)pos, newString); 1562 pos += newLen; 1563 // number++; 1564 } 1565 // return number; 1566} 1567 1568void UString::Delete(unsigned index) throw() 1569{ 1570 MoveItems(index, index + 1); 1571 _len--; 1572} 1573 1574void UString::Delete(unsigned index, unsigned count) throw() 1575{ 1576 if (index + count > _len) 1577 count = _len - index; 1578 if (count > 0) 1579 { 1580 MoveItems(index, index + count); 1581 _len -= count; 1582 } 1583} 1584 1585void UString::DeleteFrontal(unsigned num) throw() 1586{ 1587 if (num != 0) 1588 { 1589 MoveItems(0, num); 1590 _len -= num; 1591 } 1592} 1593 1594 1595// ---------- UString2 ---------- 1596 1597void UString2::ReAlloc2(unsigned newLimit) 1598{ 1599 // wrong (_len) is allowed after this function 1600 if (newLimit > k_Alloc_Len_Limit) throw 20130221; 1601 // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); 1602 if (_chars) 1603 { 1604 MY_STRING_DELETE(_chars) 1605 _chars = NULL; 1606 // _len = 0; 1607 } 1608 _chars = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); 1609 _chars[0] = 0; 1610 // _len = newLimit; 1611} 1612 1613void UString2::SetStartLen(unsigned len) 1614{ 1615 _chars = NULL; 1616 _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); 1617 _len = len; 1618} 1619 1620 1621/* 1622UString2::UString2(wchar_t c) 1623{ 1624 SetStartLen(1); 1625 wchar_t *chars = _chars; 1626 chars[0] = c; 1627 chars[1] = 0; 1628} 1629*/ 1630 1631UString2::UString2(const wchar_t *s) 1632{ 1633 const unsigned len = MyStringLen(s); 1634 SetStartLen(len); 1635 wmemcpy(_chars, s, len + 1); 1636} 1637 1638UString2::UString2(const UString2 &s): _chars(NULL), _len(0) 1639{ 1640 if (s._chars) 1641 { 1642 SetStartLen(s._len); 1643 wmemcpy(_chars, s._chars, s._len + 1); 1644 } 1645} 1646 1647/* 1648UString2 &UString2::operator=(wchar_t c) 1649{ 1650 if (1 > _len) 1651 { 1652 wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); 1653 if (_chars) 1654 MY_STRING_DELETE(_chars) 1655 _chars = newBuf; 1656 } 1657 _len = 1; 1658 wchar_t *chars = _chars; 1659 chars[0] = c; 1660 chars[1] = 0; 1661 return *this; 1662} 1663*/ 1664 1665UString2 &UString2::operator=(const wchar_t *s) 1666{ 1667 unsigned len = MyStringLen(s); 1668 if (len > _len) 1669 { 1670 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1671 if (_chars) 1672 MY_STRING_DELETE(_chars) 1673 _chars = newBuf; 1674 } 1675 _len = len; 1676 MyStringCopy(_chars, s); 1677 return *this; 1678} 1679 1680void UString2::SetFromAscii(const char *s) 1681{ 1682 unsigned len = MyStringLen(s); 1683 if (len > _len) 1684 { 1685 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1686 if (_chars) 1687 MY_STRING_DELETE(_chars) 1688 _chars = newBuf; 1689 } 1690 wchar_t *chars = _chars; 1691 for (unsigned i = 0; i < len; i++) 1692 chars[i] = (unsigned char)s[i]; 1693 chars[len] = 0; 1694 _len = len; 1695} 1696 1697UString2 &UString2::operator=(const UString2 &s) 1698{ 1699 if (&s == this) 1700 return *this; 1701 unsigned len = s._len; 1702 if (len > _len) 1703 { 1704 wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); 1705 if (_chars) 1706 MY_STRING_DELETE(_chars) 1707 _chars = newBuf; 1708 } 1709 _len = len; 1710 MyStringCopy(_chars, s._chars); 1711 return *this; 1712} 1713 1714bool operator==(const UString2 &s1, const UString2 &s2) 1715{ 1716 return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0); 1717} 1718 1719bool operator==(const UString2 &s1, const wchar_t *s2) 1720{ 1721 if (s1.IsEmpty()) 1722 return (*s2 == 0); 1723 return wcscmp(s1.GetRawPtr(), s2) == 0; 1724} 1725 1726bool operator==(const wchar_t *s1, const UString2 &s2) 1727{ 1728 if (s2.IsEmpty()) 1729 return (*s1 == 0); 1730 return wcscmp(s1, s2.GetRawPtr()) == 0; 1731} 1732 1733 1734 1735// ---------------------------------------- 1736 1737/* 1738int MyStringCompareNoCase(const char *s1, const char *s2) 1739{ 1740 return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); 1741} 1742*/ 1743 1744#if !defined(USE_UNICODE_FSTRING) || !defined(_UNICODE) 1745 1746static inline UINT GetCurrentCodePage() 1747{ 1748 #if defined(UNDER_CE) || !defined(_WIN32) 1749 return CP_ACP; 1750 #else 1751 return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; 1752 #endif 1753} 1754 1755#endif 1756 1757#ifdef USE_UNICODE_FSTRING 1758 1759#ifndef _UNICODE 1760 1761AString fs2fas(CFSTR s) 1762{ 1763 return UnicodeStringToMultiByte(s, GetCurrentCodePage()); 1764} 1765 1766FString fas2fs(const char *s) 1767{ 1768 return MultiByteToUnicodeString(s, GetCurrentCodePage()); 1769} 1770 1771FString fas2fs(const AString &s) 1772{ 1773 return MultiByteToUnicodeString(s, GetCurrentCodePage()); 1774} 1775 1776#endif // _UNICODE 1777 1778#else // USE_UNICODE_FSTRING 1779 1780UString fs2us(const FChar *s) 1781{ 1782 return MultiByteToUnicodeString(s, GetCurrentCodePage()); 1783} 1784 1785UString fs2us(const FString &s) 1786{ 1787 return MultiByteToUnicodeString(s, GetCurrentCodePage()); 1788} 1789 1790FString us2fs(const wchar_t *s) 1791{ 1792 return UnicodeStringToMultiByte(s, GetCurrentCodePage()); 1793} 1794 1795#endif // USE_UNICODE_FSTRING 1796 1797 1798bool CStringFinder::FindWord_In_LowCaseAsciiList_NoCase(const char *p, const wchar_t *str) 1799{ 1800 _temp.Empty(); 1801 for (;;) 1802 { 1803 const wchar_t c = *str++; 1804 if (c == 0) 1805 break; 1806 if (c <= 0x20 || c > 0x7f) 1807 return false; 1808 _temp += (char)MyCharLower_Ascii((char)c); 1809 } 1810 1811 while (*p != 0) 1812 { 1813 const char *s2 = _temp.Ptr(); 1814 char c, c2; 1815 do 1816 { 1817 c = *p++; 1818 c2 = *s2++; 1819 } 1820 while (c == c2); 1821 1822 if (c == ' ') 1823 { 1824 if (c2 == 0) 1825 return true; 1826 continue; 1827 } 1828 1829 while (*p++ != ' '); 1830 } 1831 1832 return false; 1833} 1834 1835 1836void SplitString(const UString &srcString, UStringVector &destStrings) 1837{ 1838 destStrings.Clear(); 1839 unsigned len = srcString.Len(); 1840 if (len == 0) 1841 return; 1842 UString s; 1843 for (unsigned i = 0; i < len; i++) 1844 { 1845 const wchar_t c = srcString[i]; 1846 if (c == ' ') 1847 { 1848 if (!s.IsEmpty()) 1849 { 1850 destStrings.Add(s); 1851 s.Empty(); 1852 } 1853 } 1854 else 1855 s += c; 1856 } 1857 if (!s.IsEmpty()) 1858 destStrings.Add(s); 1859} 1860