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
FindCharPosInString(const char * s,char c)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
FindCharPosInString(const wchar_t * s,wchar_t c)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
MyStringLower_Ascii(char * s)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
MyStringLower_Ascii(wchar_t * s)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
MyCharUpper_WIN(wchar_t c)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
IsString1PrefixedByString2(const char * s1,const char * s2)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
StringsAreEqualNoCase(const wchar_t * s1,const wchar_t * s2)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
IsPrefixedBy_Ascii_NoCase(const char * s) const211 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
IsPrefixedBy_Ascii_NoCase(const char * s) const226 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
StringsAreEqual_Ascii(const wchar_t * u,const char * a)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
StringsAreEqualNoCase_Ascii(const char * s1,const char * s2)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
StringsAreEqualNoCase_Ascii(const wchar_t * s1,const wchar_t * s2)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
StringsAreEqualNoCase_Ascii(const wchar_t * s1,const char * s2)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
IsString1PrefixedByString2(const wchar_t * s1,const wchar_t * s2)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
IsString1PrefixedByString2(const wchar_t * s1,const char * s2)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
IsString1PrefixedByString2_NoCase_Ascii(const wchar_t * s1,const char * s2)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
IsString1PrefixedByString2_NoCase(const wchar_t * s1,const wchar_t * s2)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
MyStringCompareNoCase(const wchar_t * s1,const wchar_t * s2)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
InsertSpace(unsigned & index,unsigned size)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
ReAlloc(unsigned newLimit)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
ReAlloc2(unsigned newLimit)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
SetStartLen(unsigned len)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
Grow_1()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
Grow(unsigned n)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
AString(unsigned num,const char * s)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
AString(unsigned num,const AString & s)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
AString(const AString & s,char c)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
AString(const char * s1,unsigned num1,const char * s2,unsigned num2)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
operator +(const AString & s1,const AString & s2)470 AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
operator +(const AString & s1,const char * s2)471 AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
operator +(const char * s1,const AString & 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
AString()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
AString(char c)485 AString::AString(char c)
486 {
487 SetStartLen(1);
488 char *chars = _chars;
489 chars[0] = c;
490 chars[1] = 0;
491 }
492
AString(const char * s)493 AString::AString(const char *s)
494 {
495 SetStartLen(MyStringLen(s));
496 MyStringCopy(_chars, s);
497 }
498
AString(const AString & s)499 AString::AString(const AString &s)
500 {
501 SetStartLen(s._len);
502 MyStringCopy(_chars, s._chars);
503 }
504
operator =(char c)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
operator =(const char * s)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
operator =(const AString & s)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
SetFromWStr_if_Ascii(const wchar_t * s)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
Add_Space()606 void AString::Add_Space() { operator+=(' '); }
Add_Space_if_NotEmpty()607 void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
Add_LF()608 void AString::Add_LF() { operator+=('\n'); }
609
operator +=(const char * s)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
Add_OptSpaced(const char * s)619 void AString::Add_OptSpaced(const char *s)
620 {
621 Add_Space_if_NotEmpty();
622 (*this) += s;
623 }
624
operator +=(const AString & s)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
Add_UInt32(UInt32 v)633 void AString::Add_UInt32(UInt32 v)
634 {
635 char sz[16];
636 ConvertUInt32ToString(v, sz);
637 (*this) += sz;
638 }
639
SetFrom(const char * s,unsigned len)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
SetFrom_CalcLen(const char * s,unsigned len)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
Find(const char * s,unsigned startIndex) const664 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
ReverseFind(char c) const695 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
ReverseFind_PathSepar() const710 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
TrimLeft()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
TrimRight()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
InsertAtFront(char c)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
Insert(unsigned index,const char * s)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
Insert(unsigned index,const AString & s)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
RemoveChar(char ch)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'
Replace(char oldChar,char newChar)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
Replace(const AString & oldString,const AString & newString)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
Delete(unsigned index)871 void AString::Delete(unsigned index) throw()
872 {
873 MoveItems(index, index + 1);
874 _len--;
875 }
876
Delete(unsigned index,unsigned count)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
DeleteFrontal(unsigned num)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
InsertSpace(unsigned index,unsigned size)941 void UString::InsertSpace(unsigned index, unsigned size)
942 {
943 Grow(size);
944 MoveItems(index + size, index);
945 }
946
ReAlloc(unsigned newLimit)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
ReAlloc2(unsigned newLimit)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
SetStartLen(unsigned len)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
Grow_1()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
Grow(unsigned n)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
UString(unsigned num,const wchar_t * s)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
UString(unsigned num,const UString & s)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
UString(const UString & s,wchar_t c)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
UString(const wchar_t * s1,unsigned num1,const wchar_t * s2,unsigned num2)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
operator +(const UString & s1,const UString & s2)1038 UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
operator +(const UString & s1,const wchar_t * s2)1039 UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
operator +(const wchar_t * s1,const UString & s2)1040 UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
1041
UString()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
UString(wchar_t c)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
UString(char c)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
UString(const wchar_t * s)1067 UString::UString(const wchar_t *s)
1068 {
1069 unsigned len = MyStringLen(s);
1070 SetStartLen(len);
1071 wmemcpy(_chars, s, len + 1);
1072 }
1073
UString(const char * s)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
UString(const UString & s)1084 UString::UString(const UString &s)
1085 {
1086 SetStartLen(s._len);
1087 wmemcpy(_chars, s._chars, s._len + 1);
1088 }
1089
operator =(wchar_t c)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
operator =(const wchar_t * s)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
operator =(const UString & s)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
SetFrom(const wchar_t * s,unsigned len)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
SetFromBstr(BSTR s)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
operator =(const char * s)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
Add_Space()1186 void UString::Add_Space() { operator+=(L' '); }
Add_Space_if_NotEmpty()1187 void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
1188
Add_LF()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
operator +=(const wchar_t * s)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
operator +=(const UString & s)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
operator +=(const char * s)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
Add_UInt32(UInt32 v)1230 void UString::Add_UInt32(UInt32 v)
1231 {
1232 char sz[16];
1233 ConvertUInt32ToString(v, sz);
1234 (*this) += sz;
1235 }
1236
1237
Find(const wchar_t * s,unsigned startIndex) const1238 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
ReverseFind(wchar_t c) const1269 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
ReverseFind_PathSepar() const1284 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
TrimLeft()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
TrimRight()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
InsertAtFront(wchar_t c)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
Insert(unsigned index,const wchar_t * s)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
Insert(unsigned index,const UString & s)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
RemoveChar(wchar_t ch)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'
Replace(wchar_t oldChar,wchar_t newChar)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
Replace(const UString & oldString,const UString & newString)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
Delete(unsigned index)1445 void UString::Delete(unsigned index) throw()
1446 {
1447 MoveItems(index, index + 1);
1448 _len--;
1449 }
1450
Delete(unsigned index,unsigned count)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
DeleteFrontal(unsigned num)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
ReAlloc2(unsigned newLimit)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
SetStartLen(unsigned len)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
UString2(const wchar_t * s)1499 UString2::UString2(const wchar_t *s)
1500 {
1501 unsigned len = MyStringLen(s);
1502 SetStartLen(len);
1503 wmemcpy(_chars, s, len + 1);
1504 }
1505
UString2(const UString2 & s)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
operator =(const wchar_t * s)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
SetFromAscii(const char * s)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
operator =(const UString2 & s)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
operator ==(const UString2 & s1,const UString2 & s2)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
operator ==(const UString2 & s1,const wchar_t * s2)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
operator ==(const wchar_t * s1,const UString2 & s2)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
GetCurrentCodePage()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
fs2fas(CFSTR s)1625 AString fs2fas(CFSTR s)
1626 {
1627 return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1628 }
1629
fas2fs(const char * s)1630 FString fas2fs(const char *s)
1631 {
1632 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1633 }
1634
fas2fs(const AString & s)1635 FString fas2fs(const AString &s)
1636 {
1637 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1638 }
1639
1640 #endif
1641
1642 #else
1643
fs2us(const FChar * s)1644 UString fs2us(const FChar *s)
1645 {
1646 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1647 }
1648
fs2us(const FString & s)1649 UString fs2us(const FString &s)
1650 {
1651 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1652 }
1653
us2fs(const wchar_t * s)1654 FString us2fs(const wchar_t *s)
1655 {
1656 return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1657 }
1658
1659 #endif
1660