• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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 
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     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 
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     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 
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     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 
StringsAreEqual_Ascii(const char * u,const char * a)240 bool 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 
StringsAreEqual_Ascii(const wchar_t * u,const char * a)254 bool 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 
StringsAreEqualNoCase_Ascii(const char * s1,const char * s2)268 bool 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 
StringsAreEqualNoCase_Ascii(const wchar_t * s1,const wchar_t * s2)281 bool 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 
StringsAreEqualNoCase_Ascii(const wchar_t * s1,const char * s2)294 bool 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 
IsString1PrefixedByString2(const wchar_t * s1,const wchar_t * s2)307 bool 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 
IsString1PrefixedByString2(const wchar_t * s1,const char * s2)316 bool 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 
IsString1PrefixedByString2_NoCase_Ascii(const char * s1,const char * s2)325 bool 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 
IsString1PrefixedByString2_NoCase_Ascii(const wchar_t * s1,const char * s2)336 bool 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 
IsString1PrefixedByString2_NoCase(const wchar_t * s1,const wchar_t * s2)347 bool 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
MyStringCompareNoCase(const wchar_t * s1,const wchar_t * s2)359 int 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 /*
377 int 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 
InsertSpace(unsigned & index,unsigned size)398 void 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 
ReAlloc(unsigned newLimit)406 void 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 
ReAlloc2(unsigned newLimit)416 void 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 }
426 
SetStartLen(unsigned len)427 void AString::SetStartLen(unsigned len)
428 {
429   _chars = NULL;
430   _chars = MY_STRING_NEW_char((size_t)len + 1);
431   _len = len;
432   _limit = len;
433 }
434 
Grow_1()435 void AString::Grow_1()
436 {
437   unsigned next = _len;
438   next += next / 2;
439   next += 16;
440   next &= ~(unsigned)15;
441   next--;
442   if (next < _len || next > k_Alloc_Len_Limit)
443     next = k_Alloc_Len_Limit;
444   if (next <= _len)
445     throw 20130220;
446   ReAlloc(next);
447   // Grow(1);
448 }
449 
Grow(unsigned n)450 void AString::Grow(unsigned n)
451 {
452   const unsigned freeSize = _limit - _len;
453   if (n <= freeSize)
454     return;
455   unsigned next = _len + n;
456   next += next / 2;
457   next += 16;
458   next &= ~(unsigned)15;
459   next--;
460   if (next < _len || next > k_Alloc_Len_Limit)
461     next = k_Alloc_Len_Limit;
462   if (next <= _len || next - _len < n)
463     throw 20130220;
464   ReAlloc(next);
465 }
466 
AString(unsigned num,const char * s)467 AString::AString(unsigned num, const char *s)
468 {
469   unsigned len = MyStringLen(s);
470   if (num > len)
471     num = len;
472   SetStartLen(num);
473   memcpy(_chars, s, num);
474   _chars[num] = 0;
475 }
476 
AString(unsigned num,const AString & s)477 AString::AString(unsigned num, const AString &s)
478 {
479   if (num > s._len)
480     num = s._len;
481   SetStartLen(num);
482   memcpy(_chars, s._chars, num);
483   _chars[num] = 0;
484 }
485 
AString(const AString & s,char c)486 AString::AString(const AString &s, char c)
487 {
488   SetStartLen(s.Len() + 1);
489   char *chars = _chars;
490   unsigned len = s.Len();
491   memcpy(chars, s, len);
492   chars[len] = c;
493   chars[(size_t)len + 1] = 0;
494 }
495 
AString(const char * s1,unsigned num1,const char * s2,unsigned num2)496 AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)
497 {
498   SetStartLen(num1 + num2);
499   char *chars = _chars;
500   memcpy(chars, s1, num1);
501   memcpy(chars + num1, s2, num2 + 1);
502 }
503 
operator +(const AString & s1,const AString & s2)504 AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
operator +(const AString & s1,const char * s2)505 AString operator+(const AString &s1, const char    *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
operator +(const char * s1,const AString & s2)506 AString operator+(const char    *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
507 
508 static const unsigned kStartStringCapacity = 4;
509 
AString()510 AString::AString()
511 {
512   _chars = NULL;
513   _chars = MY_STRING_NEW_char(kStartStringCapacity);
514   _len = 0;
515   _limit = kStartStringCapacity - 1;
516   _chars[0] = 0;
517 }
518 
AString(char c)519 AString::AString(char c)
520 {
521   SetStartLen(1);
522   char *chars = _chars;
523   chars[0] = c;
524   chars[1] = 0;
525 }
526 
AString(const char * s)527 AString::AString(const char *s)
528 {
529   SetStartLen(MyStringLen(s));
530   MyStringCopy(_chars, s);
531 }
532 
AString(const AString & s)533 AString::AString(const AString &s)
534 {
535   SetStartLen(s._len);
536   MyStringCopy(_chars, s._chars);
537 }
538 
operator =(char c)539 AString &AString::operator=(char c)
540 {
541   if (1 > _limit)
542   {
543     char *newBuf = MY_STRING_NEW_char(1 + 1);
544     MY_STRING_DELETE(_chars);
545     _chars = newBuf;
546     _limit = 1;
547   }
548   _len = 1;
549   char *chars = _chars;
550   chars[0] = c;
551   chars[1] = 0;
552   return *this;
553 }
554 
operator =(const char * s)555 AString &AString::operator=(const char *s)
556 {
557   unsigned len = MyStringLen(s);
558   if (len > _limit)
559   {
560     char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
561     MY_STRING_DELETE(_chars);
562     _chars = newBuf;
563     _limit = len;
564   }
565   _len = len;
566   MyStringCopy(_chars, s);
567   return *this;
568 }
569 
operator =(const AString & s)570 AString &AString::operator=(const AString &s)
571 {
572   if (&s == this)
573     return *this;
574   unsigned len = s._len;
575   if (len > _limit)
576   {
577     char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
578     MY_STRING_DELETE(_chars);
579     _chars = newBuf;
580     _limit = len;
581   }
582   _len = len;
583   MyStringCopy(_chars, s._chars);
584   return *this;
585 }
586 
SetFromWStr_if_Ascii(const wchar_t * s)587 void AString::SetFromWStr_if_Ascii(const wchar_t *s)
588 {
589   unsigned len = 0;
590   {
591     for (;; len++)
592     {
593       wchar_t c = s[len];
594       if (c == 0)
595         break;
596       if (c >= 0x80)
597         return;
598     }
599   }
600   if (len > _limit)
601   {
602     char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
603     MY_STRING_DELETE(_chars);
604     _chars = newBuf;
605     _limit = len;
606   }
607   _len = len;
608   char *dest = _chars;
609   unsigned i;
610   for (i = 0; i < len; i++)
611     dest[i] = (char)s[i];
612   dest[i] = 0;
613 }
614 
615 /*
616 void AString::SetFromBstr_if_Ascii(BSTR s)
617 {
618   unsigned len = ::SysStringLen(s);
619   {
620     for (unsigned i = 0; i < len; i++)
621       if (s[i] <= 0 || s[i] >= 0x80)
622         return;
623   }
624   if (len > _limit)
625   {
626     char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
627     MY_STRING_DELETE(_chars);
628     _chars = newBuf;
629     _limit = len;
630   }
631   _len = len;
632   char *dest = _chars;
633   unsigned i;
634   for (i = 0; i < len; i++)
635     dest[i] = (char)s[i];
636   dest[i] = 0;
637 }
638 */
639 
Add_Space()640 void AString::Add_Space() { operator+=(' '); }
Add_Space_if_NotEmpty()641 void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
Add_LF()642 void AString::Add_LF() { operator+=('\n'); }
Add_Slash()643 void AString::Add_Slash() { operator+=('/'); }
644 
operator +=(const char * s)645 AString &AString::operator+=(const char *s)
646 {
647   unsigned len = MyStringLen(s);
648   Grow(len);
649   MyStringCopy(_chars + _len, s);
650   _len += len;
651   return *this;
652 }
653 
Add_OptSpaced(const char * s)654 void AString::Add_OptSpaced(const char *s)
655 {
656   Add_Space_if_NotEmpty();
657   (*this) += s;
658 }
659 
operator +=(const AString & s)660 AString &AString::operator+=(const AString &s)
661 {
662   Grow(s._len);
663   MyStringCopy(_chars + _len, s._chars);
664   _len += s._len;
665   return *this;
666 }
667 
Add_UInt32(UInt32 v)668 void AString::Add_UInt32(UInt32 v)
669 {
670   Grow(10);
671   _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars);
672 }
673 
Add_UInt64(UInt64 v)674 void UString::Add_UInt64(UInt64 v)
675 {
676   Grow(20);
677   _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars);
678 }
679 
AddFrom(const char * s,unsigned len)680 void AString::AddFrom(const char *s, unsigned len) // no check
681 {
682   if (len != 0)
683   {
684     Grow(len);
685     memcpy(_chars + _len, s, len);
686     len += _len;
687     _chars[len] = 0;
688     _len = len;
689   }
690 }
691 
SetFrom(const char * s,unsigned len)692 void AString::SetFrom(const char *s, unsigned len) // no check
693 {
694   if (len > _limit)
695   {
696     char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
697     MY_STRING_DELETE(_chars);
698     _chars = newBuf;
699     _limit = len;
700   }
701   if (len != 0)
702     memcpy(_chars, s, len);
703   _chars[len] = 0;
704   _len = len;
705 }
706 
SetFrom_CalcLen(const char * s,unsigned len)707 void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check
708 {
709   unsigned i;
710   for (i = 0; i < len; i++)
711     if (s[i] == 0)
712       break;
713   SetFrom(s, i);
714 }
715 
Find(const char * s,unsigned startIndex) const716 int AString::Find(const char *s, unsigned startIndex) const throw()
717 {
718   const char *fs = strstr(_chars + startIndex, s);
719   if (!fs)
720     return -1;
721   return (int)(fs - _chars);
722 
723   /*
724   if (s[0] == 0)
725     return startIndex;
726   unsigned len = MyStringLen(s);
727   const char *p = _chars + startIndex;
728   for (;; p++)
729   {
730     const char c = *p;
731     if (c != s[0])
732     {
733       if (c == 0)
734         return -1;
735       continue;
736     }
737     unsigned i;
738     for (i = 1; i < len; i++)
739       if (p[i] != s[i])
740         break;
741     if (i == len)
742       return (int)(p - _chars);
743   }
744   */
745 }
746 
ReverseFind(char c) const747 int AString::ReverseFind(char c) const throw()
748 {
749   if (_len == 0)
750     return -1;
751   const char *p = _chars + _len - 1;
752   for (;;)
753   {
754     if (*p == c)
755       return (int)(p - _chars);
756     if (p == _chars)
757       return -1;
758     p--; // p = GetPrevCharPointer(_chars, p);
759   }
760 }
761 
ReverseFind_PathSepar() const762 int AString::ReverseFind_PathSepar() const throw()
763 {
764   if (_len == 0)
765     return -1;
766   const char *p = _chars + _len - 1;
767   for (;;)
768   {
769     char c = *p;
770     if (IS_PATH_SEPAR(c))
771       return (int)(p - _chars);
772     if (p == _chars)
773       return -1;
774     p--;
775   }
776 }
777 
TrimLeft()778 void AString::TrimLeft() throw()
779 {
780   const char *p = _chars;
781   for (;; p++)
782   {
783     char c = *p;
784     if (c != ' ' && c != '\n' && c != '\t')
785       break;
786   }
787   unsigned pos = (unsigned)(p - _chars);
788   if (pos != 0)
789   {
790     MoveItems(0, pos);
791     _len -= pos;
792   }
793 }
794 
TrimRight()795 void AString::TrimRight() throw()
796 {
797   const char *p = _chars;
798   unsigned i;
799   for (i = _len; i != 0; i--)
800   {
801     char c = p[(size_t)i - 1];
802     if (c != ' ' && c != '\n' && c != '\t')
803       break;
804   }
805   if (i != _len)
806   {
807     _chars[i] = 0;
808     _len = i;
809   }
810 }
811 
InsertAtFront(char c)812 void AString::InsertAtFront(char c)
813 {
814   if (_limit == _len)
815     Grow_1();
816   MoveItems(1, 0);
817   _chars[0] = c;
818   _len++;
819 }
820 
821 /*
822 void AString::Insert(unsigned index, char c)
823 {
824   InsertSpace(index, 1);
825   _chars[index] = c;
826   _len++;
827 }
828 */
829 
Insert(unsigned index,const char * s)830 void AString::Insert(unsigned index, const char *s)
831 {
832   unsigned num = MyStringLen(s);
833   if (num != 0)
834   {
835     InsertSpace(index, num);
836     memcpy(_chars + index, s, num);
837     _len += num;
838   }
839 }
840 
Insert(unsigned index,const AString & s)841 void AString::Insert(unsigned index, const AString &s)
842 {
843   unsigned num = s.Len();
844   if (num != 0)
845   {
846     InsertSpace(index, num);
847     memcpy(_chars + index, s, num);
848     _len += num;
849   }
850 }
851 
RemoveChar(char ch)852 void AString::RemoveChar(char ch) throw()
853 {
854   char *src = _chars;
855 
856   for (;;)
857   {
858     char c = *src++;
859     if (c == 0)
860       return;
861     if (c == ch)
862       break;
863   }
864 
865   char *dest = src - 1;
866 
867   for (;;)
868   {
869     char c = *src++;
870     if (c == 0)
871       break;
872     if (c != ch)
873       *dest++ = c;
874   }
875 
876   *dest = 0;
877   _len = (unsigned)(dest - _chars);
878 }
879 
880 // !!!!!!!!!!!!!!! test it if newChar = '\0'
Replace(char oldChar,char newChar)881 void AString::Replace(char oldChar, char newChar) throw()
882 {
883   if (oldChar == newChar)
884     return; // 0;
885   // unsigned number = 0;
886   int pos = 0;
887   char *chars = _chars;
888   while ((unsigned)pos < _len)
889   {
890     pos = Find(oldChar, (unsigned)pos);
891     if (pos < 0)
892       break;
893     chars[(unsigned)pos] = newChar;
894     pos++;
895     // number++;
896   }
897   return; //  number;
898 }
899 
Replace(const AString & oldString,const AString & newString)900 void AString::Replace(const AString &oldString, const AString &newString)
901 {
902   if (oldString.IsEmpty())
903     return; // 0;
904   if (oldString == newString)
905     return; // 0;
906   unsigned oldLen = oldString.Len();
907   unsigned newLen = newString.Len();
908   // unsigned number = 0;
909   int pos = 0;
910   while ((unsigned)pos < _len)
911   {
912     pos = Find(oldString, (unsigned)pos);
913     if (pos < 0)
914       break;
915     Delete((unsigned)pos, oldLen);
916     Insert((unsigned)pos, newString);
917     pos += newLen;
918     // number++;
919   }
920   // return number;
921 }
922 
Delete(unsigned index)923 void AString::Delete(unsigned index) throw()
924 {
925   MoveItems(index, index + 1);
926   _len--;
927 }
928 
Delete(unsigned index,unsigned count)929 void AString::Delete(unsigned index, unsigned count) throw()
930 {
931   if (index + count > _len)
932     count = _len - index;
933   if (count > 0)
934   {
935     MoveItems(index, index + count);
936     _len -= count;
937   }
938 }
939 
DeleteFrontal(unsigned num)940 void AString::DeleteFrontal(unsigned num) throw()
941 {
942   if (num != 0)
943   {
944     MoveItems(0, num);
945     _len -= num;
946   }
947 }
948 
949 /*
950 AString operator+(const AString &s1, const AString &s2)
951 {
952   AString result(s1);
953   result += s2;
954   return result;
955 }
956 
957 AString operator+(const AString &s, const char *chars)
958 {
959   AString result(s);
960   result += chars;
961   return result;
962 }
963 
964 AString operator+(const char *chars, const AString &s)
965 {
966   AString result(chars);
967   result += s;
968   return result;
969 }
970 
971 AString operator+(const AString &s, char c)
972 {
973   AString result(s);
974   result += c;
975   return result;
976 }
977 */
978 
979 /*
980 AString operator+(char c, const AString &s)
981 {
982   AString result(c);
983   result += s;
984   return result;
985 }
986 */
987 
988 
989 
990 
991 // ---------- UString ----------
992 
InsertSpace(unsigned index,unsigned size)993 void UString::InsertSpace(unsigned index, unsigned size)
994 {
995   Grow(size);
996   MoveItems(index + size, index);
997 }
998 
ReAlloc(unsigned newLimit)999 void UString::ReAlloc(unsigned newLimit)
1000 {
1001   // MY_STRING_REALLOC(_chars, wchar_t, (size_t)newLimit + 1, (size_t)_len + 1);
1002   wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1);
1003   wmemcpy(newBuf, _chars, _len + 1);
1004   MY_STRING_DELETE(_chars);
1005   _chars = newBuf;
1006   _limit = newLimit;
1007 }
1008 
ReAlloc2(unsigned newLimit)1009 void UString::ReAlloc2(unsigned newLimit)
1010 {
1011   if (newLimit > k_Alloc_Len_Limit) throw 20130221;
1012   // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
1013   wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1);
1014   newBuf[0] = 0;
1015   MY_STRING_DELETE(_chars);
1016   _chars = newBuf;
1017   _limit = newLimit;
1018 }
1019 
SetStartLen(unsigned len)1020 void UString::SetStartLen(unsigned len)
1021 {
1022   _chars = 0;
1023   _chars = MY_STRING_NEW_wchar_t((size_t)len + 1);
1024   _len = len;
1025   _limit = len;
1026 }
1027 
Grow_1()1028 void UString::Grow_1()
1029 {
1030   unsigned next = _len;
1031   next += next / 2;
1032   next += 16;
1033   next &= ~(unsigned)15;
1034   next--;
1035   if (next < _len || next > k_Alloc_Len_Limit)
1036     next = k_Alloc_Len_Limit;
1037   if (next <= _len)
1038     throw 20130220;
1039   ReAlloc(next);
1040 }
1041 
Grow(unsigned n)1042 void UString::Grow(unsigned n)
1043 {
1044   const unsigned freeSize = _limit - _len;
1045   if (n <= freeSize)
1046     return;
1047   unsigned next = _len + n;
1048   next += next / 2;
1049   next += 16;
1050   next &= ~(unsigned)15;
1051   next--;
1052   if (next < _len || next > k_Alloc_Len_Limit)
1053     next = k_Alloc_Len_Limit;
1054   if (next <= _len || next - _len < n)
1055     throw 20130220;
1056   ReAlloc(next - 1);
1057 }
1058 
1059 
UString(unsigned num,const wchar_t * s)1060 UString::UString(unsigned num, const wchar_t *s)
1061 {
1062   unsigned len = MyStringLen(s);
1063   if (num > len)
1064     num = len;
1065   SetStartLen(num);
1066   wmemcpy(_chars, s, num);
1067   _chars[num] = 0;
1068 }
1069 
1070 
UString(unsigned num,const UString & s)1071 UString::UString(unsigned num, const UString &s)
1072 {
1073   if (num > s._len)
1074     num = s._len;
1075   SetStartLen(num);
1076   wmemcpy(_chars, s._chars, num);
1077   _chars[num] = 0;
1078 }
1079 
UString(const UString & s,wchar_t c)1080 UString::UString(const UString &s, wchar_t c)
1081 {
1082   SetStartLen(s.Len() + 1);
1083   wchar_t *chars = _chars;
1084   unsigned len = s.Len();
1085   wmemcpy(chars, s, len);
1086   chars[len] = c;
1087   chars[(size_t)len + 1] = 0;
1088 }
1089 
UString(const wchar_t * s1,unsigned num1,const wchar_t * s2,unsigned num2)1090 UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)
1091 {
1092   SetStartLen(num1 + num2);
1093   wchar_t *chars = _chars;
1094   wmemcpy(chars, s1, num1);
1095   wmemcpy(chars + num1, s2, num2 + 1);
1096 }
1097 
operator +(const UString & s1,const UString & s2)1098 UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
operator +(const UString & s1,const wchar_t * s2)1099 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)1100 UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
1101 
UString()1102 UString::UString()
1103 {
1104   _chars = 0;
1105   _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity);
1106   _len = 0;
1107   _limit = kStartStringCapacity - 1;
1108   _chars[0] = 0;
1109 }
1110 
UString(wchar_t c)1111 UString::UString(wchar_t c)
1112 {
1113   SetStartLen(1);
1114   wchar_t *chars = _chars;
1115   chars[0] = c;
1116   chars[1] = 0;
1117 }
1118 
UString(char c)1119 UString::UString(char c)
1120 {
1121   SetStartLen(1);
1122   wchar_t *chars = _chars;
1123   chars[0] = (unsigned char)c;
1124   chars[1] = 0;
1125 }
1126 
UString(const wchar_t * s)1127 UString::UString(const wchar_t *s)
1128 {
1129   const unsigned len = MyStringLen(s);
1130   SetStartLen(len);
1131   wmemcpy(_chars, s, len + 1);
1132 }
1133 
UString(const char * s)1134 UString::UString(const char *s)
1135 {
1136   const unsigned len = MyStringLen(s);
1137   SetStartLen(len);
1138   wchar_t *chars = _chars;
1139   for (unsigned i = 0; i < len; i++)
1140     chars[i] = (unsigned char)s[i];
1141   chars[len] = 0;
1142 }
1143 
UString(const AString & s)1144 UString::UString(const AString &s)
1145 {
1146   const unsigned len = s.Len();
1147   SetStartLen(len);
1148   wchar_t *chars = _chars;
1149   const char *s2 = s.Ptr();
1150   for (unsigned i = 0; i < len; i++)
1151     chars[i] = (unsigned char)s2[i];
1152   chars[len] = 0;
1153 }
1154 
UString(const UString & s)1155 UString::UString(const UString &s)
1156 {
1157   SetStartLen(s._len);
1158   wmemcpy(_chars, s._chars, s._len + 1);
1159 }
1160 
operator =(wchar_t c)1161 UString &UString::operator=(wchar_t c)
1162 {
1163   if (1 > _limit)
1164   {
1165     wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1);
1166     MY_STRING_DELETE(_chars);
1167     _chars = newBuf;
1168     _limit = 1;
1169   }
1170   _len = 1;
1171   wchar_t *chars = _chars;
1172   chars[0] = c;
1173   chars[1] = 0;
1174   return *this;
1175 }
1176 
operator =(const wchar_t * s)1177 UString &UString::operator=(const wchar_t *s)
1178 {
1179   unsigned len = MyStringLen(s);
1180   if (len > _limit)
1181   {
1182     wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
1183     MY_STRING_DELETE(_chars);
1184     _chars = newBuf;
1185     _limit = len;
1186   }
1187   _len = len;
1188   wmemcpy(_chars, s, len + 1);
1189   return *this;
1190 }
1191 
operator =(const UString & s)1192 UString &UString::operator=(const UString &s)
1193 {
1194   if (&s == this)
1195     return *this;
1196   unsigned len = s._len;
1197   if (len > _limit)
1198   {
1199     wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
1200     MY_STRING_DELETE(_chars);
1201     _chars = newBuf;
1202     _limit = len;
1203   }
1204   _len = len;
1205   wmemcpy(_chars, s._chars, len + 1);
1206   return *this;
1207 }
1208 
SetFrom(const wchar_t * s,unsigned len)1209 void UString::SetFrom(const wchar_t *s, unsigned len) // no check
1210 {
1211   if (len > _limit)
1212   {
1213     wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
1214     MY_STRING_DELETE(_chars);
1215     _chars = newBuf;
1216     _limit = len;
1217   }
1218   if (len != 0)
1219     wmemcpy(_chars, s, len);
1220   _chars[len] = 0;
1221   _len = len;
1222 }
1223 
SetFromBstr(LPCOLESTR s)1224 void UString::SetFromBstr(LPCOLESTR s)
1225 {
1226   unsigned len = ::SysStringLen((BSTR)(void *)(s));
1227 
1228   /*
1229   #if WCHAR_MAX > 0xffff
1230   size_t num_wchars = 0;
1231   for (size_t i = 0; i < len;)
1232   {
1233     wchar_t c = s[i++];
1234     if (c >= 0xd800 && c < 0xdc00 && i + 1 != len)
1235     {
1236       wchar_t c2 = s[i];
1237       if (c2 >= 0xdc00 && c2 < 0x10000)
1238       {
1239         c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff);
1240         i++;
1241       }
1242     }
1243     num_wchars++;
1244   }
1245   len = num_wchars;
1246   #endif
1247   */
1248 
1249   if (len > _limit)
1250   {
1251     wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
1252     MY_STRING_DELETE(_chars);
1253     _chars = newBuf;
1254     _limit = len;
1255   }
1256   _len = len;
1257 
1258   /*
1259   #if WCHAR_MAX > 0xffff
1260 
1261   wchar_t *chars = _chars;
1262   for (size_t i = 0; i <= len; i++)
1263   {
1264     wchar_t c = *s++;
1265     if (c >= 0xd800 && c < 0xdc00 && i + 1 != len)
1266     {
1267       wchar_t c2 = *s;
1268       if (c2 >= 0xdc00 && c2 < 0x10000)
1269       {
1270         s++;
1271         c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff);
1272       }
1273     }
1274     chars[i] = c;
1275   }
1276 
1277   #else
1278   */
1279 
1280   // if (s)
1281     wmemcpy(_chars, s, len + 1);
1282 
1283   // #endif
1284 }
1285 
operator =(const char * s)1286 UString &UString::operator=(const char *s)
1287 {
1288   unsigned len = MyStringLen(s);
1289   if (len > _limit)
1290   {
1291     wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
1292     MY_STRING_DELETE(_chars);
1293     _chars = newBuf;
1294     _limit = len;
1295   }
1296   wchar_t *chars = _chars;
1297   for (unsigned i = 0; i < len; i++)
1298     chars[i] = (unsigned char)s[i];
1299   chars[len] = 0;
1300   _len = len;
1301   return *this;
1302 }
1303 
Add_Space()1304 void UString::Add_Space() { operator+=(L' '); }
Add_Space_if_NotEmpty()1305 void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
1306 
Add_LF()1307 void UString::Add_LF()
1308 {
1309   if (_limit == _len)
1310     Grow_1();
1311   unsigned len = _len;
1312   wchar_t *chars = _chars;
1313   chars[len++] = L'\n';
1314   chars[len] = 0;
1315   _len = len;
1316 }
1317 
operator +=(const wchar_t * s)1318 UString &UString::operator+=(const wchar_t *s)
1319 {
1320   unsigned len = MyStringLen(s);
1321   Grow(len);
1322   wmemcpy(_chars + _len, s, len + 1);
1323   _len += len;
1324   return *this;
1325 }
1326 
operator +=(const UString & s)1327 UString &UString::operator+=(const UString &s)
1328 {
1329   Grow(s._len);
1330   wmemcpy(_chars + _len, s._chars, s._len + 1);
1331   _len += s._len;
1332   return *this;
1333 }
1334 
operator +=(const char * s)1335 UString &UString::operator+=(const char *s)
1336 {
1337   unsigned len = MyStringLen(s);
1338   Grow(len);
1339   wchar_t *chars = _chars + _len;
1340   for (unsigned i = 0; i < len; i++)
1341     chars[i] = (unsigned char)s[i];
1342   chars[len] = 0;
1343   _len += len;
1344   return *this;
1345 }
1346 
1347 
Add_UInt32(UInt32 v)1348 void UString::Add_UInt32(UInt32 v)
1349 {
1350   Grow(10);
1351   _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars);
1352 }
1353 
Add_UInt64(UInt64 v)1354 void AString::Add_UInt64(UInt64 v)
1355 {
1356   Grow(20);
1357   _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars);
1358 }
1359 
1360 
Find(const wchar_t * s,unsigned startIndex) const1361 int UString::Find(const wchar_t *s, unsigned startIndex) const throw()
1362 {
1363   const wchar_t *fs = wcsstr(_chars + startIndex, s);
1364   if (!fs)
1365     return -1;
1366   return (int)(fs - _chars);
1367 
1368   /*
1369   if (s[0] == 0)
1370     return startIndex;
1371   unsigned len = MyStringLen(s);
1372   const wchar_t *p = _chars + startIndex;
1373   for (;; p++)
1374   {
1375     const wchar_t c = *p;
1376     if (c != s[0])
1377     {
1378       if (c == 0)
1379         return -1;
1380       continue;
1381     }
1382     unsigned i;
1383     for (i = 1; i < len; i++)
1384       if (p[i] != s[i])
1385         break;
1386     if (i == len)
1387       return (int)(p - _chars);
1388   }
1389   */
1390 }
1391 
ReverseFind(wchar_t c) const1392 int UString::ReverseFind(wchar_t c) const throw()
1393 {
1394   if (_len == 0)
1395     return -1;
1396   const wchar_t *p = _chars + _len - 1;
1397   for (;;)
1398   {
1399     if (*p == c)
1400       return (int)(p - _chars);
1401     if (p == _chars)
1402       return -1;
1403     p--;
1404   }
1405 }
1406 
ReverseFind_PathSepar() const1407 int UString::ReverseFind_PathSepar() const throw()
1408 {
1409   if (_len == 0)
1410     return -1;
1411   const wchar_t *p = _chars + _len - 1;
1412   for (;;)
1413   {
1414     wchar_t c = *p;
1415     if (IS_PATH_SEPAR(c))
1416       return (int)(p - _chars);
1417     if (p == _chars)
1418       return -1;
1419     p--;
1420   }
1421 }
1422 
TrimLeft()1423 void 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 
TrimRight()1440 void 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 
InsertAtFront(wchar_t c)1457 void 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 /*
1467 void UString::Insert_wchar_t(unsigned index, wchar_t c)
1468 {
1469   InsertSpace(index, 1);
1470   _chars[index] = c;
1471   _len++;
1472 }
1473 */
1474 
Insert(unsigned index,const wchar_t * s)1475 void 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 
Insert(unsigned index,const UString & s)1486 void 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 
RemoveChar(wchar_t ch)1497 void 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'
Replace(wchar_t oldChar,wchar_t newChar)1526 void 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 
Replace(const UString & oldString,const UString & newString)1545 void 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 
Delete(unsigned index)1568 void UString::Delete(unsigned index) throw()
1569 {
1570   MoveItems(index, index + 1);
1571   _len--;
1572 }
1573 
Delete(unsigned index,unsigned count)1574 void 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 
DeleteFrontal(unsigned num)1585 void 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 
ReAlloc2(unsigned newLimit)1597 void 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 
SetStartLen(unsigned len)1613 void 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 /*
1622 UString2::UString2(wchar_t c)
1623 {
1624   SetStartLen(1);
1625   wchar_t *chars = _chars;
1626   chars[0] = c;
1627   chars[1] = 0;
1628 }
1629 */
1630 
UString2(const wchar_t * s)1631 UString2::UString2(const wchar_t *s)
1632 {
1633   const unsigned len = MyStringLen(s);
1634   SetStartLen(len);
1635   wmemcpy(_chars, s, len + 1);
1636 }
1637 
UString2(const UString2 & s)1638 UString2::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 /*
1648 UString2 &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 
operator =(const wchar_t * s)1665 UString2 &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 
SetFromAscii(const char * s)1680 void 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 
operator =(const UString2 & s)1697 UString2 &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 
operator ==(const UString2 & s1,const UString2 & s2)1714 bool operator==(const UString2 &s1, const UString2 &s2)
1715 {
1716   return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);
1717 }
1718 
operator ==(const UString2 & s1,const wchar_t * s2)1719 bool 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 
operator ==(const wchar_t * s1,const UString2 & s2)1726 bool 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 /*
1738 int 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 
GetCurrentCodePage()1746 static 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 
fs2fas(CFSTR s)1761 AString fs2fas(CFSTR s)
1762 {
1763   return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1764 }
1765 
fas2fs(const char * s)1766 FString fas2fs(const char *s)
1767 {
1768   return MultiByteToUnicodeString(s, GetCurrentCodePage());
1769 }
1770 
fas2fs(const AString & s)1771 FString fas2fs(const AString &s)
1772 {
1773   return MultiByteToUnicodeString(s, GetCurrentCodePage());
1774 }
1775 
1776 #endif //  _UNICODE
1777 
1778 #else // USE_UNICODE_FSTRING
1779 
fs2us(const FChar * s)1780 UString fs2us(const FChar *s)
1781 {
1782   return MultiByteToUnicodeString(s, GetCurrentCodePage());
1783 }
1784 
fs2us(const FString & s)1785 UString fs2us(const FString &s)
1786 {
1787   return MultiByteToUnicodeString(s, GetCurrentCodePage());
1788 }
1789 
us2fs(const wchar_t * s)1790 FString us2fs(const wchar_t *s)
1791 {
1792   return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1793 }
1794 
1795 #endif // USE_UNICODE_FSTRING
1796