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 "MyTypes.h" 14 #include "MyVector.h" 15 16 inline unsigned MyStringLen(const char *s) 17 { 18 unsigned i; 19 for (i = 0; s[i] != 0; i++); 20 return i; 21 } 22 23 inline void MyStringCopy(char *dest, const char *src) 24 { 25 while ((*dest++ = *src++) != 0); 26 } 27 28 inline char *MyStpCpy(char *dest, const char *src) 29 { 30 for (;;) 31 { 32 char c = *src; 33 *dest = c; 34 if (c == 0) 35 return dest; 36 src++; 37 dest++; 38 } 39 } 40 41 inline unsigned MyStringLen(const wchar_t *s) 42 { 43 unsigned i; 44 for (i = 0; s[i] != 0; i++); 45 return i; 46 } 47 48 inline void MyStringCopy(wchar_t *dest, const wchar_t *src) 49 { 50 while ((*dest++ = *src++) != 0); 51 } 52 53 int FindCharPosInString(const char *s, char c) throw(); 54 int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); 55 56 #ifdef _WIN32 57 #ifndef _UNICODE 58 #define STRING_UNICODE_THROW 59 #endif 60 #endif 61 62 #ifndef STRING_UNICODE_THROW 63 #define STRING_UNICODE_THROW throw() 64 #endif 65 66 /* 67 inline char MyCharUpper_Ascii(char c) 68 { 69 if (c >= 'a' && c <= 'z') 70 return (char)(c - 0x20); 71 return c; 72 } 73 inline wchar_t MyCharUpper_Ascii(wchar_t c) 74 { 75 if (c >= 'a' && c <= 'z') 76 return (wchar_t)(c - 0x20); 77 return c; 78 } 79 */ 80 81 inline char MyCharLower_Ascii(char c) 82 { 83 if (c >= 'A' && c <= 'Z') 84 return (char)(c + 0x20); 85 return c; 86 } 87 88 inline wchar_t MyCharLower_Ascii(wchar_t c) 89 { 90 if (c >= 'A' && c <= 'Z') 91 return (wchar_t)(c + 0x20); 92 return c; 93 } 94 95 wchar_t MyCharUpper_WIN(wchar_t c) throw(); 96 97 inline wchar_t MyCharUpper(wchar_t c) throw() 98 { 99 if (c < 'a') return c; 100 if (c <= 'z') return (wchar_t)(c - 0x20); 101 if (c <= 0x7F) return c; 102 #ifdef _WIN32 103 #ifdef _UNICODE 104 return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); 105 #else 106 return (wchar_t)MyCharUpper_WIN(c); 107 #endif 108 #else 109 return (wchar_t)towupper(c); 110 #endif 111 } 112 113 /* 114 wchar_t MyCharLower_WIN(wchar_t c) throw(); 115 116 inline wchar_t MyCharLower(wchar_t c) throw() 117 { 118 if (c < 'A') return c; 119 if (c <= 'Z') return (wchar_t)(c + 0x20); 120 if (c <= 0x7F) return c; 121 #ifdef _WIN32 122 #ifdef _UNICODE 123 return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); 124 #else 125 return (wchar_t)MyCharLower_WIN(c); 126 #endif 127 #else 128 return (wchar_t)tolower(c); 129 #endif 130 } 131 */ 132 133 // char *MyStringUpper(char *s) throw(); 134 // char *MyStringLower(char *s) throw(); 135 136 // void MyStringUpper_Ascii(wchar_t *s) throw(); 137 void MyStringLower_Ascii(wchar_t *s) throw(); 138 // wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; 139 // wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; 140 141 bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 142 143 bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); 144 bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); 145 146 int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); 147 int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); 148 149 // ---------- ASCII ---------- 150 // char values in ASCII strings must be less then 128 151 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); 152 bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); 153 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); 154 bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); 155 156 #define MY_STRING_DELETE(_p_) delete []_p_; 157 // #define MY_STRING_DELETE(_p_) my_delete(_p_); 158 159 class AString 160 { 161 char *_chars; 162 unsigned _len; 163 unsigned _limit; 164 165 void MoveItems(unsigned dest, unsigned src) 166 { 167 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); 168 } 169 170 void InsertSpace(unsigned &index, unsigned size); 171 172 void ReAlloc(unsigned newLimit); 173 void SetStartLen(unsigned len); 174 void Grow_1(); 175 void Grow(unsigned n); 176 177 // AString(unsigned num, const char *s); 178 AString(unsigned num, const AString &s); 179 AString(const AString &s, char c); // it's for String + char 180 AString(const char *s1, unsigned num1, const char *s2, unsigned num2); 181 182 friend AString operator+(const AString &s, char c) { return AString(s, c); } ; 183 // friend AString operator+(char c, const AString &s); // is not supported 184 185 friend AString operator+(const AString &s1, const AString &s2); 186 friend AString operator+(const AString &s1, const char *s2); 187 friend AString operator+(const char *s1, const AString &s2); 188 189 public: 190 AString(); 191 AString(char c); 192 AString(const char *s); 193 AString(const AString &s); 194 ~AString() { MY_STRING_DELETE(_chars); } 195 196 unsigned Len() const { return _len; } 197 bool IsEmpty() const { return _len == 0; } 198 void Empty() { _len = 0; _chars[0] = 0; } 199 200 operator const char *() const { return _chars; } 201 const char *Ptr() const { return _chars; } 202 const char *Ptr(unsigned pos) const { return _chars + pos; } 203 const char *RightPtr(unsigned num) const { return _chars + _len - num; } 204 char Back() const { return _chars[_len - 1]; } 205 206 void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } 207 208 // The minimum size of the character buffer in characters. 209 // This value does not include space for a null terminator. 210 char *GetBuffer(unsigned minBufLen) 211 { 212 if (minBufLen > _limit) 213 ReAlloc(minBufLen); 214 return _chars; 215 } 216 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } 217 void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 218 219 AString &operator=(char c); 220 AString &operator=(const char *s); 221 AString &operator=(const AString &s); 222 223 AString &operator+=(char c) 224 { 225 if (_limit == _len) 226 Grow_1(); 227 unsigned len = _len; 228 char *chars = _chars; 229 chars[len++] = c; 230 chars[len] = 0; 231 _len = len; 232 return *this; 233 } 234 235 AString &operator+=(const char *s); 236 AString &operator+=(const AString &s); 237 238 void SetFrom(const char *s, unsigned len); // no check 239 // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); } 240 AString Left(unsigned count) const { return AString(count, *this); } 241 242 // void MakeUpper() { MyStringUpper(_chars); } 243 // void MakeLower() { MyStringLower(_chars); } 244 245 246 // int Compare(const char *s) const { return MyStringCompare(_chars, s); } 247 // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } 248 // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } 249 // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 250 bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } 251 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 252 253 int Find(char c) const { return FindCharPosInString(_chars, c); } 254 int Find(char c, unsigned startIndex) const 255 { 256 int pos = FindCharPosInString(_chars + startIndex, c); 257 return pos < 0 ? -1 : (int)startIndex + pos; 258 } 259 int ReverseFind(char c) const throw(); 260 int Find(const AString &s) const { return Find(s, 0); } 261 int Find(const AString &s, unsigned startIndex) const throw(); 262 263 void TrimLeft() throw(); 264 void TrimRight() throw(); 265 void Trim() 266 { 267 TrimRight(); 268 TrimLeft(); 269 } 270 271 void InsertAtFront(char c); 272 // void Insert(unsigned index, char c); 273 void Insert(unsigned index, const char *s); 274 void Insert(unsigned index, const AString &s); 275 276 void RemoveChar(char ch) throw(); 277 void Replace(char oldChar, char newChar) throw(); 278 void Replace(const AString &oldString, const AString &newString); 279 280 void Delete(unsigned index) throw(); 281 void Delete(unsigned index, unsigned count) throw(); 282 void DeleteFrontal(unsigned num) throw(); 283 void DeleteBack() { _chars[--_len] = 0; } 284 void DeleteFrom(unsigned index) 285 { 286 if (index < _len) 287 { 288 _len = index; 289 _chars[index] = 0; 290 } 291 } 292 }; 293 294 bool operator<(const AString &s1, const AString &s2); 295 bool operator>(const AString &s1, const AString &s2); 296 297 /* 298 bool operator==(const AString &s1, const AString &s2); 299 bool operator==(const AString &s1, const char *s2); 300 bool operator==(const char *s1, const AString &s2); 301 302 bool operator!=(const AString &s1, const AString &s2); 303 bool operator!=(const AString &s1, const char *s2); 304 bool operator!=(const char *s1, const AString &s2); 305 */ 306 307 inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } 308 inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } 309 inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } 310 311 inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } 312 inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } 313 inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } 314 315 316 317 class UString 318 { 319 wchar_t *_chars; 320 unsigned _len; 321 unsigned _limit; 322 323 void MoveItems(unsigned dest, unsigned src) 324 { 325 memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); 326 } 327 328 void InsertSpace(unsigned index, unsigned size); 329 330 void ReAlloc(unsigned newLimit); 331 void SetStartLen(unsigned len); 332 void Grow_1(); 333 void Grow(unsigned n); 334 335 UString(unsigned num, const wchar_t *s); // for Mid 336 UString(unsigned num, const UString &s); // for Left 337 UString(const UString &s, wchar_t c); // it's for String + char 338 UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); 339 340 friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; 341 // friend UString operator+(wchar_t c, const UString &s); // is not supported 342 343 friend UString operator+(const UString &s1, const UString &s2); 344 friend UString operator+(const UString &s1, const wchar_t *s2); 345 friend UString operator+(const wchar_t *s1, const UString &s2); 346 347 public: 348 UString(); 349 UString(wchar_t c); 350 UString(const wchar_t *s); 351 UString(const UString &s); 352 ~UString() { MY_STRING_DELETE(_chars); } 353 354 unsigned Len() const { return _len; } 355 bool IsEmpty() const { return _len == 0; } 356 void Empty() { _len = 0; _chars[0] = 0; } 357 358 operator const wchar_t *() const { return _chars; } 359 const wchar_t *Ptr() const { return _chars; } 360 const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } 361 const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } 362 wchar_t Back() const { return _chars[_len - 1]; } 363 364 void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } 365 366 // The minimum size of the character buffer in characters. 367 // This value does not include space for a null terminator. 368 wchar_t *GetBuffer(unsigned minBufLen) 369 { 370 if (minBufLen > _limit) 371 ReAlloc(minBufLen); 372 return _chars; 373 } 374 void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } 375 void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } 376 377 UString &operator=(wchar_t c); 378 UString &operator=(const wchar_t *s); 379 UString &operator=(const UString &s); 380 381 UString &operator+=(wchar_t c) 382 { 383 if (_limit == _len) 384 Grow_1(); 385 unsigned len = _len; 386 wchar_t *chars = _chars; 387 chars[len++] = c; 388 chars[len] = 0; 389 _len = len; 390 return *this; 391 } 392 393 UString &operator+=(const wchar_t *s); 394 UString &operator+=(const UString &s); 395 396 void SetFrom(const wchar_t *s, unsigned len); // no check 397 398 void SetFromAscii(const char *s); 399 void AddAsciiStr(const char *s); 400 401 UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } 402 UString Left(unsigned count) const { return UString(count, *this); } 403 404 // void MakeUpper() { MyStringUpper(_chars); } 405 // void MakeUpper() { MyStringUpper_Ascii(_chars); } 406 // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } 407 void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } 408 409 bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } 410 bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } 411 int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } 412 // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } 413 // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } 414 // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } 415 bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }; 416 bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); 417 418 int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } 419 int Find(wchar_t c, unsigned startIndex) const 420 { 421 int pos = FindCharPosInString(_chars + startIndex, c); 422 return pos < 0 ? -1 : (int)startIndex + pos; 423 } 424 int Find(const UString &s) const { return Find(s, 0); } 425 int Find(const UString &s, unsigned startIndex) const throw(); 426 int ReverseFind(wchar_t c) const throw(); 427 428 void TrimLeft() throw(); 429 void TrimRight() throw(); 430 void Trim() 431 { 432 TrimRight(); 433 TrimLeft(); 434 } 435 436 void InsertAtFront(wchar_t c); 437 // void Insert(unsigned index, wchar_t c); 438 void Insert(unsigned index, const wchar_t *s); 439 void Insert(unsigned index, const UString &s); 440 441 void RemoveChar(wchar_t ch) throw(); 442 void Replace(wchar_t oldChar, wchar_t newChar) throw(); 443 void Replace(const UString &oldString, const UString &newString); 444 445 void Delete(unsigned index) throw(); 446 void Delete(unsigned index, unsigned count) throw(); 447 void DeleteFrontal(unsigned num) throw(); 448 void DeleteBack() { _chars[--_len] = 0; } 449 void DeleteFrom(unsigned index) 450 { 451 if (index < _len) 452 { 453 _len = index; 454 _chars[index] = 0; 455 } 456 } 457 }; 458 459 bool operator<(const UString &s1, const UString &s2); 460 bool operator>(const UString &s1, const UString &s2); 461 462 inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } 463 inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } 464 inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } 465 466 inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } 467 inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } 468 inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } 469 470 471 typedef CObjectVector<AString> AStringVector; 472 typedef CObjectVector<UString> UStringVector; 473 474 #ifdef _UNICODE 475 typedef UString CSysString; 476 #else 477 typedef AString CSysString; 478 #endif 479 480 typedef CObjectVector<CSysString> CSysStringVector; 481 482 483 // ---------- FString ---------- 484 485 #ifdef _WIN32 486 #define USE_UNICODE_FSTRING 487 #endif 488 489 #ifdef USE_UNICODE_FSTRING 490 491 #define __FTEXT(quote) L##quote 492 493 typedef wchar_t FChar; 494 typedef UString FString; 495 496 #define fs2us(_x_) (_x_) 497 #define us2fs(_x_) (_x_) 498 FString fas2fs(const AString &s); 499 AString fs2fas(const FChar *s); 500 501 #else 502 503 #define __FTEXT(quote) quote 504 505 typedef char FChar; 506 typedef AString FString; 507 508 UString fs2us(const FString &s); 509 FString us2fs(const wchar_t *s); 510 #define fas2fs(_x_) (_x_) 511 #define fs2fas(_x_) (_x_) 512 513 #endif 514 515 #define FTEXT(quote) __FTEXT(quote) 516 517 #define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) 518 #define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) 519 #define FCHAR_ANY_MASK FTEXT('*') 520 #define FSTRING_ANY_MASK FTEXT("*") 521 typedef const FChar *CFSTR; 522 523 typedef CObjectVector<FString> FStringVector; 524 525 #endif 526