// Common/String.h #ifndef __COMMON_STRING_H #define __COMMON_STRING_H #include #ifndef _WIN32 #include #include #endif #include "MyTypes.h" #include "MyVector.h" inline unsigned MyStringLen(const char *s) { unsigned i; for (i = 0; s[i] != 0; i++); return i; } inline void MyStringCopy(char *dest, const char *src) { while ((*dest++ = *src++) != 0); } inline char *MyStpCpy(char *dest, const char *src) { for (;;) { char c = *src; *dest = c; if (c == 0) return dest; src++; dest++; } } inline unsigned MyStringLen(const wchar_t *s) { unsigned i; for (i = 0; s[i] != 0; i++); return i; } inline void MyStringCopy(wchar_t *dest, const wchar_t *src) { while ((*dest++ = *src++) != 0); } int FindCharPosInString(const char *s, char c) throw(); int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); #ifdef _WIN32 #ifndef _UNICODE #define STRING_UNICODE_THROW #endif #endif #ifndef STRING_UNICODE_THROW #define STRING_UNICODE_THROW throw() #endif /* inline char MyCharUpper_Ascii(char c) { if (c >= 'a' && c <= 'z') return (char)(c - 0x20); return c; } inline wchar_t MyCharUpper_Ascii(wchar_t c) { if (c >= 'a' && c <= 'z') return (wchar_t)(c - 0x20); return c; } */ inline char MyCharLower_Ascii(char c) { if (c >= 'A' && c <= 'Z') return (char)(c + 0x20); return c; } inline wchar_t MyCharLower_Ascii(wchar_t c) { if (c >= 'A' && c <= 'Z') return (wchar_t)(c + 0x20); return c; } wchar_t MyCharUpper_WIN(wchar_t c) throw(); inline wchar_t MyCharUpper(wchar_t c) throw() { if (c < 'a') return c; if (c <= 'z') return (wchar_t)(c - 0x20); if (c <= 0x7F) return c; #ifdef _WIN32 #ifdef _UNICODE return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); #else return (wchar_t)MyCharUpper_WIN(c); #endif #else return (wchar_t)towupper(c); #endif } /* wchar_t MyCharLower_WIN(wchar_t c) throw(); inline wchar_t MyCharLower(wchar_t c) throw() { if (c < 'A') return c; if (c <= 'Z') return (wchar_t)(c + 0x20); if (c <= 0x7F) return c; #ifdef _WIN32 #ifdef _UNICODE return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); #else return (wchar_t)MyCharLower_WIN(c); #endif #else return (wchar_t)tolower(c); #endif } */ // char *MyStringUpper(char *s) throw(); // char *MyStringLower(char *s) throw(); // void MyStringUpper_Ascii(wchar_t *s) throw(); void MyStringLower_Ascii(wchar_t *s) throw(); // wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; // wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); // ---------- ASCII ---------- // char values in ASCII strings must be less then 128 bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); #define MY_STRING_DELETE(_p_) delete []_p_; // #define MY_STRING_DELETE(_p_) my_delete(_p_); class AString { char *_chars; unsigned _len; unsigned _limit; void MoveItems(unsigned dest, unsigned src) { memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); } void InsertSpace(unsigned &index, unsigned size); void ReAlloc(unsigned newLimit); void SetStartLen(unsigned len); void Grow_1(); void Grow(unsigned n); // AString(unsigned num, const char *s); AString(unsigned num, const AString &s); AString(const AString &s, char c); // it's for String + char AString(const char *s1, unsigned num1, const char *s2, unsigned num2); friend AString operator+(const AString &s, char c) { return AString(s, c); } ; // friend AString operator+(char c, const AString &s); // is not supported friend AString operator+(const AString &s1, const AString &s2); friend AString operator+(const AString &s1, const char *s2); friend AString operator+(const char *s1, const AString &s2); public: AString(); AString(char c); AString(const char *s); AString(const AString &s); ~AString() { MY_STRING_DELETE(_chars); } unsigned Len() const { return _len; } bool IsEmpty() const { return _len == 0; } void Empty() { _len = 0; _chars[0] = 0; } operator const char *() const { return _chars; } const char *Ptr() const { return _chars; } const char *Ptr(unsigned pos) const { return _chars + pos; } const char *RightPtr(unsigned num) const { return _chars + _len - num; } char Back() const { return _chars[_len - 1]; } void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } // The minimum size of the character buffer in characters. // This value does not include space for a null terminator. char *GetBuffer(unsigned minBufLen) { if (minBufLen > _limit) ReAlloc(minBufLen); return _chars; } void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } AString &operator=(char c); AString &operator=(const char *s); AString &operator=(const AString &s); AString &operator+=(char c) { if (_limit == _len) Grow_1(); unsigned len = _len; char *chars = _chars; chars[len++] = c; chars[len] = 0; _len = len; return *this; } AString &operator+=(const char *s); AString &operator+=(const AString &s); void SetFrom(const char *s, unsigned len); // no check // AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); } AString Left(unsigned count) const { return AString(count, *this); } // void MakeUpper() { MyStringUpper(_chars); } // void MakeLower() { MyStringLower(_chars); } // int Compare(const char *s) const { return MyStringCompare(_chars, s); } // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); int Find(char c) const { return FindCharPosInString(_chars, c); } int Find(char c, unsigned startIndex) const { int pos = FindCharPosInString(_chars + startIndex, c); return pos < 0 ? -1 : (int)startIndex + pos; } int ReverseFind(char c) const throw(); int Find(const AString &s) const { return Find(s, 0); } int Find(const AString &s, unsigned startIndex) const throw(); void TrimLeft() throw(); void TrimRight() throw(); void Trim() { TrimRight(); TrimLeft(); } void InsertAtFront(char c); // void Insert(unsigned index, char c); void Insert(unsigned index, const char *s); void Insert(unsigned index, const AString &s); void RemoveChar(char ch) throw(); void Replace(char oldChar, char newChar) throw(); void Replace(const AString &oldString, const AString &newString); void Delete(unsigned index) throw(); void Delete(unsigned index, unsigned count) throw(); void DeleteFrontal(unsigned num) throw(); void DeleteBack() { _chars[--_len] = 0; } void DeleteFrom(unsigned index) { if (index < _len) { _len = index; _chars[index] = 0; } } }; bool operator<(const AString &s1, const AString &s2); bool operator>(const AString &s1, const AString &s2); /* bool operator==(const AString &s1, const AString &s2); bool operator==(const AString &s1, const char *s2); bool operator==(const char *s1, const AString &s2); bool operator!=(const AString &s1, const AString &s2); bool operator!=(const AString &s1, const char *s2); bool operator!=(const char *s1, const AString &s2); */ inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } class UString { wchar_t *_chars; unsigned _len; unsigned _limit; void MoveItems(unsigned dest, unsigned src) { memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); } void InsertSpace(unsigned index, unsigned size); void ReAlloc(unsigned newLimit); void SetStartLen(unsigned len); void Grow_1(); void Grow(unsigned n); UString(unsigned num, const wchar_t *s); // for Mid UString(unsigned num, const UString &s); // for Left UString(const UString &s, wchar_t c); // it's for String + char UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; // friend UString operator+(wchar_t c, const UString &s); // is not supported friend UString operator+(const UString &s1, const UString &s2); friend UString operator+(const UString &s1, const wchar_t *s2); friend UString operator+(const wchar_t *s1, const UString &s2); public: UString(); UString(wchar_t c); UString(const wchar_t *s); UString(const UString &s); ~UString() { MY_STRING_DELETE(_chars); } unsigned Len() const { return _len; } bool IsEmpty() const { return _len == 0; } void Empty() { _len = 0; _chars[0] = 0; } operator const wchar_t *() const { return _chars; } const wchar_t *Ptr() const { return _chars; } const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } wchar_t Back() const { return _chars[_len - 1]; } void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } // The minimum size of the character buffer in characters. // This value does not include space for a null terminator. wchar_t *GetBuffer(unsigned minBufLen) { if (minBufLen > _limit) ReAlloc(minBufLen); return _chars; } void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } void ReleaseBuffer(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } UString &operator=(wchar_t c); UString &operator=(const wchar_t *s); UString &operator=(const UString &s); UString &operator+=(wchar_t c) { if (_limit == _len) Grow_1(); unsigned len = _len; wchar_t *chars = _chars; chars[len++] = c; chars[len] = 0; _len = len; return *this; } UString &operator+=(const wchar_t *s); UString &operator+=(const UString &s); void SetFrom(const wchar_t *s, unsigned len); // no check void SetFromAscii(const char *s); void AddAsciiStr(const char *s); UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } UString Left(unsigned count) const { return UString(count, *this); } // void MakeUpper() { MyStringUpper(_chars); } // void MakeUpper() { MyStringUpper_Ascii(_chars); } // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } bool IsEqualToNoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); }; bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } int Find(wchar_t c, unsigned startIndex) const { int pos = FindCharPosInString(_chars + startIndex, c); return pos < 0 ? -1 : (int)startIndex + pos; } int Find(const UString &s) const { return Find(s, 0); } int Find(const UString &s, unsigned startIndex) const throw(); int ReverseFind(wchar_t c) const throw(); void TrimLeft() throw(); void TrimRight() throw(); void Trim() { TrimRight(); TrimLeft(); } void InsertAtFront(wchar_t c); // void Insert(unsigned index, wchar_t c); void Insert(unsigned index, const wchar_t *s); void Insert(unsigned index, const UString &s); void RemoveChar(wchar_t ch) throw(); void Replace(wchar_t oldChar, wchar_t newChar) throw(); void Replace(const UString &oldString, const UString &newString); void Delete(unsigned index) throw(); void Delete(unsigned index, unsigned count) throw(); void DeleteFrontal(unsigned num) throw(); void DeleteBack() { _chars[--_len] = 0; } void DeleteFrom(unsigned index) { if (index < _len) { _len = index; _chars[index] = 0; } } }; bool operator<(const UString &s1, const UString &s2); bool operator>(const UString &s1, const UString &s2); inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } typedef CObjectVector AStringVector; typedef CObjectVector UStringVector; #ifdef _UNICODE typedef UString CSysString; #else typedef AString CSysString; #endif typedef CObjectVector CSysStringVector; // ---------- FString ---------- #ifdef _WIN32 #define USE_UNICODE_FSTRING #endif #ifdef USE_UNICODE_FSTRING #define __FTEXT(quote) L##quote typedef wchar_t FChar; typedef UString FString; #define fs2us(_x_) (_x_) #define us2fs(_x_) (_x_) FString fas2fs(const AString &s); AString fs2fas(const FChar *s); #else #define __FTEXT(quote) quote typedef char FChar; typedef AString FString; UString fs2us(const FString &s); FString us2fs(const wchar_t *s); #define fas2fs(_x_) (_x_) #define fs2fas(_x_) (_x_) #endif #define FTEXT(quote) __FTEXT(quote) #define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) #define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) #define FCHAR_ANY_MASK FTEXT('*') #define FSTRING_ANY_MASK FTEXT("*") typedef const FChar *CFSTR; typedef CObjectVector FStringVector; #endif