793 lines
23 KiB
C
793 lines
23 KiB
C
|
// Common/String.h
|
||
|
|
||
|
#ifndef __COMMON_STRING_H
|
||
|
#define __COMMON_STRING_H
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#ifdef ENV_HAVE_WCHAR__H
|
||
|
#include <wchar.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef ENV_HAVE_WCTYPE_H
|
||
|
#include <wctype.h>
|
||
|
#else
|
||
|
#define towupper(c) (c) // FIXME
|
||
|
int wcscmp(const wchar_t *s1, const wchar_t *s2);
|
||
|
wchar_t * wmemcpy(wchar_t *dest, const wchar_t *src, size_t num);
|
||
|
wchar_t * wcsstr(const wchar_t *wcs1, const wchar_t *wcs2);
|
||
|
#endif
|
||
|
|
||
|
#include "MyWindows.h"
|
||
|
#include "MyTypes.h"
|
||
|
#include "MyVector.h"
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/')
|
||
|
#else
|
||
|
#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR)
|
||
|
#endif
|
||
|
|
||
|
inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); }
|
||
|
inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); }
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
|
||
|
{
|
||
|
for (;;)
|
||
|
{
|
||
|
wchar_t c = *src;
|
||
|
*dest = c;
|
||
|
if (c == 0)
|
||
|
return dest;
|
||
|
src++;
|
||
|
dest++;
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
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)((unsigned 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(char *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();
|
||
|
bool IsString1PrefixedByString2_NoCase(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 ReAlloc2(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);
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
AString &operator+=(wchar_t c);
|
||
|
AString &operator=(wchar_t c);
|
||
|
AString(wchar_t c);
|
||
|
void Find(wchar_t c) const;
|
||
|
void Find(wchar_t c, unsigned startIndex) const;
|
||
|
void ReverseFind(wchar_t c) const;
|
||
|
void InsertAtFront(wchar_t c);
|
||
|
void RemoveChar(wchar_t ch);
|
||
|
void Replace(wchar_t oldChar, wchar_t newChar);
|
||
|
|
||
|
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; }
|
||
|
|
||
|
/* GetBuf(minLen): provides the buffer that can store
|
||
|
at least (minLen) characters and additional null terminator.
|
||
|
9.35: GetBuf doesn't preserve old characters and terminator */
|
||
|
char *GetBuf(unsigned minLen)
|
||
|
{
|
||
|
if (minLen > _limit)
|
||
|
ReAlloc2(minLen);
|
||
|
return _chars;
|
||
|
}
|
||
|
char *GetBuf_SetEnd(unsigned minLen)
|
||
|
{
|
||
|
if (minLen > _limit)
|
||
|
ReAlloc2(minLen);
|
||
|
char *chars = _chars;
|
||
|
chars[minLen] = 0;
|
||
|
_len = minLen;
|
||
|
return chars;
|
||
|
}
|
||
|
|
||
|
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||
|
void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||
|
void ReleaseBuf_CalcLen(unsigned maxLen)
|
||
|
{
|
||
|
char *chars = _chars;
|
||
|
chars[maxLen] = 0;
|
||
|
_len = MyStringLen(chars);
|
||
|
}
|
||
|
|
||
|
AString &operator=(char c);
|
||
|
AString &operator=(const char *s);
|
||
|
AString &operator=(const AString &s);
|
||
|
void SetFromWStr_if_Ascii(const wchar_t *s);
|
||
|
// void SetFromBstr_if_Ascii(BSTR 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;
|
||
|
}
|
||
|
|
||
|
void Add_Space();
|
||
|
void Add_Space_if_NotEmpty();
|
||
|
void Add_LF();
|
||
|
void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
|
||
|
|
||
|
AString &operator+=(const char *s);
|
||
|
AString &operator+=(const AString &s);
|
||
|
void AddAscii(const char *s) { operator+=(s); }
|
||
|
|
||
|
void SetFrom(const char *s, unsigned len); // no check
|
||
|
void SetFrom_CalcLen(const char *s, unsigned len);
|
||
|
// void SetFromAscii(const char *s) { operator+=(s); }
|
||
|
|
||
|
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); }
|
||
|
void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
|
||
|
|
||
|
|
||
|
bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; }
|
||
|
bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); }
|
||
|
// 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();
|
||
|
|
||
|
bool IsAscii() const
|
||
|
{
|
||
|
unsigned len = Len();
|
||
|
const char *s = _chars;
|
||
|
for (unsigned i = 0; i < len; i++)
|
||
|
if ((unsigned char)s[i] >= 0x80)
|
||
|
return false;
|
||
|
return true;
|
||
|
}
|
||
|
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 ReverseFind_Dot() const throw() { return ReverseFind('.'); }
|
||
|
int ReverseFind_PathSepar() const throw();
|
||
|
|
||
|
int Find(const char *s) const { return Find(s, 0); }
|
||
|
int Find(const char *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; }
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
|
||
|
void operator==(char c1, const AString &s2);
|
||
|
void operator==(const AString &s1, char c2);
|
||
|
|
||
|
void operator+(char c, const AString &s); // this function can be OK, but we don't use it
|
||
|
|
||
|
void operator+(const AString &s, int c);
|
||
|
void operator+(const AString &s, unsigned c);
|
||
|
void operator+(int c, const AString &s);
|
||
|
void operator+(unsigned c, const AString &s);
|
||
|
void operator-(const AString &s, int c);
|
||
|
void operator-(const AString &s, unsigned c);
|
||
|
|
||
|
|
||
|
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 ReAlloc2(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);
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
|
||
|
UString &operator+=(char c);
|
||
|
UString &operator+=(unsigned char c);
|
||
|
UString &operator=(char c);
|
||
|
UString &operator=(unsigned char c);
|
||
|
UString(char c);
|
||
|
UString(unsigned char c);
|
||
|
void Find(char c) const;
|
||
|
void Find(unsigned char c) const;
|
||
|
void Find(char c, unsigned startIndex) const;
|
||
|
void Find(unsigned char c, unsigned startIndex) const;
|
||
|
void ReverseFind(char c) const;
|
||
|
void ReverseFind(unsigned char c) const;
|
||
|
void InsertAtFront(char c);
|
||
|
void InsertAtFront(unsigned char c);
|
||
|
void RemoveChar(char ch);
|
||
|
void RemoveChar(unsigned char ch);
|
||
|
void Replace(char oldChar, char newChar);
|
||
|
void Replace(unsigned char oldChar, unsigned char newChar);
|
||
|
|
||
|
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; }
|
||
|
|
||
|
wchar_t *GetBuf(unsigned minLen)
|
||
|
{
|
||
|
if (minLen > _limit)
|
||
|
ReAlloc2(minLen);
|
||
|
return _chars;
|
||
|
}
|
||
|
wchar_t *GetBuf_SetEnd(unsigned minLen)
|
||
|
{
|
||
|
if (minLen > _limit)
|
||
|
ReAlloc2(minLen);
|
||
|
wchar_t *chars = _chars;
|
||
|
chars[minLen] = 0;
|
||
|
_len = minLen;
|
||
|
return chars;
|
||
|
}
|
||
|
|
||
|
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||
|
void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; }
|
||
|
void ReleaseBuf_CalcLen(unsigned maxLen)
|
||
|
{
|
||
|
wchar_t *chars = _chars;
|
||
|
chars[maxLen] = 0;
|
||
|
_len = MyStringLen(chars);
|
||
|
}
|
||
|
|
||
|
UString &operator=(wchar_t c);
|
||
|
UString &operator=(const wchar_t *s);
|
||
|
UString &operator=(const UString &s);
|
||
|
void SetFromBstr(BSTR 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;
|
||
|
}
|
||
|
|
||
|
void Add_Space();
|
||
|
void Add_Space_if_NotEmpty();
|
||
|
void Add_LF();
|
||
|
void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
|
||
|
|
||
|
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 AddAscii(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 IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); }
|
||
|
bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_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_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); }
|
||
|
bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw();
|
||
|
|
||
|
bool IsAscii() const
|
||
|
{
|
||
|
unsigned len = Len();
|
||
|
const wchar_t *s = _chars;
|
||
|
for (unsigned i = 0; i < len; i++)
|
||
|
if (s[i] >= 0x80)
|
||
|
return false;
|
||
|
return true;
|
||
|
}
|
||
|
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 ReverseFind(wchar_t c) const throw();
|
||
|
int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); }
|
||
|
int ReverseFind_PathSepar() const throw();
|
||
|
|
||
|
int Find(const wchar_t *s) const { return Find(s, 0); }
|
||
|
int Find(const wchar_t *s, unsigned startIndex) 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; }
|
||
|
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
|
||
|
void operator==(wchar_t c1, const UString &s2);
|
||
|
void operator==(const UString &s1, wchar_t c2);
|
||
|
|
||
|
void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it
|
||
|
|
||
|
void operator+(const UString &s, char c);
|
||
|
void operator+(const UString &s, unsigned char c);
|
||
|
void operator+(char c, const UString &s);
|
||
|
void operator+(unsigned char c, const UString &s);
|
||
|
void operator-(const UString &s1, wchar_t c);
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
// can we forbid these functions, if wchar_t is 32-bit ?
|
||
|
void operator+(const UString &s, int c);
|
||
|
void operator+(const UString &s, unsigned c);
|
||
|
void operator+(int c, const UString &s);
|
||
|
void operator+(unsigned c, const UString &s);
|
||
|
void operator-(const UString &s1, int c);
|
||
|
void operator-(const UString &s1, unsigned c);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
class UString2
|
||
|
{
|
||
|
wchar_t *_chars;
|
||
|
unsigned _len;
|
||
|
|
||
|
void ReAlloc2(unsigned newLimit);
|
||
|
void SetStartLen(unsigned len);
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
|
||
|
UString2 &operator=(char c);
|
||
|
UString2 &operator=(unsigned char c);
|
||
|
UString2 &operator=(wchar_t c);
|
||
|
UString2(char c);
|
||
|
UString2(unsigned char c);
|
||
|
|
||
|
public:
|
||
|
UString2(): _chars(NULL), _len(0) {}
|
||
|
// UString2(wchar_t c);
|
||
|
UString2(const wchar_t *s);
|
||
|
UString2(const UString2 &s);
|
||
|
~UString2() { if (_chars) 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 *GetRawPtr() const { return _chars; }
|
||
|
|
||
|
wchar_t *GetBuf(unsigned minLen)
|
||
|
{
|
||
|
if (!_chars || minLen > _len)
|
||
|
ReAlloc2(minLen);
|
||
|
return _chars;
|
||
|
}
|
||
|
void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; }
|
||
|
|
||
|
UString2 &operator=(const wchar_t *s);
|
||
|
UString2 &operator=(const UString2 &s);
|
||
|
void SetFromAscii(const char *s);
|
||
|
};
|
||
|
|
||
|
bool operator==(const UString2 &s1, const UString2 &s2);
|
||
|
bool operator==(const UString2 &s1, const wchar_t *s2);
|
||
|
bool operator==(const wchar_t *s1, const UString2 &s2);
|
||
|
|
||
|
inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); }
|
||
|
inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); }
|
||
|
inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); }
|
||
|
|
||
|
|
||
|
// ---------- forbidden functions ----------
|
||
|
|
||
|
void operator==(wchar_t c1, const UString2 &s2);
|
||
|
void operator==(const UString2 &s1, wchar_t c2);
|
||
|
bool operator<(const UString2 &s1, const UString2 &s2);
|
||
|
bool operator>(const UString2 &s1, const UString2 &s2);
|
||
|
|
||
|
void operator+(const UString2 &s1, const UString2 &s2);
|
||
|
void operator+(const UString2 &s1, const wchar_t *s2);
|
||
|
void operator+(const wchar_t *s1, const UString2 &s2);
|
||
|
void operator+(wchar_t c, const UString2 &s);
|
||
|
void operator+(const UString2 &s, wchar_t c);
|
||
|
void operator+(const UString2 &s, char c);
|
||
|
void operator+(const UString2 &s, unsigned char c);
|
||
|
void operator+(char c, const UString2 &s);
|
||
|
void operator+(unsigned char c, const UString2 &s);
|
||
|
void operator-(const UString2 &s1, wchar_t c);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef CObjectVector<AString> AStringVector;
|
||
|
typedef CObjectVector<UString> UStringVector;
|
||
|
|
||
|
#ifdef _UNICODE
|
||
|
typedef UString CSysString;
|
||
|
#else
|
||
|
typedef AString CSysString;
|
||
|
#endif
|
||
|
|
||
|
typedef CObjectVector<CSysString> CSysStringVector;
|
||
|
|
||
|
|
||
|
// ---------- FString ----------
|
||
|
|
||
|
#ifdef _UNICODE // FIXME #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<FString> FStringVector;
|
||
|
|
||
|
#endif
|