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
IsPathSepar(char c)23 inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
IsPathSepar(wchar_t c)24 inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
25
MyStringLen(const char * s)26 inline unsigned MyStringLen(const char *s)
27 {
28 unsigned i;
29 for (i = 0; s[i] != 0; i++);
30 return i;
31 }
32
MyStringCopy(char * dest,const char * src)33 inline void MyStringCopy(char *dest, const char *src)
34 {
35 while ((*dest++ = *src++) != 0);
36 }
37
MyStpCpy(char * dest,const char * src)38 inline 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
MyStringLen(const wchar_t * s)51 inline unsigned MyStringLen(const wchar_t *s)
52 {
53 unsigned i;
54 for (i = 0; s[i] != 0; i++);
55 return i;
56 }
57
MyStringCopy(wchar_t * dest,const wchar_t * src)58 inline void MyStringCopy(wchar_t *dest, const wchar_t *src)
59 {
60 while ((*dest++ = *src++) != 0);
61 }
62
63 /*
64 inline 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
78 int FindCharPosInString(const char *s, char c) throw();
79 int 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 /*
92 inline char MyCharUpper_Ascii(char c)
93 {
94 if (c >= 'a' && c <= 'z')
95 return (char)(c - 0x20);
96 return c;
97 }
98 inline 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
MyCharLower_Ascii(char c)106 inline char MyCharLower_Ascii(char c)
107 {
108 if (c >= 'A' && c <= 'Z')
109 return (char)((unsigned char)c + 0x20);
110 return c;
111 }
112
MyCharLower_Ascii(wchar_t c)113 inline 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
120 wchar_t MyCharUpper_WIN(wchar_t c) throw();
121
MyCharUpper(wchar_t c)122 inline 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 /*
139 wchar_t MyCharLower_WIN(wchar_t c) throw();
140
141 inline 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();
162 void MyStringLower_Ascii(char *s) throw();
163 void 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
167 bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw();
168
169 bool IsString1PrefixedByString2(const char *s1, const char *s2) throw();
170 bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw();
171 bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
172
173 int 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
178 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw();
179 bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw();
180 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw();
181 bool 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
186 class AString
187 {
188 char *_chars;
189 unsigned _len;
190 unsigned _limit;
191
MoveItems(unsigned dest,unsigned src)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
228 public:
229 AString();
230 AString(char c);
231 AString(const char *s);
232 AString(const AString &s);
~AString()233 ~AString() { MY_STRING_DELETE(_chars); }
234
Len()235 unsigned Len() const { return _len; }
IsEmpty()236 bool IsEmpty() const { return _len == 0; }
Empty()237 void Empty() { _len = 0; _chars[0] = 0; }
238
239 operator const char *() const { return _chars; }
Ptr()240 const char *Ptr() const { return _chars; }
Ptr(unsigned pos)241 const char *Ptr(unsigned pos) const { return _chars + pos; }
RightPtr(unsigned num)242 const char *RightPtr(unsigned num) const { return _chars + _len - num; }
Back()243 char Back() const { return _chars[_len - 1]; }
244
ReplaceOneCharAtPos(unsigned pos,char c)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 */
GetBuf(unsigned minLen)250 char *GetBuf(unsigned minLen)
251 {
252 if (minLen > _limit)
253 ReAlloc2(minLen);
254 return _chars;
255 }
GetBuf_SetEnd(unsigned minLen)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
ReleaseBuf_SetLen(unsigned newLen)266 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
ReleaseBuf_SetEnd(unsigned newLen)267 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
ReleaseBuf_CalcLen(unsigned maxLen)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();
Add_PathSepar()296 void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
297
298 AString &operator+=(const char *s);
299 AString &operator+=(const AString &s);
AddAscii(const char * 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
Mid(unsigned startIndex,unsigned count)306 AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
Left(unsigned count)307 AString Left(unsigned count) const { return AString(count, *this); }
308
309 // void MakeUpper() { MyStringUpper(_chars); }
310 // void MakeLower() { MyStringLower(_chars); }
MakeLower_Ascii()311 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
312
313
IsEqualTo(const char * s)314 bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
IsEqualTo_Ascii_NoCase(const char * s)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); }
IsPrefixedBy(const char * s)320 bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); }
321 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
322
IsAscii()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 }
Find(char c)332 int Find(char c) const { return FindCharPosInString(_chars, c); }
Find(char c,unsigned startIndex)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();
ReverseFind_Dot()340 int ReverseFind_Dot() const throw() { return ReverseFind('.'); }
341 int ReverseFind_PathSepar() const throw();
342
Find(const char * s)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();
Trim()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();
DeleteBack()367 void DeleteBack() { _chars[--_len] = 0; }
DeleteFrom(unsigned index)368 void DeleteFrom(unsigned index)
369 {
370 if (index < _len)
371 {
372 _len = index;
373 _chars[index] = 0;
374 }
375 }
376 };
377
378 bool operator<(const AString &s1, const AString &s2);
379 bool operator>(const AString &s1, const AString &s2);
380
381 /*
382 bool operator==(const AString &s1, const AString &s2);
383 bool operator==(const AString &s1, const char *s2);
384 bool operator==(const char *s1, const AString &s2);
385
386 bool operator!=(const AString &s1, const AString &s2);
387 bool operator!=(const AString &s1, const char *s2);
388 bool operator!=(const char *s1, const AString &s2);
389 */
390
391 inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; }
392 inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; }
393 inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; }
394
395 inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; }
396 inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; }
397 inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; }
398
399 // ---------- forbidden functions ----------
400
401 void operator==(char c1, const AString &s2);
402 void operator==(const AString &s1, char c2);
403
404 void operator+(char c, const AString &s); // this function can be OK, but we don't use it
405
406 void operator+(const AString &s, int c);
407 void operator+(const AString &s, unsigned c);
408 void operator+(int c, const AString &s);
409 void operator+(unsigned c, const AString &s);
410 void operator-(const AString &s, int c);
411 void operator-(const AString &s, unsigned c);
412
413
414 class UString
415 {
416 wchar_t *_chars;
417 unsigned _len;
418 unsigned _limit;
419
MoveItems(unsigned dest,unsigned src)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
466 public:
467 UString();
468 UString(wchar_t c);
469 UString(const wchar_t *s);
470 UString(const UString &s);
~UString()471 ~UString() { MY_STRING_DELETE(_chars); }
472
Len()473 unsigned Len() const { return _len; }
IsEmpty()474 bool IsEmpty() const { return _len == 0; }
Empty()475 void Empty() { _len = 0; _chars[0] = 0; }
476
477 operator const wchar_t *() const { return _chars; }
Ptr()478 const wchar_t *Ptr() const { return _chars; }
Ptr(unsigned pos)479 const wchar_t *Ptr(unsigned pos) const { return _chars + pos; }
RightPtr(unsigned num)480 const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; }
Back()481 wchar_t Back() const { return _chars[_len - 1]; }
482
ReplaceOneCharAtPos(unsigned pos,wchar_t c)483 void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
484
GetBuf(unsigned minLen)485 wchar_t *GetBuf(unsigned minLen)
486 {
487 if (minLen > _limit)
488 ReAlloc2(minLen);
489 return _chars;
490 }
GetBuf_SetEnd(unsigned minLen)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
ReleaseBuf_SetLen(unsigned newLen)501 void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
ReleaseBuf_SetEnd(unsigned newLen)502 void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
ReleaseBuf_CalcLen(unsigned maxLen)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();
Add_PathSepar()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
Mid(unsigned startIndex,unsigned count)540 UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
Left(unsigned count)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); }
MakeLower_Ascii()546 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
547
IsEqualTo(const char * s)548 bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); }
IsEqualTo_NoCase(const wchar_t * s)549 bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
IsEqualTo_Ascii_NoCase(const char * s)550 bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
Compare(const wchar_t * 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); }
IsPrefixedBy(const wchar_t * s)555 bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }
IsPrefixedBy_NoCase(const wchar_t * 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
IsAscii()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 }
Find(wchar_t c)568 int Find(wchar_t c) const { return FindCharPosInString(_chars, c); }
Find(wchar_t c,unsigned startIndex)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();
ReverseFind_Dot()576 int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
577 int ReverseFind_PathSepar() const throw();
578
Find(const wchar_t * s)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();
Trim()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();
DeleteBack()603 void DeleteBack() { _chars[--_len] = 0; }
DeleteFrom(unsigned index)604 void DeleteFrom(unsigned index)
605 {
606 if (index < _len)
607 {
608 _len = index;
609 _chars[index] = 0;
610 }
611 }
612 };
613
614 bool operator<(const UString &s1, const UString &s2);
615 bool operator>(const UString &s1, const UString &s2);
616
617 inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; }
618 inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; }
619 inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; }
620
621 inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; }
622 inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; }
623 inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; }
624
625
626 // ---------- forbidden functions ----------
627
628 void operator==(wchar_t c1, const UString &s2);
629 void operator==(const UString &s1, wchar_t c2);
630
631 void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
632
633 void operator+(const UString &s, char c);
634 void operator+(const UString &s, unsigned char c);
635 void operator+(char c, const UString &s);
636 void operator+(unsigned char c, const UString &s);
637 void operator-(const UString &s1, wchar_t c);
638
639 #ifdef _WIN32
640 // can we forbid these functions, if wchar_t is 32-bit ?
641 void operator+(const UString &s, int c);
642 void operator+(const UString &s, unsigned c);
643 void operator+(int c, const UString &s);
644 void operator+(unsigned c, const UString &s);
645 void operator-(const UString &s1, int c);
646 void operator-(const UString &s1, unsigned c);
647 #endif
648
649
650
651
652
653
654
655 class 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
671 public:
UString2()672 UString2(): _chars(NULL), _len(0) {}
673 // UString2(wchar_t c);
674 UString2(const wchar_t *s);
675 UString2(const UString2 &s);
~UString2()676 ~UString2() { if (_chars) MY_STRING_DELETE(_chars); }
677
Len()678 unsigned Len() const { return _len; }
IsEmpty()679 bool IsEmpty() const { return _len == 0; }
680 // void Empty() { _len = 0; _chars[0] = 0; }
681
682 // operator const wchar_t *() const { return _chars; }
GetRawPtr()683 const wchar_t *GetRawPtr() const { return _chars; }
684
GetBuf(unsigned minLen)685 wchar_t *GetBuf(unsigned minLen)
686 {
687 if (!_chars || minLen > _len)
688 ReAlloc2(minLen);
689 return _chars;
690 }
ReleaseBuf_SetLen(unsigned newLen)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
698 bool operator==(const UString2 &s1, const UString2 &s2);
699 bool operator==(const UString2 &s1, const wchar_t *s2);
700 bool operator==(const wchar_t *s1, const UString2 &s2);
701
702 inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
703 inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
704 inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
705
706
707 // ---------- forbidden functions ----------
708
709 void operator==(wchar_t c1, const UString2 &s2);
710 void operator==(const UString2 &s1, wchar_t c2);
711 bool operator<(const UString2 &s1, const UString2 &s2);
712 bool operator>(const UString2 &s1, const UString2 &s2);
713
714 void operator+(const UString2 &s1, const UString2 &s2);
715 void operator+(const UString2 &s1, const wchar_t *s2);
716 void operator+(const wchar_t *s1, const UString2 &s2);
717 void operator+(wchar_t c, const UString2 &s);
718 void operator+(const UString2 &s, wchar_t c);
719 void operator+(const UString2 &s, char c);
720 void operator+(const UString2 &s, unsigned char c);
721 void operator+(char c, const UString2 &s);
722 void operator+(unsigned char c, const UString2 &s);
723 void operator-(const UString2 &s1, wchar_t c);
724
725
726
727
728
729
730 typedef CObjectVector<AString> AStringVector;
731 typedef CObjectVector<UString> UStringVector;
732
733 #ifdef _UNICODE
734 typedef UString CSysString;
735 #else
736 typedef AString CSysString;
737 #endif
738
739 typedef 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("*")
780 typedef const FChar *CFSTR;
781
782 typedef CObjectVector<FString> FStringVector;
783
784 #endif
785