Sandboxie/SandboxiePlus/MiscHelpers/Archive/7z/CPP/Common/MyString.h

1065 lines
30 KiB
C++

// Common/MyString.h
#ifndef ZIP7_INC_COMMON_MY_STRING_H
#define ZIP7_INC_COMMON_MY_STRING_H
#include <string.h>
#ifndef _WIN32
#include <wctype.h>
#include <wchar.h>
#endif
#include "Common.h"
#include "MyWindows.h"
#include "MyTypes.h"
#include "MyVector.h"
/* if (DEBUG_FSTRING_INHERITS_ASTRING is defined), then
FString inherits from AString, so we can find bugs related to FString at compile time.
DON'T define DEBUG_FSTRING_INHERITS_ASTRING in release code */
// #define DEBUG_FSTRING_INHERITS_ASTRING
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
class FString;
#endif
#ifdef _MSC_VER
#ifdef _NATIVE_WCHAR_T_DEFINED
#define MY_NATIVE_WCHAR_T_DEFINED
#endif
#else
#define MY_NATIVE_WCHAR_T_DEFINED
#endif
/*
native support for wchar_t:
_MSC_VER == 1600 : /Zc:wchar_t is not supported
_MSC_VER == 1310 (VS2003)
? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short
/Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED
_MSC_VER > 1400 (VS2008+)
/Zc:wchar_t[-]
/Zc:wchar_t is on by default
*/
#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 (;;)
{
const char c = *src;
*dest = c;
if (c == 0)
return dest;
src++;
dest++;
}
}
inline void MyStringCat(char *dest, const char *src)
{
for (; *dest != 0; dest++);
while ((*dest++ = *src++) != 0);
// MyStringCopy(dest + MyStringLen(dest), src);
}
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 void MyStringCat(wchar_t *dest, const wchar_t *src)
{
for (; *dest != 0; dest++);
while ((*dest++ = *src++) != 0);
// MyStringCopy(dest + MyStringLen(dest), src);
}
/*
inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src)
{
for (;;)
{
const 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)((unsigned 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((wint_t)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(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(const wchar_t *s1, const char *s2) throw();
bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw();
bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw();
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw();
#define MyStringCompare(s1, s2) wcscmp(s1, s2)
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 char *u, const char *a) throw();
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_);
#define FORBID_STRING_OPS_2(cls, t) \
void Find(t) const; \
void Find(t, unsigned startIndex) const; \
void ReverseFind(t) const; \
void InsertAtFront(t); \
void RemoveChar(t); \
void Replace(t, t); \
#define FORBID_STRING_OPS(cls, t) \
explicit cls(t); \
explicit cls(const t *); \
cls &operator=(t); \
cls &operator=(const t *); \
cls &operator+=(t); \
cls &operator+=(const t *); \
FORBID_STRING_OPS_2(cls, t) \
/*
cls &operator+(t); \
cls &operator+(const t *); \
*/
#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t)
#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t)
#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t)
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 ----------
#ifdef MY_NATIVE_WCHAR_T_DEFINED
FORBID_STRING_OPS_AString(wchar_t)
#endif
FORBID_STRING_OPS_AString(signed char)
FORBID_STRING_OPS_AString(unsigned char)
FORBID_STRING_OPS_AString(short)
FORBID_STRING_OPS_AString(unsigned short)
FORBID_STRING_OPS_AString(int)
FORBID_STRING_OPS_AString(unsigned)
FORBID_STRING_OPS_AString(long)
FORBID_STRING_OPS_AString(unsigned long)
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
AString(const FString &s);
AString &operator=(const FString &s);
AString &operator+=(const FString &s);
#endif
public:
explicit AString();
explicit AString(char c);
explicit 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; }
char *Ptr_non_const() const { return _chars; }
const char *Ptr() const { return _chars; }
const char *Ptr(unsigned pos) const { return _chars + pos; }
const char *Ptr(int pos) const { return _chars + (unsigned)pos; }
const char *RightPtr(unsigned num) const { return _chars + _len - num; }
char Back() const { return _chars[(size_t)_len - 1]; }
void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; }
char *GetBuf() { return _chars; }
/* 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_OptSpaced(const char *s);
void Add_LF();
void Add_Slash();
void Add_Dot();
void Add_Minus();
void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
AString &operator+=(const char *s);
AString &operator+=(const AString &s);
void Add_UInt32(UInt32 v);
void Add_UInt64(UInt64 v);
void AddFrom(const char *s, unsigned len); // no check
void SetFrom(const char *s, unsigned len); // no check
void SetFrom(const char* s, int len) // no check
{
SetFrom(s, (unsigned)len); // no check
}
void SetFrom_CalcLen(const char *s, unsigned len);
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
{
const int pos = FindCharPosInString(_chars + startIndex, c);
return pos < 0 ? -1 : (int)startIndex + pos;
}
int Find(char c, int startIndex) const
{
return Find(c, (unsigned)startIndex);
}
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;
}
}
void DeleteFrom(int index)
{
DeleteFrom((unsigned)index);
}
void Wipe_and_Empty()
{
if (_chars)
{
memset(_chars, 0, (_limit + 1) * sizeof(*_chars));
_len = 0;
}
}
};
class AString_Wipe: public AString
{
Z7_CLASS_NO_COPY(AString_Wipe)
public:
AString_Wipe(): AString() {}
// AString_Wipe(const AString &s): AString(s) {}
// AString_Wipe &operator=(const AString &s) { AString::operator=(s); return *this; }
// AString_Wipe &operator=(const char *s) { AString::operator=(s); return *this; }
~AString_Wipe() { Wipe_and_Empty(); }
};
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 ----------
FORBID_STRING_OPS_UString(signed char)
FORBID_STRING_OPS_UString(unsigned char)
FORBID_STRING_OPS_UString(short)
#ifdef MY_NATIVE_WCHAR_T_DEFINED
FORBID_STRING_OPS_UString(unsigned short)
#endif
FORBID_STRING_OPS_UString(int)
FORBID_STRING_OPS_UString(unsigned)
FORBID_STRING_OPS_UString(long)
FORBID_STRING_OPS_UString(unsigned long)
FORBID_STRING_OPS_2(UString, char)
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
UString(const FString &s);
UString &operator=(const FString &s);
UString &operator+=(const FString &s);
#endif
public:
UString();
explicit UString(wchar_t c);
explicit UString(char c);
explicit UString(const char *s);
explicit UString(const AString &s);
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; }
wchar_t *Ptr_non_const() const { return _chars; }
const wchar_t *Ptr() const { return _chars; }
const wchar_t *Ptr(int pos) const { return _chars + (unsigned)pos; }
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[(size_t)_len - 1]; }
void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; }
wchar_t *GetBuf() { return _chars; }
/*
wchar_t *GetBuf_GetMaxAvail(unsigned &availBufLen)
{
availBufLen = _limit;
return _chars;
}
*/
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=(char c) { return (*this)=((wchar_t)(unsigned char)c); }
UString &operator=(const wchar_t *s);
UString &operator=(const UString &s);
void SetFrom(const wchar_t *s, unsigned len); // no check
void SetFromBstr(LPCOLESTR s);
UString &operator=(const char *s);
UString &operator=(const AString &s) { return operator=(s.Ptr()); }
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+=(char c) { return (*this)+=((wchar_t)(unsigned char)c); }
void Add_Space();
void Add_Space_if_NotEmpty();
void Add_LF();
void Add_Dot();
void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); }
UString &operator+=(const wchar_t *s);
UString &operator+=(const UString &s);
UString &operator+=(const char *s);
UString &operator+=(const AString &s) { return operator+=(s.Ptr()); }
void Add_UInt32(UInt32 v);
void Add_UInt64(UInt64 v);
UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); }
UString Left(unsigned count) const { return UString(count, *this); }
UString Left(int count) const { return Left((unsigned)count); }
// 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_wchar_t(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(int index) throw() { Delete((unsigned)index); }
void Delete(unsigned index) throw();
void Delete(unsigned index, unsigned count) throw();
void DeleteFrontal(unsigned num) throw();
void DeleteBack() { _chars[--_len] = 0; }
void DeleteFrom(int index) { DeleteFrom((unsigned)index); }
void DeleteFrom(unsigned index)
{
if (index < _len)
{
_len = index;
_chars[index] = 0;
}
}
void Wipe_and_Empty()
{
if (_chars)
{
memset(_chars, 0, (_limit + 1) * sizeof(*_chars));
_len = 0;
}
}
};
class UString_Wipe: public UString
{
Z7_CLASS_NO_COPY(UString_Wipe)
public:
UString_Wipe(): UString() {}
// UString_Wipe(const UString &s): UString(s) {}
// UString_Wipe &operator=(const UString &s) { UString::operator=(s); return *this; }
// UString_Wipe &operator=(const wchar_t *s) { UString::operator=(s); return *this; }
~UString_Wipe() { Wipe_and_Empty(); }
};
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 AString &s1, const UString &s2);
void operator+(const UString &s1, const AString &s2);
void operator+(const UString &s1, const char *s2);
void operator+(const char *s1, const UString &s2);
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 ----------
FORBID_STRING_OPS_UString2(char)
FORBID_STRING_OPS_UString2(signed char)
FORBID_STRING_OPS_UString2(unsigned char)
FORBID_STRING_OPS_UString2(short)
UString2 &operator=(wchar_t c);
UString2(const AString &s);
UString2 &operator=(const AString &s);
UString2 &operator+=(const AString &s);
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
UString2(const FString &s);
UString2 &operator=(const FString &s);
UString2 &operator+=(const FString &s);
#endif
public:
UString2(): _chars(NULL), _len(0) {}
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; }
int Compare(const wchar_t *s) const { return wcscmp(_chars, s); }
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 ----------
#ifndef DEBUG_FSTRING_INHERITS_ASTRING
#ifdef _WIN32
#define USE_UNICODE_FSTRING
#endif
#endif
#ifdef USE_UNICODE_FSTRING
#define MY_FTEXT(quote) L##quote
typedef wchar_t FChar;
typedef UString FString;
#define fs2us(_x_) (_x_)
#define us2fs(_x_) (_x_)
FString fas2fs(const char *s);
FString fas2fs(const AString &s);
AString fs2fas(const FChar *s);
#else // USE_UNICODE_FSTRING
#define MY_FTEXT(quote) quote
typedef char FChar;
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
class FString: public AString
{
// FString &operator=(const char *s);
FString &operator=(const AString &s);
// FString &operator+=(const AString &s);
public:
FString(const AString &s): AString(s.Ptr()) {}
FString(const FString &s): AString(s.Ptr()) {}
FString(const char *s): AString(s) {}
FString() {}
FString &operator=(const FString &s) { AString::operator=((const AString &)s); return *this; }
FString &operator=(char c) { AString::operator=(c); return *this; }
FString &operator+=(char c) { AString::operator+=(c); return *this; }
FString &operator+=(const FString &s) { AString::operator+=((const AString &)s); return *this; }
FString Left(unsigned count) const { return FString(AString::Left(count)); }
};
void operator+(const AString &s1, const FString &s2);
void operator+(const FString &s1, const AString &s2);
inline FString operator+(const FString &s1, const FString &s2)
{
AString s =(const AString &)s1 + (const AString &)s2;
return FString(s.Ptr());
// return FString((const AString &)s1 + (const AString &)s2);
}
inline FString operator+(const FString &s1, const FChar *s2)
{
return s1 + (FString)s2;
}
/*
inline FString operator+(const FChar *s1, const FString &s2)
{
return (FString)s1 + s2;
}
*/
inline FString fas2fs(const char *s) { return FString(s); }
#else // DEBUG_FSTRING_INHERITS_ASTRING
typedef AString FString;
#define fas2fs(_x_) (_x_)
#endif // DEBUG_FSTRING_INHERITS_ASTRING
UString fs2us(const FChar *s);
UString fs2us(const FString &s);
FString us2fs(const wchar_t *s);
#define fs2fas(_x_) (_x_)
#endif // USE_UNICODE_FSTRING
#define FTEXT(quote) MY_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;
class CStringFinder
{
AString _temp;
public:
// list - is list of low case Ascii strings separated by space " ".
// the function returns true, if it can find exact word (str) in (list).
bool FindWord_In_LowCaseAsciiList_NoCase(const char *list, const wchar_t *str);
};
void SplitString(const UString &srcString, UStringVector &destStrings);
#endif
#if defined(_WIN32)
// #include <wchar.h>
// WCHAR_MAX is defined as ((wchar_t)-1)
#define Z7_WCHART_IS_16BIT 1
#elif (defined(WCHAR_MAX) && (WCHAR_MAX <= 0xffff)) \
|| (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ == 2))
#define Z7_WCHART_IS_16BIT 1
#endif
#if WCHAR_PATH_SEPARATOR == L'\\'
// WSL scheme
#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT ((wchar_t)((unsigned)(0xF000) + (unsigned)'\\'))
// #define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT '_'
#endif