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