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