aboutsummaryrefslogtreecommitdiff
path: root/CPP/Common/MyString.cpp
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/Common/MyString.cpp
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to 'CPP/Common/MyString.cpp')
-rw-r--r--CPP/Common/MyString.cpp1756
1 files changed, 1756 insertions, 0 deletions
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
new file mode 100644
index 0000000..db202f4
--- /dev/null
+++ b/CPP/Common/MyString.cpp
@@ -0,0 +1,1756 @@
1// Common/MyString.cpp
2
3#include "StdAfx.h"
4
5#ifdef _WIN32
6#include <wchar.h>
7#else
8#include <ctype.h>
9#endif
10
11#include "IntToString.h"
12
13#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)
14#include "StringConvert.h"
15#endif
16
17#include "MyString.h"
18
19#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]
20// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))
21
22/*
23inline const char* MyStringGetNextCharPointer(const char *p) throw()
24{
25 #if defined(_WIN32) && !defined(UNDER_CE)
26 return CharNextA(p);
27 #else
28 return p + 1;
29 #endif
30}
31*/
32
33#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, _size_)
34#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, _size_)
35
36
37int FindCharPosInString(const char *s, char c) throw()
38{
39 for (const char *p = s;; p++)
40 {
41 if (*p == c)
42 return (int)(p - s);
43 if (*p == 0)
44 return -1;
45 // MyStringGetNextCharPointer(p);
46 }
47}
48
49int FindCharPosInString(const wchar_t *s, wchar_t c) throw()
50{
51 for (const wchar_t *p = s;; p++)
52 {
53 if (*p == c)
54 return (int)(p - s);
55 if (*p == 0)
56 return -1;
57 }
58}
59
60/*
61void MyStringUpper_Ascii(char *s) throw()
62{
63 for (;;)
64 {
65 char c = *s;
66 if (c == 0)
67 return;
68 *s++ = MyCharUpper_Ascii(c);
69 }
70}
71
72void MyStringUpper_Ascii(wchar_t *s) throw()
73{
74 for (;;)
75 {
76 wchar_t c = *s;
77 if (c == 0)
78 return;
79 *s++ = MyCharUpper_Ascii(c);
80 }
81}
82*/
83
84void MyStringLower_Ascii(char *s) throw()
85{
86 for (;;)
87 {
88 char c = *s;
89 if (c == 0)
90 return;
91 *s++ = MyCharLower_Ascii(c);
92 }
93}
94
95void MyStringLower_Ascii(wchar_t *s) throw()
96{
97 for (;;)
98 {
99 wchar_t c = *s;
100 if (c == 0)
101 return;
102 *s++ = MyCharLower_Ascii(c);
103 }
104}
105
106#ifdef _WIN32
107
108#ifdef _UNICODE
109
110// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
111// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
112// for WinCE - FString - char
113// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }
114
115#else
116
117// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }
118// char * MyStringUpper(char *s) { return CharUpperA(s); }
119// char * MyStringLower(char *s) { return CharLowerA(s); }
120
121wchar_t MyCharUpper_WIN(wchar_t c) throw()
122{
123 wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
124 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
125 return (wchar_t)(unsigned)(UINT_PTR)res;
126 const int kBufSize = 4;
127 char s[kBufSize + 1];
128 int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
129 if (numChars == 0 || numChars > kBufSize)
130 return c;
131 s[numChars] = 0;
132 ::CharUpperA(s);
133 ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
134 return c;
135}
136
137/*
138wchar_t MyCharLower_WIN(wchar_t c)
139{
140 wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
141 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
142 return (wchar_t)(unsigned)(UINT_PTR)res;
143 const int kBufSize = 4;
144 char s[kBufSize + 1];
145 int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);
146 if (numChars == 0 || numChars > kBufSize)
147 return c;
148 s[numChars] = 0;
149 ::CharLowerA(s);
150 ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
151 return c;
152}
153*/
154
155/*
156wchar_t * MyStringUpper(wchar_t *s)
157{
158 if (s == 0)
159 return 0;
160 wchar_t *res = CharUpperW(s);
161 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
162 return res;
163 AString a = UnicodeStringToMultiByte(s);
164 a.MakeUpper();
165 MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
166 return s;
167}
168*/
169
170/*
171wchar_t * MyStringLower(wchar_t *s)
172{
173 if (s == 0)
174 return 0;
175 wchar_t *res = CharLowerW(s);
176 if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
177 return res;
178 AString a = UnicodeStringToMultiByte(s);
179 a.MakeLower();
180 MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
181 return s;
182}
183*/
184
185#endif
186
187#endif
188
189bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
190{
191 for (;;)
192 {
193 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
198bool 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
211bool 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
226bool 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
240bool 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
254bool 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
268bool 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
281bool 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
294bool 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
307bool 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
316bool 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
325bool 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
336bool 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
347bool 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
359int 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/*
377int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)
378{
379 for (; num != 0; num--)
380 {
381 wchar_t c1 = *s1++;
382 wchar_t c2 = *s2++;
383 if (c1 != c2)
384 {
385 wchar_t u1 = MyCharUpper(c1);
386 wchar_t u2 = MyCharUpper(c2);
387 if (u1 < u2) return -1;
388 if (u1 > u2) return 1;
389 }
390 if (c1 == 0) return 0;
391 }
392 return 0;
393}
394*/
395
396// ---------- AString ----------
397
398void AString::InsertSpace(unsigned &index, unsigned size)
399{
400 Grow(size);
401 MoveItems(index + size, index);
402}
403
404#define k_Alloc_Len_Limit 0x40000000
405
406void 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
417void 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
428void AString::SetStartLen(unsigned len)
429{
430 _chars = 0;
431 _chars = MY_STRING_NEW_char(len + 1);
432 _len = len;
433 _limit = len;
434}
435
436void AString::Grow_1()
437{
438 unsigned next = _len;
439 next += next / 2;
440 next += 16;
441 next &= ~(unsigned)15;
442 ReAlloc(next - 1);
443}
444
445void 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
458AString::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
468AString::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
477AString::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
487AString::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
495AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }
496AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }
497AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }
498
499static const unsigned kStartStringCapacity = 4;
500
501AString::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
510AString::AString(char c)
511{
512 SetStartLen(1);
513 char *chars = _chars;
514 chars[0] = c;
515 chars[1] = 0;
516}
517
518AString::AString(const char *s)
519{
520 SetStartLen(MyStringLen(s));
521 MyStringCopy(_chars, s);
522}
523
524AString::AString(const AString &s)
525{
526 SetStartLen(s._len);
527 MyStringCopy(_chars, s._chars);
528}
529
530AString &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
546AString &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
561AString &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
578void 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/*
607void 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
631void AString::Add_Space() { operator+=(' '); }
632void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
633void AString::Add_LF() { operator+=('\n'); }
634
635AString &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
644void AString::Add_OptSpaced(const char *s)
645{
646 Add_Space_if_NotEmpty();
647 (*this) += s;
648}
649
650AString &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
658void AString::Add_UInt32(UInt32 v)
659{
660 Grow(10);
661 _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars);
662}
663
664void UString::Add_UInt64(UInt64 v)
665{
666 Grow(20);
667 _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars);
668}
669
670void 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
685void 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
694int 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
725int 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
740int 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
756void 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
773void 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
790void 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/*
800void AString::Insert(unsigned index, char c)
801{
802 InsertSpace(index, 1);
803 _chars[index] = c;
804 _len++;
805}
806*/
807
808void 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
819void 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
830void 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'
859void 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
878void 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
901void AString::Delete(unsigned index) throw()
902{
903 MoveItems(index, index + 1);
904 _len--;
905}
906
907void 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
918void AString::DeleteFrontal(unsigned num) throw()
919{
920 if (num != 0)
921 {
922 MoveItems(0, num);
923 _len -= num;
924 }
925}
926
927/*
928AString operator+(const AString &s1, const AString &s2)
929{
930 AString result(s1);
931 result += s2;
932 return result;
933}
934
935AString operator+(const AString &s, const char *chars)
936{
937 AString result(s);
938 result += chars;
939 return result;
940}
941
942AString operator+(const char *chars, const AString &s)
943{
944 AString result(chars);
945 result += s;
946 return result;
947}
948
949AString operator+(const AString &s, char c)
950{
951 AString result(s);
952 result += c;
953 return result;
954}
955*/
956
957/*
958AString 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
971void UString::InsertSpace(unsigned index, unsigned size)
972{
973 Grow(size);
974 MoveItems(index + size, index);
975}
976
977void 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
988void 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
999void 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
1007void 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
1016void 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
1030UString::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
1041UString::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
1050UString::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
1060UString::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
1068UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }
1069UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }
1070UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }
1071
1072UString::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
1081UString::UString(wchar_t c)
1082{
1083 SetStartLen(1);
1084 wchar_t *chars = _chars;
1085 chars[0] = c;
1086 chars[1] = 0;
1087}
1088
1089UString::UString(char c)
1090{
1091 SetStartLen(1);
1092 wchar_t *chars = _chars;
1093 chars[0] = (unsigned char)c;
1094 chars[1] = 0;
1095}
1096
1097UString::UString(const wchar_t *s)
1098{
1099 const unsigned len = MyStringLen(s);
1100 SetStartLen(len);
1101 wmemcpy(_chars, s, len + 1);
1102}
1103
1104UString::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
1114UString::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
1125UString::UString(const UString &s)
1126{
1127 SetStartLen(s._len);
1128 wmemcpy(_chars, s._chars, s._len + 1);
1129}
1130
1131UString &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
1147UString &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
1162UString &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
1179void 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
1194void 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
1256UString &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
1274void UString::Add_Space() { operator+=(L' '); }
1275void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
1276
1277void 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
1288UString &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
1297UString &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
1305UString &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
1318void UString::Add_UInt32(UInt32 v)
1319{
1320 Grow(10);
1321 _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars);
1322}
1323
1324void AString::Add_UInt64(UInt64 v)
1325{
1326 Grow(20);
1327 _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars);
1328}
1329
1330
1331int 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
1362int 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
1377int 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
1393void 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
1410void 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
1427void 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/*
1437void UString::Insert_wchar_t(unsigned index, wchar_t c)
1438{
1439 InsertSpace(index, 1);
1440 _chars[index] = c;
1441 _len++;
1442}
1443*/
1444
1445void 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
1456void 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
1467void 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'
1496void 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
1515void 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
1538void UString::Delete(unsigned index) throw()
1539{
1540 MoveItems(index, index + 1);
1541 _len--;
1542}
1543
1544void 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
1555void 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
1567void 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
1574void UString2::SetStartLen(unsigned len)
1575{
1576 _chars = 0;
1577 _chars = MY_STRING_NEW_wchar_t(len + 1);
1578 _len = len;
1579}
1580
1581
1582/*
1583UString2::UString2(wchar_t c)
1584{
1585 SetStartLen(1);
1586 wchar_t *chars = _chars;
1587 chars[0] = c;
1588 chars[1] = 0;
1589}
1590*/
1591
1592UString2::UString2(const wchar_t *s)
1593{
1594 unsigned len = MyStringLen(s);
1595 SetStartLen(len);
1596 wmemcpy(_chars, s, len + 1);
1597}
1598
1599UString2::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/*
1609UString2 &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
1626UString2 &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
1641void 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
1658UString2 &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
1675bool operator==(const UString2 &s1, const UString2 &s2)
1676{
1677 return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);
1678}
1679
1680bool 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
1687bool 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/*
1699int 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
1707static 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
1722AString fs2fas(CFSTR s)
1723{
1724 return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1725}
1726
1727FString fas2fs(const char *s)
1728{
1729 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1730}
1731
1732FString fas2fs(const AString &s)
1733{
1734 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1735}
1736
1737#endif // _UNICODE
1738
1739#else // USE_UNICODE_FSTRING
1740
1741UString fs2us(const FChar *s)
1742{
1743 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1744}
1745
1746UString fs2us(const FString &s)
1747{
1748 return MultiByteToUnicodeString(s, GetCurrentCodePage());
1749}
1750
1751FString us2fs(const wchar_t *s)
1752{
1753 return UnicodeStringToMultiByte(s, GetCurrentCodePage());
1754}
1755
1756#endif // USE_UNICODE_FSTRING