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