aboutsummaryrefslogtreecommitdiff
path: root/CPP/Common/MyString.h
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Common/MyString.h')
-rw-r--r--CPP/Common/MyString.h1012
1 files changed, 1012 insertions, 0 deletions
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
new file mode 100644
index 0000000..aa3c301
--- /dev/null
+++ b/CPP/Common/MyString.h
@@ -0,0 +1,1012 @@
1// Common/MyString.h
2
3#ifndef __COMMON_MY_STRING_H
4#define __COMMON_MY_STRING_H
5
6#include <string.h>
7
8#ifndef _WIN32
9#include <wctype.h>
10#include <wchar.h>
11#endif
12
13#include "MyWindows.h"
14#include "MyTypes.h"
15#include "MyVector.h"
16
17
18/* if (DEBUG_FSTRING_INHERITS_ASTRING is defined), then
19 FString inherits from AString, so we can find bugs related to FString at compile time.
20 DON'T define DEBUG_FSTRING_INHERITS_ASTRING in release code */
21
22// #define DEBUG_FSTRING_INHERITS_ASTRING
23
24#ifdef DEBUG_FSTRING_INHERITS_ASTRING
25class FString;
26#endif
27
28
29#ifdef _MSC_VER
30 #ifdef _NATIVE_WCHAR_T_DEFINED
31 #define MY_NATIVE_WCHAR_T_DEFINED
32 #endif
33#else
34 #define MY_NATIVE_WCHAR_T_DEFINED
35#endif
36
37/*
38 native support for wchar_t:
39 _MSC_VER == 1600 : /Zc:wchar_t is not supported
40 _MSC_VER == 1310 (VS2003)
41 ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
42 /Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
43 _MSC_VER > 1400 (VS2008+)
44 /Zc:wchar_t[-]
45 /Zc:wchar_t is on by default
46*/
47
48#ifdef _WIN32
49#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
50#else
51#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
52#endif
53
54inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
55inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
56
57inline unsigned MyStringLen(const char *s)
58{
59 unsigned i;
60 for (i = 0; s[i] != 0; i++);
61 return i;
62}
63
64inline void MyStringCopy(char *dest, const char *src)
65{
66 while ((*dest++ = *src++) != 0);
67}
68
69inline char *MyStpCpy(char *dest, const char *src)
70{
71 for (;;)
72 {
73 char c = *src;
74 *dest = c;
75 if (c == 0)
76 return dest;
77 src++;
78 dest++;
79 }
80}
81
82inline unsigned MyStringLen(const wchar_t *s)
83{
84 unsigned i;
85 for (i = 0; s[i] != 0; i++);
86 return i;
87}
88
89inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
90{
91 while ((*dest++ = *src++) != 0);
92}
93
94inline void MyStringCat(wchar_t *dest, const wchar_t *src)
95{
96 MyStringCopy(dest + MyStringLen(dest), src);
97}
98
99
100/*
101inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
102{
103 for (;;)
104 {
105 wchar_t c = *src;
106 *dest = c;
107 if (c == 0)
108 return dest;
109 src++;
110 dest++;
111 }
112}
113*/
114
115int FindCharPosInString(const char *s, char c) throw();
116int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
117
118#ifdef _WIN32
119 #ifndef _UNICODE
120 #define STRING_UNICODE_THROW
121 #endif
122#endif
123
124#ifndef STRING_UNICODE_THROW
125 #define STRING_UNICODE_THROW throw()
126#endif
127
128
129inline char MyCharUpper_Ascii(char c)
130{
131 if (c >= 'a' && c <= 'z')
132 return (char)((unsigned char)c - 0x20);
133 return c;
134}
135
136/*
137inline wchar_t MyCharUpper_Ascii(wchar_t c)
138{
139 if (c >= 'a' && c <= 'z')
140 return (wchar_t)(c - 0x20);
141 return c;
142}
143*/
144
145inline char MyCharLower_Ascii(char c)
146{
147 if (c >= 'A' && c <= 'Z')
148 return (char)((unsigned char)c + 0x20);
149 return c;
150}
151
152inline wchar_t MyCharLower_Ascii(wchar_t c)
153{
154 if (c >= 'A' && c <= 'Z')
155 return (wchar_t)(c + 0x20);
156 return c;
157}
158
159wchar_t MyCharUpper_WIN(wchar_t c) throw();
160
161inline wchar_t MyCharUpper(wchar_t c) throw()
162{
163 if (c < 'a') return c;
164 if (c <= 'z') return (wchar_t)(c - 0x20);
165 if (c <= 0x7F) return c;
166 #ifdef _WIN32
167 #ifdef _UNICODE
168 return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
169 #else
170 return (wchar_t)MyCharUpper_WIN(c);
171 #endif
172 #else
173 return (wchar_t)towupper((wint_t)c);
174 #endif
175}
176
177/*
178wchar_t MyCharLower_WIN(wchar_t c) throw();
179
180inline wchar_t MyCharLower(wchar_t c) throw()
181{
182 if (c < 'A') return c;
183 if (c <= 'Z') return (wchar_t)(c + 0x20);
184 if (c <= 0x7F) return c;
185 #ifdef _WIN32
186 #ifdef _UNICODE
187 return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
188 #else
189 return (wchar_t)MyCharLower_WIN(c);
190 #endif
191 #else
192 return (wchar_t)tolower(c);
193 #endif
194}
195*/
196
197// char *MyStringUpper(char *s) throw();
198// char *MyStringLower(char *s) throw();
199
200// void MyStringUpper_Ascii(char *s) throw();
201// void MyStringUpper_Ascii(wchar_t *s) throw();
202void MyStringLower_Ascii(char *s) throw();
203void MyStringLower_Ascii(wchar_t *s) throw();
204// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
205// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
206
207bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
208
209bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
210bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
211bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw();
212bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw();
213bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
214bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
215
216#define MyStringCompare(s1, s2) wcscmp(s1, s2)
217int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
218// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
219
220// ---------- ASCII ----------
221// char values in ASCII strings must be less then 128
222bool StringsAreEqual_Ascii(const char *u, const char *a) throw();
223bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
224bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
225bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
226bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
227
228#define MY_STRING_DELETE(_p_) delete []_p_;
229// #define MY_STRING_DELETE(_p_) my_delete(_p_);
230
231
232#define FORBID_STRING_OPS_2(cls, t) \
233 void Find(t) const; \
234 void Find(t, unsigned startIndex) const; \
235 void ReverseFind(t) const; \
236 void InsertAtFront(t); \
237 void RemoveChar(t); \
238 void Replace(t, t); \
239
240#define FORBID_STRING_OPS(cls, t) \
241 explicit cls(t); \
242 explicit cls(const t *); \
243 cls &operator=(t); \
244 cls &operator=(const t *); \
245 cls &operator+=(t); \
246 cls &operator+=(const t *); \
247 FORBID_STRING_OPS_2(cls, t) \
248
249/*
250 cls &operator+(t); \
251 cls &operator+(const t *); \
252*/
253
254#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
255#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
256#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
257
258class AString
259{
260 char *_chars;
261 unsigned _len;
262 unsigned _limit;
263
264 void MoveItems(unsigned dest, unsigned src)
265 {
266 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
267 }
268
269 void InsertSpace(unsigned &index, unsigned size);
270
271 void ReAlloc(unsigned newLimit);
272 void ReAlloc2(unsigned newLimit);
273 void SetStartLen(unsigned len);
274 void Grow_1();
275 void Grow(unsigned n);
276
277 AString(unsigned num, const char *s);
278 AString(unsigned num, const AString &s);
279 AString(const AString &s, char c); // it's for String + char
280 AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
281
282 friend AString operator+(const AString &s, char c) { return AString(s, c); }
283 // friend AString operator+(char c, const AString &s); // is not supported
284
285 friend AString operator+(const AString &s1, const AString &s2);
286 friend AString operator+(const AString &s1, const char *s2);
287 friend AString operator+(const char *s1, const AString &s2);
288
289 // ---------- forbidden functions ----------
290
291 #ifdef MY_NATIVE_WCHAR_T_DEFINED
292 FORBID_STRING_OPS_AString(wchar_t)
293 #endif
294
295 FORBID_STRING_OPS_AString(signed char)
296 FORBID_STRING_OPS_AString(unsigned char)
297 FORBID_STRING_OPS_AString(short)
298 FORBID_STRING_OPS_AString(unsigned short)
299 FORBID_STRING_OPS_AString(int)
300 FORBID_STRING_OPS_AString(unsigned)
301 FORBID_STRING_OPS_AString(long)
302 FORBID_STRING_OPS_AString(unsigned long)
303
304 #ifdef DEBUG_FSTRING_INHERITS_ASTRING
305 AString(const FString &s);
306 AString &operator=(const FString &s);
307 AString &operator+=(const FString &s);
308 #endif
309
310public:
311 explicit AString();
312 explicit AString(char c);
313 explicit AString(const char *s);
314 AString(const AString &s);
315 ~AString() { MY_STRING_DELETE(_chars); }
316
317 unsigned Len() const { return _len; }
318 bool IsEmpty() const { return _len == 0; }
319 void Empty() { _len = 0; _chars[0] = 0; }
320
321 operator const char *() const { return _chars; }
322 char *Ptr_non_const() const { return _chars; }
323 const char *Ptr() const { return _chars; }
324 const char *Ptr(unsigned pos) const { return _chars + pos; }
325 const char *RightPtr(unsigned num) const { return _chars + _len - num; }
326 char Back() const { return _chars[(size_t)_len - 1]; }
327
328 void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
329
330 char *GetBuf() { return _chars; }
331 /* GetBuf(minLen): provides the buffer that can store
332 at least (minLen) characters and additional null terminator.
333 9.35: GetBuf doesn't preserve old characters and terminator */
334 char *GetBuf(unsigned minLen)
335 {
336 if (minLen > _limit)
337 ReAlloc2(minLen);
338 return _chars;
339 }
340 char *GetBuf_SetEnd(unsigned minLen)
341 {
342 if (minLen > _limit)
343 ReAlloc2(minLen);
344 char *chars = _chars;
345 chars[minLen] = 0;
346 _len = minLen;
347 return chars;
348 }
349
350 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
351 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
352 void ReleaseBuf_CalcLen(unsigned maxLen)
353 {
354 char *chars = _chars;
355 chars[maxLen] = 0;
356 _len = MyStringLen(chars);
357 }
358
359 AString &operator=(char c);
360 AString &operator=(const char *s);
361 AString &operator=(const AString &s);
362 void SetFromWStr_if_Ascii(const wchar_t *s);
363 // void SetFromBstr_if_Ascii(BSTR s);
364
365 AString &operator+=(char c)
366 {
367 if (_limit == _len)
368 Grow_1();
369 unsigned len = _len;
370 char *chars = _chars;
371 chars[len++] = c;
372 chars[len] = 0;
373 _len = len;
374 return *this;
375 }
376
377 void Add_Space();
378 void Add_Space_if_NotEmpty();
379 void Add_OptSpaced(const char *s);
380 void Add_LF();
381 void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
382
383 AString &operator+=(const char *s);
384 AString &operator+=(const AString &s);
385
386 void Add_UInt32(UInt32 v);
387 void Add_UInt64(UInt64 v);
388
389 void SetFrom(const char *s, unsigned len); // no check
390 void SetFrom_CalcLen(const char *s, unsigned len);
391
392 AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
393 AString Left(unsigned count) const { return AString(count, *this); }
394
395 // void MakeUpper() { MyStringUpper(_chars); }
396 // void MakeLower() { MyStringLower(_chars); }
397 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
398
399
400 bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
401 bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
402 // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
403 // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
404 // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
405 // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
406 bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
407 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
408
409 bool IsAscii() const
410 {
411 unsigned len = Len();
412 const char *s = _chars;
413 for (unsigned i = 0; i < len; i++)
414 if ((unsigned char)s[i] >= 0x80)
415 return false;
416 return true;
417 }
418 int Find(char c) const { return FindCharPosInString(_chars, c); }
419 int Find(char c, unsigned startIndex) const
420 {
421 int pos = FindCharPosInString(_chars + startIndex, c);
422 return pos < 0 ? -1 : (int)startIndex + pos;
423 }
424
425 int ReverseFind(char c) const throw();
426 int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
427 int ReverseFind_PathSepar() const throw();
428
429 int Find(const char *s) const { return Find(s, 0); }
430 int Find(const char *s, unsigned startIndex) const throw();
431
432 void TrimLeft() throw();
433 void TrimRight() throw();
434 void Trim()
435 {
436 TrimRight();
437 TrimLeft();
438 }
439
440 void InsertAtFront(char c);
441 // void Insert(unsigned index, char c);
442 void Insert(unsigned index, const char *s);
443 void Insert(unsigned index, const AString &s);
444
445 void RemoveChar(char ch) throw();
446
447 void Replace(char oldChar, char newChar) throw();
448 void Replace(const AString &oldString, const AString &newString);
449
450 void Delete(unsigned index) throw();
451 void Delete(unsigned index, unsigned count) throw();
452 void DeleteFrontal(unsigned num) throw();
453 void DeleteBack() { _chars[--_len] = 0; }
454 void DeleteFrom(unsigned index)
455 {
456 if (index < _len)
457 {
458 _len = index;
459 _chars[index] = 0;
460 }
461 }
462
463 void Wipe_and_Empty()
464 {
465 if (_chars)
466 {
467 memset(_chars, 0, (_limit + 1) * sizeof(*_chars));
468 _len = 0;
469 }
470 }
471};
472
473
474class AString_Wipe: public AString
475{
476 CLASS_NO_COPY(AString_Wipe)
477public:
478 AString_Wipe(): AString() {}
479 // AString_Wipe(const AString &s): AString(s) {}
480 // AString_Wipe &operator=(const AString &s) { AString::operator=(s); return *this; }
481 // AString_Wipe &operator=(const char *s) { AString::operator=(s); return *this; }
482 ~AString_Wipe() { Wipe_and_Empty(); }
483};
484
485
486bool operator<(const AString &s1, const AString &s2);
487bool operator>(const AString &s1, const AString &s2);
488
489/*
490bool operator==(const AString &s1, const AString &s2);
491bool operator==(const AString &s1, const char *s2);
492bool operator==(const char *s1, const AString &s2);
493
494bool operator!=(const AString &s1, const AString &s2);
495bool operator!=(const AString &s1, const char *s2);
496bool operator!=(const char *s1, const AString &s2);
497*/
498
499inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
500inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
501inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
502
503inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
504inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
505inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
506
507// ---------- forbidden functions ----------
508
509void operator==(char c1, const AString &s2);
510void operator==(const AString &s1, char c2);
511
512void operator+(char c, const AString &s); // this function can be OK, but we don't use it
513
514void operator+(const AString &s, int c);
515void operator+(const AString &s, unsigned c);
516void operator+(int c, const AString &s);
517void operator+(unsigned c, const AString &s);
518void operator-(const AString &s, int c);
519void operator-(const AString &s, unsigned c);
520
521
522class UString
523{
524 wchar_t *_chars;
525 unsigned _len;
526 unsigned _limit;
527
528 void MoveItems(unsigned dest, unsigned src)
529 {
530 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
531 }
532
533 void InsertSpace(unsigned index, unsigned size);
534
535 void ReAlloc(unsigned newLimit);
536 void ReAlloc2(unsigned newLimit);
537 void SetStartLen(unsigned len);
538 void Grow_1();
539 void Grow(unsigned n);
540
541 UString(unsigned num, const wchar_t *s); // for Mid
542 UString(unsigned num, const UString &s); // for Left
543 UString(const UString &s, wchar_t c); // it's for String + char
544 UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
545
546 friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); }
547 // friend UString operator+(wchar_t c, const UString &s); // is not supported
548
549 friend UString operator+(const UString &s1, const UString &s2);
550 friend UString operator+(const UString &s1, const wchar_t *s2);
551 friend UString operator+(const wchar_t *s1, const UString &s2);
552
553 // ---------- forbidden functions ----------
554
555 FORBID_STRING_OPS_UString(signed char)
556 FORBID_STRING_OPS_UString(unsigned char)
557 FORBID_STRING_OPS_UString(short)
558
559 #ifdef MY_NATIVE_WCHAR_T_DEFINED
560 FORBID_STRING_OPS_UString(unsigned short)
561 #endif
562
563 FORBID_STRING_OPS_UString(int)
564 FORBID_STRING_OPS_UString(unsigned)
565 FORBID_STRING_OPS_UString(long)
566 FORBID_STRING_OPS_UString(unsigned long)
567
568 FORBID_STRING_OPS_2(UString, char)
569
570 #ifdef DEBUG_FSTRING_INHERITS_ASTRING
571 UString(const FString &s);
572 UString &operator=(const FString &s);
573 UString &operator+=(const FString &s);
574 #endif
575
576public:
577 UString();
578 explicit UString(wchar_t c);
579 explicit UString(char c);
580 explicit UString(const char *s);
581 explicit UString(const AString &s);
582 UString(const wchar_t *s);
583 UString(const UString &s);
584 ~UString() { MY_STRING_DELETE(_chars); }
585
586 unsigned Len() const { return _len; }
587 bool IsEmpty() const { return _len == 0; }
588 void Empty() { _len = 0; _chars[0] = 0; }
589
590 operator const wchar_t *() const { return _chars; }
591 wchar_t *Ptr_non_const() const { return _chars; }
592 const wchar_t *Ptr() const { return _chars; }
593 const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
594 const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
595 wchar_t Back() const { return _chars[(size_t)_len - 1]; }
596
597 void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
598
599 wchar_t *GetBuf() { return _chars; }
600
601 wchar_t *GetBuf(unsigned minLen)
602 {
603 if (minLen > _limit)
604 ReAlloc2(minLen);
605 return _chars;
606 }
607 wchar_t *GetBuf_SetEnd(unsigned minLen)
608 {
609 if (minLen > _limit)
610 ReAlloc2(minLen);
611 wchar_t *chars = _chars;
612 chars[minLen] = 0;
613 _len = minLen;
614 return chars;
615 }
616
617 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
618 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
619 void ReleaseBuf_CalcLen(unsigned maxLen)
620 {
621 wchar_t *chars = _chars;
622 chars[maxLen] = 0;
623 _len = MyStringLen(chars);
624 }
625
626 UString &operator=(wchar_t c);
627 UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
628 UString &operator=(const wchar_t *s);
629 UString &operator=(const UString &s);
630 void SetFrom(const wchar_t *s, unsigned len); // no check
631 void SetFromBstr(LPCOLESTR s);
632 UString &operator=(const char *s);
633 UString &operator=(const AString &s) { return operator=(s.Ptr()); }
634
635 UString &operator+=(wchar_t c)
636 {
637 if (_limit == _len)
638 Grow_1();
639 unsigned len = _len;
640 wchar_t *chars = _chars;
641 chars[len++] = c;
642 chars[len] = 0;
643 _len = len;
644 return *this;
645 }
646
647 UString &operator+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
648
649 void Add_Space();
650 void Add_Space_if_NotEmpty();
651 void Add_LF();
652 void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
653
654 UString &operator+=(const wchar_t *s);
655 UString &operator+=(const UString &s);
656 UString &operator+=(const char *s);
657 UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
658
659 void Add_UInt32(UInt32 v);
660 void Add_UInt64(UInt64 v);
661
662 UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
663 UString Left(unsigned count) const { return UString(count, *this); }
664
665 // void MakeUpper() { MyStringUpper(_chars); }
666 // void MakeUpper() { MyStringUpper_Ascii(_chars); }
667 // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
668 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
669
670 bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
671 bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
672 bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
673 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
674 // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
675 // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
676 // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
677 bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
678 bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
679 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
680
681 bool IsAscii() const
682 {
683 unsigned len = Len();
684 const wchar_t *s = _chars;
685 for (unsigned i = 0; i < len; i++)
686 if (s[i] >= 0x80)
687 return false;
688 return true;
689 }
690 int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
691 int Find(wchar_t c, unsigned startIndex) const
692 {
693 int pos = FindCharPosInString(_chars + startIndex, c);
694 return pos < 0 ? -1 : (int)startIndex + pos;
695 }
696
697 int ReverseFind(wchar_t c) const throw();
698 int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
699 int ReverseFind_PathSepar() const throw();
700
701 int Find(const wchar_t *s) const { return Find(s, 0); }
702 int Find(const wchar_t *s, unsigned startIndex) const throw();
703
704 void TrimLeft() throw();
705 void TrimRight() throw();
706 void Trim()
707 {
708 TrimRight();
709 TrimLeft();
710 }
711
712 void InsertAtFront(wchar_t c);
713 // void Insert_wchar_t(unsigned index, wchar_t c);
714 void Insert(unsigned index, const wchar_t *s);
715 void Insert(unsigned index, const UString &s);
716
717 void RemoveChar(wchar_t ch) throw();
718
719 void Replace(wchar_t oldChar, wchar_t newChar) throw();
720 void Replace(const UString &oldString, const UString &newString);
721
722 void Delete(unsigned index) throw();
723 void Delete(unsigned index, unsigned count) throw();
724 void DeleteFrontal(unsigned num) throw();
725 void DeleteBack() { _chars[--_len] = 0; }
726 void DeleteFrom(unsigned index)
727 {
728 if (index < _len)
729 {
730 _len = index;
731 _chars[index] = 0;
732 }
733 }
734
735 void Wipe_and_Empty()
736 {
737 if (_chars)
738 {
739 memset(_chars, 0, (_limit + 1) * sizeof(*_chars));
740 _len = 0;
741 }
742 }
743};
744
745
746class UString_Wipe: public UString
747{
748 CLASS_NO_COPY(UString_Wipe)
749public:
750 UString_Wipe(): UString() {}
751 // UString_Wipe(const UString &s): UString(s) {}
752 // UString_Wipe &operator=(const UString &s) { UString::operator=(s); return *this; }
753 // UString_Wipe &operator=(const wchar_t *s) { UString::operator=(s); return *this; }
754 ~UString_Wipe() { Wipe_and_Empty(); }
755};
756
757
758bool operator<(const UString &s1, const UString &s2);
759bool operator>(const UString &s1, const UString &s2);
760
761inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
762inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
763inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
764
765inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
766inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
767inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
768
769
770// ---------- forbidden functions ----------
771
772void operator==(wchar_t c1, const UString &s2);
773void operator==(const UString &s1, wchar_t c2);
774
775void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
776
777void operator+(const AString &s1, const UString &s2);
778void operator+(const UString &s1, const AString &s2);
779
780void operator+(const UString &s1, const char *s2);
781void operator+(const char *s1, const UString &s2);
782
783void operator+(const UString &s, char c);
784void operator+(const UString &s, unsigned char c);
785void operator+(char c, const UString &s);
786void operator+(unsigned char c, const UString &s);
787void operator-(const UString &s1, wchar_t c);
788
789#ifdef _WIN32
790// can we forbid these functions, if wchar_t is 32-bit ?
791void operator+(const UString &s, int c);
792void operator+(const UString &s, unsigned c);
793void operator+(int c, const UString &s);
794void operator+(unsigned c, const UString &s);
795void operator-(const UString &s1, int c);
796void operator-(const UString &s1, unsigned c);
797#endif
798
799
800
801
802
803
804
805class UString2
806{
807 wchar_t *_chars;
808 unsigned _len;
809
810 void ReAlloc2(unsigned newLimit);
811 void SetStartLen(unsigned len);
812
813 // ---------- forbidden functions ----------
814
815 FORBID_STRING_OPS_UString2(char)
816 FORBID_STRING_OPS_UString2(signed char)
817 FORBID_STRING_OPS_UString2(unsigned char)
818 FORBID_STRING_OPS_UString2(short)
819
820 UString2 &operator=(wchar_t c);
821
822 UString2(const AString &s);
823 UString2 &operator=(const AString &s);
824 UString2 &operator+=(const AString &s);
825
826 #ifdef DEBUG_FSTRING_INHERITS_ASTRING
827 UString2(const FString &s);
828 UString2 &operator=(const FString &s);
829 UString2 &operator+=(const FString &s);
830 #endif
831
832public:
833 UString2(): _chars(NULL), _len(0) {}
834 UString2(const wchar_t *s);
835 UString2(const UString2 &s);
836 ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
837
838 unsigned Len() const { return _len; }
839 bool IsEmpty() const { return _len == 0; }
840 // void Empty() { _len = 0; _chars[0] = 0; }
841
842 // operator const wchar_t *() const { return _chars; }
843 const wchar_t *GetRawPtr() const { return _chars; }
844
845 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
846
847 wchar_t *GetBuf(unsigned minLen)
848 {
849 if (!_chars || minLen > _len)
850 ReAlloc2(minLen);
851 return _chars;
852 }
853 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
854
855 UString2 &operator=(const wchar_t *s);
856 UString2 &operator=(const UString2 &s);
857 void SetFromAscii(const char *s);
858};
859
860bool operator==(const UString2 &s1, const UString2 &s2);
861bool operator==(const UString2 &s1, const wchar_t *s2);
862bool operator==(const wchar_t *s1, const UString2 &s2);
863
864inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
865inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
866inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
867
868
869// ---------- forbidden functions ----------
870
871void operator==(wchar_t c1, const UString2 &s2);
872void operator==(const UString2 &s1, wchar_t c2);
873bool operator<(const UString2 &s1, const UString2 &s2);
874bool operator>(const UString2 &s1, const UString2 &s2);
875
876void operator+(const UString2 &s1, const UString2 &s2);
877void operator+(const UString2 &s1, const wchar_t *s2);
878void operator+(const wchar_t *s1, const UString2 &s2);
879void operator+(wchar_t c, const UString2 &s);
880void operator+(const UString2 &s, wchar_t c);
881void operator+(const UString2 &s, char c);
882void operator+(const UString2 &s, unsigned char c);
883void operator+(char c, const UString2 &s);
884void operator+(unsigned char c, const UString2 &s);
885void operator-(const UString2 &s1, wchar_t c);
886
887
888
889
890
891
892typedef CObjectVector<AString> AStringVector;
893typedef CObjectVector<UString> UStringVector;
894
895#ifdef _UNICODE
896 typedef UString CSysString;
897#else
898 typedef AString CSysString;
899#endif
900
901typedef CObjectVector<CSysString> CSysStringVector;
902
903
904// ---------- FString ----------
905
906#ifndef DEBUG_FSTRING_INHERITS_ASTRING
907#ifdef _WIN32
908 #define USE_UNICODE_FSTRING
909#endif
910#endif
911
912#ifdef USE_UNICODE_FSTRING
913
914 #define __FTEXT(quote) L##quote
915
916 typedef wchar_t FChar;
917 typedef UString FString;
918
919 #define fs2us(_x_) (_x_)
920 #define us2fs(_x_) (_x_)
921 FString fas2fs(const char *s);
922 FString fas2fs(const AString &s);
923 AString fs2fas(const FChar *s);
924
925#else
926
927 #define __FTEXT(quote) quote
928
929 typedef char FChar;
930
931 #ifdef DEBUG_FSTRING_INHERITS_ASTRING
932
933 class FString: public AString
934 {
935 // FString &operator=(const char *s);
936 FString &operator=(const AString &s);
937 // FString &operator+=(const AString &s);
938 public:
939 FString(const AString &s): AString(s.Ptr()) {}
940 FString(const FString &s): AString(s.Ptr()) {}
941 FString(const char *s): AString(s) {}
942 FString() {}
943 FString &operator=(const FString &s) { AString::operator=((const AString &)s); return *this; }
944 FString &operator=(char c) { AString::operator=(c); return *this; }
945 FString &operator+=(char c) { AString::operator+=(c); return *this; }
946 FString &operator+=(const FString &s) { AString::operator+=((const AString &)s); return *this; }
947 FString Left(unsigned count) const { return FString(AString::Left(count)); }
948 };
949 void operator+(const AString &s1, const FString &s2);
950 void operator+(const FString &s1, const AString &s2);
951
952 inline FString operator+(const FString &s1, const FString &s2)
953 {
954 AString s =(const AString &)s1 + (const AString &)s2;
955 return FString(s.Ptr());
956 // return FString((const AString &)s1 + (const AString &)s2);
957 }
958 inline FString operator+(const FString &s1, const FChar *s2)
959 {
960 return s1 + (FString)s2;
961 }
962 /*
963 inline FString operator+(const FChar *s1, const FString &s2)
964 {
965 return (FString)s1 + s2;
966 }
967 */
968
969 inline FString fas2fs(const char *s) { return FString(s); }
970
971 #else // DEBUG_FSTRING_INHERITS_ASTRING
972 typedef AString FString;
973 #define fas2fs(_x_) (_x_)
974 #endif // DEBUG_FSTRING_INHERITS_ASTRING
975
976 UString fs2us(const FChar *s);
977 UString fs2us(const FString &s);
978 FString us2fs(const wchar_t *s);
979 #define fs2fas(_x_) (_x_)
980
981#endif
982
983#define FTEXT(quote) __FTEXT(quote)
984
985#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
986#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
987
988// #define FCHAR_ANY_MASK FTEXT('*')
989// #define FSTRING_ANY_MASK FTEXT("*")
990
991typedef const FChar *CFSTR;
992
993typedef CObjectVector<FString> FStringVector;
994
995#endif
996
997
998
999#if defined(_WIN32)
1000 // #include <wchar.h>
1001 // WCHAR_MAX is defined as ((wchar_t)-1)
1002 #define _WCHART_IS_16BIT 1
1003#elif (defined(WCHAR_MAX) && (WCHAR_MAX <= 0xffff)) \
1004 || (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ == 2))
1005 #define _WCHART_IS_16BIT 1
1006#endif
1007
1008#if WCHAR_PATH_SEPARATOR == L'\\'
1009// WSL scheme
1010#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT ((wchar_t)((unsigned)(0xF000) + (unsigned)'\\'))
1011// #define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT '_'
1012#endif