1// Common/String.h
2
3#ifndef __COMMON_STRING_H
4#define __COMMON_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#ifdef _WIN32
18#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
19#else
20#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
21#endif
22
23inline bool IsPathSepar(char    c) { return IS_PATH_SEPAR(c); }
24inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
25
26inline unsigned MyStringLen(const char *s)
27{
28  unsigned i;
29  for (i = 0; s[i] != 0; i++);
30  return i;
31}
32
33inline void MyStringCopy(char *dest, const char *src)
34{
35  while ((*dest++ = *src++) != 0);
36}
37
38inline char *MyStpCpy(char *dest, const char *src)
39{
40  for (;;)
41  {
42    char c = *src;
43    *dest = c;
44    if (c == 0)
45      return dest;
46    src++;
47    dest++;
48  }
49}
50
51inline unsigned MyStringLen(const wchar_t *s)
52{
53  unsigned i;
54  for (i = 0; s[i] != 0; i++);
55  return i;
56}
57
58inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
59{
60  while ((*dest++ = *src++) != 0);
61}
62
63/*
64inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
65{
66  for (;;)
67  {
68    wchar_t c = *src;
69    *dest = c;
70    if (c == 0)
71      return dest;
72    src++;
73    dest++;
74  }
75}
76*/
77
78int FindCharPosInString(const char *s, char c) throw();
79int FindCharPosInString(const wchar_t *s, wchar_t c) throw();
80
81#ifdef _WIN32
82  #ifndef _UNICODE
83    #define STRING_UNICODE_THROW
84  #endif
85#endif
86
87#ifndef STRING_UNICODE_THROW
88  #define STRING_UNICODE_THROW throw()
89#endif
90
91/*
92inline char MyCharUpper_Ascii(char c)
93{
94  if (c >= 'a' && c <= 'z')
95    return (char)(c - 0x20);
96  return c;
97}
98inline wchar_t MyCharUpper_Ascii(wchar_t c)
99{
100  if (c >= 'a' && c <= 'z')
101    return (wchar_t)(c - 0x20);
102  return c;
103}
104*/
105
106inline char MyCharLower_Ascii(char c)
107{
108  if (c >= 'A' && c <= 'Z')
109    return (char)((unsigned char)c + 0x20);
110  return c;
111}
112
113inline wchar_t MyCharLower_Ascii(wchar_t c)
114{
115  if (c >= 'A' && c <= 'Z')
116    return (wchar_t)(c + 0x20);
117  return c;
118}
119
120wchar_t MyCharUpper_WIN(wchar_t c) throw();
121
122inline wchar_t MyCharUpper(wchar_t c) throw()
123{
124  if (c < 'a') return c;
125  if (c <= 'z') return (wchar_t)(c - 0x20);
126  if (c <= 0x7F) return c;
127  #ifdef _WIN32
128    #ifdef _UNICODE
129      return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);
130    #else
131      return (wchar_t)MyCharUpper_WIN(c);
132    #endif
133  #else
134    return (wchar_t)towupper(c);
135  #endif
136}
137
138/*
139wchar_t MyCharLower_WIN(wchar_t c) throw();
140
141inline wchar_t MyCharLower(wchar_t c) throw()
142{
143  if (c < 'A') return c;
144  if (c <= 'Z') return (wchar_t)(c + 0x20);
145  if (c <= 0x7F) return c;
146  #ifdef _WIN32
147    #ifdef _UNICODE
148      return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);
149    #else
150      return (wchar_t)MyCharLower_WIN(c);
151    #endif
152  #else
153    return (wchar_t)tolower(c);
154  #endif
155}
156*/
157
158// char *MyStringUpper(char *s) throw();
159// char *MyStringLower(char *s) throw();
160
161// void MyStringUpper_Ascii(wchar_t *s) throw();
162void MyStringLower_Ascii(char *s) throw();
163void MyStringLower_Ascii(wchar_t *s) throw();
164// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW;
165// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW;
166
167bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
168
169bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
170bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
171bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
172
173int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw();
174// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw();
175
176// ---------- ASCII ----------
177// char values in ASCII strings must be less then 128
178bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
179bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
180bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
181bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw();
182
183#define MY_STRING_DELETE(_p_) delete []_p_;
184// #define MY_STRING_DELETE(_p_) my_delete(_p_);
185
186class AString
187{
188  char *_chars;
189  unsigned _len;
190  unsigned _limit;
191
192  void MoveItems(unsigned dest, unsigned src)
193  {
194    memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char));
195  }
196
197  void InsertSpace(unsigned &index, unsigned size);
198
199  void ReAlloc(unsigned newLimit);
200  void ReAlloc2(unsigned newLimit);
201  void SetStartLen(unsigned len);
202  void Grow_1();
203  void Grow(unsigned n);
204
205  // AString(unsigned num, const char *s);
206  AString(unsigned num, const AString &s);
207  AString(const AString &s, char c); // it's for String + char
208  AString(const char *s1, unsigned num1, const char *s2, unsigned num2);
209
210  friend AString operator+(const AString &s, char c) { return AString(s, c); } ;
211  // friend AString operator+(char c, const AString &s); // is not supported
212
213  friend AString operator+(const AString &s1, const AString &s2);
214  friend AString operator+(const AString &s1, const char    *s2);
215  friend AString operator+(const char    *s1, const AString &s2);
216
217  // ---------- forbidden functions ----------
218  AString &operator+=(wchar_t c);
219  AString &operator=(wchar_t c);
220  AString(wchar_t c);
221  void Find(wchar_t c) const;
222  void Find(wchar_t c, unsigned startIndex) const;
223  void ReverseFind(wchar_t c) const;
224  void InsertAtFront(wchar_t c);
225  void RemoveChar(wchar_t ch);
226  void Replace(wchar_t oldChar, wchar_t newChar);
227
228public:
229  AString();
230  AString(char c);
231  AString(const char *s);
232  AString(const AString &s);
233  ~AString() { MY_STRING_DELETE(_chars); }
234
235  unsigned Len() const { return _len; }
236  bool IsEmpty() const { return _len == 0; }
237  void Empty() { _len = 0; _chars[0] = 0; }
238
239  operator const char *() const { return _chars; }
240  const char *Ptr() const { return _chars; }
241  const char *Ptr(unsigned pos) const { return _chars + pos; }
242  const char *RightPtr(unsigned num) const { return _chars + _len - num; }
243  char Back() const { return _chars[_len - 1]; }
244
245  void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
246
247  /* GetBuf(minLen): provides the buffer that can store
248     at least (minLen) characters and additional null terminator.
249     9.35: GetBuf doesn't preserve old characters and terminator */
250  char *GetBuf(unsigned minLen)
251  {
252    if (minLen > _limit)
253      ReAlloc2(minLen);
254    return _chars;
255  }
256  char *GetBuf_SetEnd(unsigned minLen)
257  {
258    if (minLen > _limit)
259      ReAlloc2(minLen);
260    char *chars = _chars;
261    chars[minLen] = 0;
262    _len = minLen;
263    return chars;
264  }
265
266  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
267  void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
268  void ReleaseBuf_CalcLen(unsigned maxLen)
269  {
270    char *chars = _chars;
271    chars[maxLen] = 0;
272    _len = MyStringLen(chars);
273  }
274
275  AString &operator=(char c);
276  AString &operator=(const char *s);
277  AString &operator=(const AString &s);
278  void SetFromWStr_if_Ascii(const wchar_t *s);
279  // void SetFromBstr_if_Ascii(BSTR s);
280
281  AString &operator+=(char c)
282  {
283    if (_limit == _len)
284      Grow_1();
285    unsigned len = _len;
286    char *chars = _chars;
287    chars[len++] = c;
288    chars[len] = 0;
289    _len = len;
290    return *this;
291  }
292
293  void Add_Space();
294  void Add_Space_if_NotEmpty();
295  void Add_LF();
296  void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
297
298  AString &operator+=(const char *s);
299  AString &operator+=(const AString &s);
300  void AddAscii(const char *s) { operator+=(s); }
301
302  void SetFrom(const char *s, unsigned len); // no check
303  void SetFrom_CalcLen(const char *s, unsigned len);
304  // void SetFromAscii(const char *s) { operator+=(s); }
305
306  AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
307  AString Left(unsigned count) const { return AString(count, *this); }
308
309  // void MakeUpper() { MyStringUpper(_chars); }
310  // void MakeLower() { MyStringLower(_chars); }
311  void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
312
313
314  bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
315  bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
316  // int Compare(const char *s) const { return MyStringCompare(_chars, s); }
317  // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); }
318  // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); }
319  // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
320  bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
321  bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
322
323  bool IsAscii() const
324  {
325    unsigned len = Len();
326    const char *s = _chars;
327    for (unsigned i = 0; i < len; i++)
328      if ((unsigned char)s[i] >= 0x80)
329        return false;
330    return true;
331  }
332  int Find(char c) const { return FindCharPosInString(_chars, c); }
333  int Find(char c, unsigned startIndex) const
334  {
335    int pos = FindCharPosInString(_chars + startIndex, c);
336    return pos < 0 ? -1 : (int)startIndex + pos;
337  }
338
339  int ReverseFind(char c) const throw();
340  int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
341  int ReverseFind_PathSepar() const throw();
342
343  int Find(const char *s) const { return Find(s, 0); }
344  int Find(const char *s, unsigned startIndex) const throw();
345
346  void TrimLeft() throw();
347  void TrimRight() throw();
348  void Trim()
349  {
350    TrimRight();
351    TrimLeft();
352  }
353
354  void InsertAtFront(char c);
355  // void Insert(unsigned index, char c);
356  void Insert(unsigned index, const char *s);
357  void Insert(unsigned index, const AString &s);
358
359  void RemoveChar(char ch) throw();
360
361  void Replace(char oldChar, char newChar) throw();
362  void Replace(const AString &oldString, const AString &newString);
363
364  void Delete(unsigned index) throw();
365  void Delete(unsigned index, unsigned count) throw();
366  void DeleteFrontal(unsigned num) throw();
367  void DeleteBack() { _chars[--_len] = 0; }
368  void DeleteFrom(unsigned index)
369  {
370    if (index < _len)
371    {
372      _len = index;
373      _chars[index] = 0;
374    }
375  }
376};
377
378bool operator<(const AString &s1, const AString &s2);
379bool operator>(const AString &s1, const AString &s2);
380
381/*
382bool operator==(const AString &s1, const AString &s2);
383bool operator==(const AString &s1, const char    *s2);
384bool operator==(const char    *s1, const AString &s2);
385
386bool operator!=(const AString &s1, const AString &s2);
387bool operator!=(const AString &s1, const char    *s2);
388bool operator!=(const char    *s1, const AString &s2);
389*/
390
391inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
392inline bool operator==(const AString &s1, const char    *s2) { return strcmp(s1, s2) == 0; }
393inline bool operator==(const char    *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
394
395inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
396inline bool operator!=(const AString &s1, const char    *s2) { return strcmp(s1, s2) != 0; }
397inline bool operator!=(const char    *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
398
399// ---------- forbidden functions ----------
400
401void operator==(char c1, const AString &s2);
402void operator==(const AString &s1, char c2);
403
404void operator+(char c, const AString &s); // this function can be OK, but we don't use it
405
406void operator+(const AString &s, int c);
407void operator+(const AString &s, unsigned c);
408void operator+(int c, const AString &s);
409void operator+(unsigned c, const AString &s);
410void operator-(const AString &s, int c);
411void operator-(const AString &s, unsigned c);
412
413
414class UString
415{
416  wchar_t *_chars;
417  unsigned _len;
418  unsigned _limit;
419
420  void MoveItems(unsigned dest, unsigned src)
421  {
422    memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t));
423  }
424
425  void InsertSpace(unsigned index, unsigned size);
426
427  void ReAlloc(unsigned newLimit);
428  void ReAlloc2(unsigned newLimit);
429  void SetStartLen(unsigned len);
430  void Grow_1();
431  void Grow(unsigned n);
432
433  UString(unsigned num, const wchar_t *s); // for Mid
434  UString(unsigned num, const UString &s); // for Left
435  UString(const UString &s, wchar_t c); // it's for String + char
436  UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2);
437
438  friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ;
439  // friend UString operator+(wchar_t c, const UString &s); // is not supported
440
441  friend UString operator+(const UString &s1, const UString &s2);
442  friend UString operator+(const UString &s1, const wchar_t *s2);
443  friend UString operator+(const wchar_t *s1, const UString &s2);
444
445  // ---------- forbidden functions ----------
446
447  UString &operator+=(char c);
448  UString &operator+=(unsigned char c);
449  UString &operator=(char c);
450  UString &operator=(unsigned char c);
451  UString(char c);
452  UString(unsigned char c);
453  void Find(char c) const;
454  void Find(unsigned char c) const;
455  void Find(char c, unsigned startIndex) const;
456  void Find(unsigned char c, unsigned startIndex) const;
457  void ReverseFind(char c) const;
458  void ReverseFind(unsigned char c) const;
459  void InsertAtFront(char c);
460  void InsertAtFront(unsigned char c);
461  void RemoveChar(char ch);
462  void RemoveChar(unsigned char ch);
463  void Replace(char oldChar, char newChar);
464  void Replace(unsigned char oldChar, unsigned char newChar);
465
466public:
467  UString();
468  UString(wchar_t c);
469  UString(const wchar_t *s);
470  UString(const UString &s);
471  ~UString() { MY_STRING_DELETE(_chars); }
472
473  unsigned Len() const { return _len; }
474  bool IsEmpty() const { return _len == 0; }
475  void Empty() { _len = 0; _chars[0] = 0; }
476
477  operator const wchar_t *() const { return _chars; }
478  const wchar_t *Ptr() const { return _chars; }
479  const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
480  const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
481  wchar_t Back() const { return _chars[_len - 1]; }
482
483  void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
484
485  wchar_t *GetBuf(unsigned minLen)
486  {
487    if (minLen > _limit)
488      ReAlloc2(minLen);
489    return _chars;
490  }
491  wchar_t *GetBuf_SetEnd(unsigned minLen)
492  {
493    if (minLen > _limit)
494      ReAlloc2(minLen);
495    wchar_t *chars = _chars;
496    chars[minLen] = 0;
497    _len = minLen;
498    return chars;
499  }
500
501  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
502  void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
503  void ReleaseBuf_CalcLen(unsigned maxLen)
504  {
505    wchar_t *chars = _chars;
506    chars[maxLen] = 0;
507    _len = MyStringLen(chars);
508  }
509
510  UString &operator=(wchar_t c);
511  UString &operator=(const wchar_t *s);
512  UString &operator=(const UString &s);
513  void SetFromBstr(BSTR s);
514
515  UString &operator+=(wchar_t c)
516  {
517    if (_limit == _len)
518      Grow_1();
519    unsigned len = _len;
520    wchar_t *chars = _chars;
521    chars[len++] = c;
522    chars[len] = 0;
523    _len = len;
524    return *this;
525  }
526
527  void Add_Space();
528  void Add_Space_if_NotEmpty();
529  void Add_LF();
530  void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
531
532  UString &operator+=(const wchar_t *s);
533  UString &operator+=(const UString &s);
534
535  void SetFrom(const wchar_t *s, unsigned len); // no check
536
537  void SetFromAscii(const char *s);
538  void AddAscii(const char *s);
539
540  UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
541  UString Left(unsigned count) const { return UString(count, *this); }
542
543  // void MakeUpper() { MyStringUpper(_chars); }
544  // void MakeUpper() { MyStringUpper_Ascii(_chars); }
545  // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); }
546  void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
547
548  bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
549  bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
550  bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
551  int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
552  // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); }
553  // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); }
554  // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); }
555  bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
556  bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
557  bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
558
559  bool IsAscii() const
560  {
561    unsigned len = Len();
562    const wchar_t *s = _chars;
563    for (unsigned i = 0; i < len; i++)
564      if (s[i] >= 0x80)
565        return false;
566    return true;
567  }
568  int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
569  int Find(wchar_t c, unsigned startIndex) const
570  {
571    int pos = FindCharPosInString(_chars + startIndex, c);
572    return pos < 0 ? -1 : (int)startIndex + pos;
573  }
574
575  int ReverseFind(wchar_t c) const throw();
576  int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
577  int ReverseFind_PathSepar() const throw();
578
579  int Find(const wchar_t *s) const { return Find(s, 0); }
580  int Find(const wchar_t *s, unsigned startIndex) const throw();
581
582  void TrimLeft() throw();
583  void TrimRight() throw();
584  void Trim()
585  {
586    TrimRight();
587    TrimLeft();
588  }
589
590  void InsertAtFront(wchar_t c);
591  // void Insert(unsigned index, wchar_t c);
592  void Insert(unsigned index, const wchar_t *s);
593  void Insert(unsigned index, const UString &s);
594
595  void RemoveChar(wchar_t ch) throw();
596
597  void Replace(wchar_t oldChar, wchar_t newChar) throw();
598  void Replace(const UString &oldString, const UString &newString);
599
600  void Delete(unsigned index) throw();
601  void Delete(unsigned index, unsigned count) throw();
602  void DeleteFrontal(unsigned num) throw();
603  void DeleteBack() { _chars[--_len] = 0; }
604  void DeleteFrom(unsigned index)
605  {
606    if (index < _len)
607    {
608      _len = index;
609      _chars[index] = 0;
610    }
611  }
612};
613
614bool operator<(const UString &s1, const UString &s2);
615bool operator>(const UString &s1, const UString &s2);
616
617inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
618inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
619inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
620
621inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
622inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
623inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
624
625
626// ---------- forbidden functions ----------
627
628void operator==(wchar_t c1, const UString &s2);
629void operator==(const UString &s1, wchar_t c2);
630
631void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
632
633void operator+(const UString &s, char c);
634void operator+(const UString &s, unsigned char c);
635void operator+(char c, const UString &s);
636void operator+(unsigned char c, const UString &s);
637void operator-(const UString &s1, wchar_t c);
638
639#ifdef _WIN32
640// can we forbid these functions, if wchar_t is 32-bit ?
641void operator+(const UString &s, int c);
642void operator+(const UString &s, unsigned c);
643void operator+(int c, const UString &s);
644void operator+(unsigned c, const UString &s);
645void operator-(const UString &s1, int c);
646void operator-(const UString &s1, unsigned c);
647#endif
648
649
650
651
652
653
654
655class UString2
656{
657  wchar_t *_chars;
658  unsigned _len;
659
660  void ReAlloc2(unsigned newLimit);
661  void SetStartLen(unsigned len);
662
663  // ---------- forbidden functions ----------
664
665  UString2 &operator=(char c);
666  UString2 &operator=(unsigned char c);
667  UString2 &operator=(wchar_t c);
668  UString2(char c);
669  UString2(unsigned char c);
670
671public:
672  UString2(): _chars(NULL), _len(0) {}
673  // UString2(wchar_t c);
674  UString2(const wchar_t *s);
675  UString2(const UString2 &s);
676  ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
677
678  unsigned Len() const { return _len; }
679  bool IsEmpty() const { return _len == 0; }
680  // void Empty() { _len = 0; _chars[0] = 0; }
681
682  // operator const wchar_t *() const { return _chars; }
683  const wchar_t *GetRawPtr() const { return _chars; }
684
685  wchar_t *GetBuf(unsigned minLen)
686  {
687    if (!_chars || minLen > _len)
688      ReAlloc2(minLen);
689    return _chars;
690  }
691  void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
692
693  UString2 &operator=(const wchar_t *s);
694  UString2 &operator=(const UString2 &s);
695  void SetFromAscii(const char *s);
696};
697
698bool operator==(const UString2 &s1, const UString2 &s2);
699bool operator==(const UString2 &s1, const wchar_t *s2);
700bool operator==(const wchar_t *s1, const UString2 &s2);
701
702inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
703inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
704inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
705
706
707// ---------- forbidden functions ----------
708
709void operator==(wchar_t c1, const UString2 &s2);
710void operator==(const UString2 &s1, wchar_t c2);
711bool operator<(const UString2 &s1, const UString2 &s2);
712bool operator>(const UString2 &s1, const UString2 &s2);
713
714void operator+(const UString2 &s1, const UString2 &s2);
715void operator+(const UString2 &s1, const wchar_t *s2);
716void operator+(const wchar_t *s1, const UString2 &s2);
717void operator+(wchar_t c, const UString2 &s);
718void operator+(const UString2 &s, wchar_t c);
719void operator+(const UString2 &s, char c);
720void operator+(const UString2 &s, unsigned char c);
721void operator+(char c, const UString2 &s);
722void operator+(unsigned char c, const UString2 &s);
723void operator-(const UString2 &s1, wchar_t c);
724
725
726
727
728
729
730typedef CObjectVector<AString> AStringVector;
731typedef CObjectVector<UString> UStringVector;
732
733#ifdef _UNICODE
734  typedef UString CSysString;
735#else
736  typedef AString CSysString;
737#endif
738
739typedef CObjectVector<CSysString> CSysStringVector;
740
741
742// ---------- FString ----------
743
744#ifdef _WIN32
745  #define USE_UNICODE_FSTRING
746#endif
747
748#ifdef USE_UNICODE_FSTRING
749
750  #define __FTEXT(quote) L##quote
751
752  typedef wchar_t FChar;
753  typedef UString FString;
754
755  #define fs2us(_x_) (_x_)
756  #define us2fs(_x_) (_x_)
757  FString fas2fs(const AString &s);
758  AString fs2fas(const FChar *s);
759
760#else
761
762  #define __FTEXT(quote) quote
763
764  typedef char FChar;
765  typedef AString FString;
766
767  UString fs2us(const FString &s);
768  FString us2fs(const wchar_t *s);
769  #define fas2fs(_x_) (_x_)
770  #define fs2fas(_x_) (_x_)
771
772#endif
773
774#define FTEXT(quote) __FTEXT(quote)
775
776#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
777#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
778#define FCHAR_ANY_MASK FTEXT('*')
779#define FSTRING_ANY_MASK FTEXT("*")
780typedef const FChar *CFSTR;
781
782typedef CObjectVector<FString> FStringVector;
783
784#endif
785