Source code

Revision control

Copy as Markdown

Other Tools

// Common/MyString.cpp↩
#include "StdAfx.h"
#ifdef _WIN32↩
#include <wchar.h>↩
#else
#include <ctype.h>↩
#endif
#include "IntToString.h"
#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING)↩
#include "StringConvert.h"
#endif
#include "MyString.h"
#define MY_STRING_NEW(_T_, _size_) new _T_[_size_]↩
// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_)))↩
/*↩
inline const char* MyStringGetNextCharPointer(const char *p) throw()↩
{↩
#if defined(_WIN32) && !defined(UNDER_CE)↩
return CharNextA(p);↩
#else↩
return p + 1;↩
#endif↩
}↩
*/
#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, _size_)↩
#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, _size_)↩
int FindCharPosInString(const char *s, char c) throw()↩
{↩
for (const char *p = s;; p++)↩
{↩
if (*p == c)↩
return (int)(p - s);↩
if (*p == 0)↩
return -1;↩
// MyStringGetNextCharPointer(p);↩
}↩
}↩
int FindCharPosInString(const wchar_t *s, wchar_t c) throw()↩
{↩
for (const wchar_t *p = s;; p++)↩
{↩
if (*p == c)↩
return (int)(p - s);↩
if (*p == 0)↩
return -1;↩
}↩
}↩
/*↩
void MyStringUpper_Ascii(char *s) throw()↩
{↩
for (;;)↩
{↩
char c = *s;↩
if (c == 0)↩
return;↩
*s++ = MyCharUpper_Ascii(c);↩
}↩
}↩
void MyStringUpper_Ascii(wchar_t *s) throw()↩
{↩
for (;;)↩
{↩
wchar_t c = *s;↩
if (c == 0)↩
return;↩
*s++ = MyCharUpper_Ascii(c);↩
}↩
}↩
*/
void MyStringLower_Ascii(char *s) throw()↩
{↩
for (;;)↩
{↩
char c = *s;↩
if (c == 0)↩
return;↩
*s++ = MyCharLower_Ascii(c);↩
}↩
}↩
void MyStringLower_Ascii(wchar_t *s) throw()↩
{↩
for (;;)↩
{↩
wchar_t c = *s;↩
if (c == 0)↩
return;↩
*s++ = MyCharLower_Ascii(c);↩
}↩
}↩
#ifdef _WIN32↩
#ifdef _UNICODE↩
// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }↩
// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }↩
// for WinCE - FString - char↩
// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; }↩
#else
// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); }↩
// char * MyStringUpper(char *s) { return CharUpperA(s); }↩
// char * MyStringLower(char *s) { return CharLowerA(s); }↩
wchar_t MyCharUpper_WIN(wchar_t c) throw()↩
{↩
wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c);↩
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)↩
return (wchar_t)(unsigned)(UINT_PTR)res;↩
const int kBufSize = 4;↩
char s[kBufSize + 1];↩
int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);↩
if (numChars == 0 || numChars > kBufSize)↩
return c;↩
s[numChars] = 0;↩
::CharUpperA(s);↩
::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);↩
return c;↩
}↩
/*↩
wchar_t MyCharLower_WIN(wchar_t c)↩
{↩
wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c);↩
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)↩
return (wchar_t)(unsigned)(UINT_PTR)res;↩
const int kBufSize = 4;↩
char s[kBufSize + 1];↩
int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0);↩
if (numChars == 0 || numChars > kBufSize)↩
return c;↩
s[numChars] = 0;↩
::CharLowerA(s);↩
::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);↩
return c;↩
}↩
*/
/*↩
wchar_t * MyStringUpper(wchar_t *s)↩
{↩
if (s == 0)↩
return 0;↩
wchar_t *res = CharUpperW(s);↩
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)↩
return res;↩
AString a = UnicodeStringToMultiByte(s);↩
a.MakeUpper();↩
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));↩
return s;↩
}↩
*/
/*↩
wchar_t * MyStringLower(wchar_t *s)↩
{↩
if (s == 0)↩
return 0;↩
wchar_t *res = CharLowerW(s);↩
if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)↩
return res;↩
AString a = UnicodeStringToMultiByte(s);↩
a.MakeLower();↩
MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));↩
return s;↩
}↩
*/
#endif
#endif
bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()↩
{↩
for (;;)↩
{↩
unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;↩
unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;↩
}↩
}↩
bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c1 = *s1++;↩
wchar_t c2 = *s2++;↩
if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;↩
if (c1 == 0) return true;↩
}↩
}↩
// ---------- ASCII ----------↩
bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()↩
{↩
const char *s1 = _chars;↩
for (;;)↩
{↩
char c2 = *s++;↩
if (c2 == 0)↩
return true;↩
char c1 = *s1++;↩
if (MyCharLower_Ascii(c1) !=↩
MyCharLower_Ascii(c2))↩
return false;↩
}↩
}↩
bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()↩
{↩
const wchar_t *s1 = _chars;↩
for (;;)↩
{↩
char c2 = *s++;↩
if (c2 == 0)↩
return true;↩
wchar_t c1 = *s1++;↩
if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))↩
return false;↩
}↩
}↩
bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()↩
{↩
for (;;)↩
{↩
unsigned char c = *a;↩
if (c != *u)↩
return false;↩
if (c == 0)↩
return true;↩
a++;↩
u++;↩
}↩
}↩
bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()↩
{↩
for (;;)↩
{↩
char c1 = *s1++;↩
char c2 = *s2++;↩
if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))↩
return false;↩
if (c1 == 0)↩
return true;↩
}↩
}↩
bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c1 = *s1++;↩
wchar_t c2 = *s2++;↩
if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))↩
return false;↩
if (c1 == 0)↩
return true;↩
}↩
}↩
bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c1 = *s1++;↩
char c2 = *s2++;↩
if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)))↩
return false;↩
if (c1 == 0)↩
return true;↩
}↩
}↩
bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c2 = *s2++; if (c2 == 0) return true;↩
wchar_t c1 = *s1++; if (c1 != c2) return false;↩
}↩
}↩
bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw()↩
{↩
for (;;)↩
{↩
unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true;↩
wchar_t c1 = *s1++; if (c1 != c2) return false;↩
}↩
}↩
bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw()↩
{↩
for (;;)↩
{↩
char c2 = *s2++; if (c2 == 0) return true;↩
wchar_t c1 = *s1++;↩
if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))↩
return false;↩
}↩
}↩
bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c2 = *s2++; if (c2 == 0) return true;↩
wchar_t c1 = *s1++;↩
if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2))↩
return false;↩
}↩
}↩
// NTFS order: uses upper case↩
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()↩
{↩
for (;;)↩
{↩
wchar_t c1 = *s1++;↩
wchar_t c2 = *s2++;↩
if (c1 != c2)↩
{↩
wchar_t u1 = MyCharUpper(c1);↩
wchar_t u2 = MyCharUpper(c2);↩
if (u1 < u2) return -1;↩
if (u1 > u2) return 1;↩
}↩
if (c1 == 0) return 0;↩
}↩
}↩
/*↩
int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num)↩
{↩
for (; num != 0; num--)↩
{↩
wchar_t c1 = *s1++;↩
wchar_t c2 = *s2++;↩
if (c1 != c2)↩
{↩
wchar_t u1 = MyCharUpper(c1);↩
wchar_t u2 = MyCharUpper(c2);↩
if (u1 < u2) return -1;↩
if (u1 > u2) return 1;↩
}↩
if (c1 == 0) return 0;↩
}↩
return 0;↩
}↩
*/
// ---------- AString ----------↩
void AString::InsertSpace(unsigned &index, unsigned size)↩
{↩
Grow(size);↩
MoveItems(index + size, index);↩
}↩
#define k_Alloc_Len_Limit 0x40000000↩
void AString::ReAlloc(unsigned newLimit)↩
{↩
if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220;↩
// MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);↩
char *newBuf = MY_STRING_NEW_char(newLimit + 1);↩
memcpy(newBuf, _chars, (size_t)(_len + 1));↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = newLimit;↩
}↩
void AString::ReAlloc2(unsigned newLimit)↩
{↩
if (newLimit >= k_Alloc_Len_Limit) throw 20130220;↩
// MY_STRING_REALLOC(_chars, char, newLimit + 1, 0);↩
char *newBuf = MY_STRING_NEW_char(newLimit + 1);↩
newBuf[0] = 0;↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = newLimit;↩
}↩
void AString::SetStartLen(unsigned len)↩
{↩
_chars = 0;↩
_chars = MY_STRING_NEW_char(len + 1);↩
_len = len;↩
_limit = len;↩
}↩
void AString::Grow_1()↩
{↩
unsigned next = _len;↩
next += next / 2;↩
next += 16;↩
next &= ~(unsigned)15;↩
ReAlloc(next - 1);↩
}↩
void AString::Grow(unsigned n)↩
{↩
unsigned freeSize = _limit - _len;↩
if (n <= freeSize)↩
return;↩
unsigned next = _len + n;↩
next += next / 2;↩
next += 16;↩
next &= ~(unsigned)15;↩
ReAlloc(next - 1);↩
}↩
AString::AString(unsigned num, const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (num > len)↩
num = len;↩
SetStartLen(num);↩
memcpy(_chars, s, num);↩
_chars[num] = 0;↩
}↩
AString::AString(unsigned num, const AString &s)↩
{↩
if (num > s._len)↩
num = s._len;↩
SetStartLen(num);↩
memcpy(_chars, s._chars, num);↩
_chars[num] = 0;↩
}↩
AString::AString(const AString &s, char c)↩
{↩
SetStartLen(s.Len() + 1);↩
char *chars = _chars;↩
unsigned len = s.Len();↩
memcpy(chars, s, len);↩
chars[len] = c;↩
chars[(size_t)len + 1] = 0;↩
}↩
AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2)↩
{↩
SetStartLen(num1 + num2);↩
char *chars = _chars;↩
memcpy(chars, s1, num1);↩
memcpy(chars + num1, s2, num2 + 1);↩
}↩
AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); }↩
AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); }↩
AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); }↩
static const unsigned kStartStringCapacity = 4;↩
AString::AString()↩
{↩
_chars = 0;↩
_chars = MY_STRING_NEW_char(kStartStringCapacity);↩
_len = 0;↩
_limit = kStartStringCapacity - 1;↩
_chars[0] = 0;↩
}↩
AString::AString(char c)↩
{↩
SetStartLen(1);↩
char *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
}↩
AString::AString(const char *s)↩
{↩
SetStartLen(MyStringLen(s));↩
MyStringCopy(_chars, s);↩
}↩
AString::AString(const AString &s)↩
{↩
SetStartLen(s._len);↩
MyStringCopy(_chars, s._chars);↩
}↩
AString &AString::operator=(char c)↩
{↩
if (1 > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(1 + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = 1;↩
}↩
_len = 1;↩
char *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
return *this;↩
}↩
AString &AString::operator=(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (len > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
MyStringCopy(_chars, s);↩
return *this;↩
}↩
AString &AString::operator=(const AString &s)↩
{↩
if (&s == this)↩
return *this;↩
unsigned len = s._len;↩
if (len > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
MyStringCopy(_chars, s._chars);↩
return *this;↩
}↩
void AString::SetFromWStr_if_Ascii(const wchar_t *s)↩
{↩
unsigned len = 0;↩
{↩
for (;; len++)↩
{↩
wchar_t c = s[len];↩
if (c == 0)↩
break;↩
if (c >= 0x80)↩
return;↩
}↩
}↩
if (len > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
char *dest = _chars;↩
unsigned i;↩
for (i = 0; i < len; i++)↩
dest[i] = (char)s[i];↩
dest[i] = 0;↩
}↩
/*↩
void AString::SetFromBstr_if_Ascii(BSTR s)↩
{↩
unsigned len = ::SysStringLen(s);↩
{↩
for (unsigned i = 0; i < len; i++)↩
if (s[i] <= 0 || s[i] >= 0x80)↩
return;↩
}↩
if (len > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
char *dest = _chars;↩
unsigned i;↩
for (i = 0; i < len; i++)↩
dest[i] = (char)s[i];↩
dest[i] = 0;↩
}↩
*/
void AString::Add_Space() { operator+=(' '); }↩
void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }↩
void AString::Add_LF() { operator+=('\n'); }↩
AString &AString::operator+=(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
Grow(len);↩
MyStringCopy(_chars + _len, s);↩
_len += len;↩
return *this;↩
}↩
void AString::Add_OptSpaced(const char *s)↩
{↩
Add_Space_if_NotEmpty();↩
(*this) += s;↩
}↩
AString &AString::operator+=(const AString &s)↩
{↩
Grow(s._len);↩
MyStringCopy(_chars + _len, s._chars);↩
_len += s._len;↩
return *this;↩
}↩
void AString::Add_UInt32(UInt32 v)↩
{↩
char sz[16];↩
ConvertUInt32ToString(v, sz);↩
(*this) += sz;↩
}↩
void AString::SetFrom(const char *s, unsigned len) // no check↩
{↩
if (len > _limit)↩
{↩
char *newBuf = MY_STRING_NEW_char(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
if (len != 0)↩
memcpy(_chars, s, len);↩
_chars[len] = 0;↩
_len = len;↩
}↩
void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check↩
{↩
unsigned i;↩
for (i = 0; i < len; i++)↩
if (s[i] == 0)↩
break;↩
SetFrom(s, i);↩
}↩
int AString::Find(const char *s, unsigned startIndex) const throw()↩
{↩
const char *fs = strstr(_chars + startIndex, s);↩
if (!fs)↩
return -1;↩
return (int)(fs - _chars);↩
/*↩
if (s[0] == 0)↩
return startIndex;↩
unsigned len = MyStringLen(s);↩
const char *p = _chars + startIndex;↩
for (;; p++)↩
{↩
const char c = *p;↩
if (c != s[0])↩
{↩
if (c == 0)↩
return -1;↩
continue;↩
}↩
unsigned i;↩
for (i = 1; i < len; i++)↩
if (p[i] != s[i])↩
break;↩
if (i == len)↩
return (int)(p - _chars);↩
}↩
*/
}↩
int AString::ReverseFind(char c) const throw()↩
{↩
if (_len == 0)↩
return -1;↩
const char *p = _chars + _len - 1;↩
for (;;)↩
{↩
if (*p == c)↩
return (int)(p - _chars);↩
if (p == _chars)↩
return -1;↩
p--; // p = GetPrevCharPointer(_chars, p);↩
}↩
}↩
int AString::ReverseFind_PathSepar() const throw()↩
{↩
if (_len == 0)↩
return -1;↩
const char *p = _chars + _len - 1;↩
for (;;)↩
{↩
char c = *p;↩
if (IS_PATH_SEPAR(c))↩
return (int)(p - _chars);↩
if (p == _chars)↩
return -1;↩
p--;↩
}↩
}↩
void AString::TrimLeft() throw()↩
{↩
const char *p = _chars;↩
for (;; p++)↩
{↩
char c = *p;↩
if (c != ' ' && c != '\n' && c != '\t')↩
break;↩
}↩
unsigned pos = (unsigned)(p - _chars);↩
if (pos != 0)↩
{↩
MoveItems(0, pos);↩
_len -= pos;↩
}↩
}↩
void AString::TrimRight() throw()↩
{↩
const char *p = _chars;↩
unsigned i;↩
for (i = _len; i != 0; i--)↩
{↩
char c = p[(size_t)i - 1];↩
if (c != ' ' && c != '\n' && c != '\t')↩
break;↩
}↩
if (i != _len)↩
{↩
_chars[i] = 0;↩
_len = i;↩
}↩
}↩
void AString::InsertAtFront(char c)↩
{↩
if (_limit == _len)↩
Grow_1();↩
MoveItems(1, 0);↩
_chars[0] = c;↩
_len++;↩
}↩
/*↩
void AString::Insert(unsigned index, char c)↩
{↩
InsertSpace(index, 1);↩
_chars[index] = c;↩
_len++;↩
}↩
*/
void AString::Insert(unsigned index, const char *s)↩
{↩
unsigned num = MyStringLen(s);↩
if (num != 0)↩
{↩
InsertSpace(index, num);↩
memcpy(_chars + index, s, num);↩
_len += num;↩
}↩
}↩
void AString::Insert(unsigned index, const AString &s)↩
{↩
unsigned num = s.Len();↩
if (num != 0)↩
{↩
InsertSpace(index, num);↩
memcpy(_chars + index, s, num);↩
_len += num;↩
}↩
}↩
void AString::RemoveChar(char ch) throw()↩
{↩
char *src = _chars;↩
for (;;)↩
{↩
char c = *src++;↩
if (c == 0)↩
return;↩
if (c == ch)↩
break;↩
}↩
char *dest = src - 1;↩
for (;;)↩
{↩
char c = *src++;↩
if (c == 0)↩
break;↩
if (c != ch)↩
*dest++ = c;↩
}↩
*dest = 0;↩
_len = (unsigned)(dest - _chars);↩
}↩
// !!!!!!!!!!!!!!! test it if newChar = '\0'↩
void AString::Replace(char oldChar, char newChar) throw()↩
{↩
if (oldChar == newChar)↩
return; // 0;↩
// unsigned number = 0;↩
int pos = 0;↩
char *chars = _chars;↩
while ((unsigned)pos < _len)↩
{↩
pos = Find(oldChar, pos);↩
if (pos < 0)↩
break;↩
chars[(unsigned)pos] = newChar;↩
pos++;↩
// number++;↩
}↩
return; // number;↩
}↩
void AString::Replace(const AString &oldString, const AString &newString)↩
{↩
if (oldString.IsEmpty())↩
return; // 0;↩
if (oldString == newString)↩
return; // 0;↩
unsigned oldLen = oldString.Len();↩
unsigned newLen = newString.Len();↩
// unsigned number = 0;↩
int pos = 0;↩
while ((unsigned)pos < _len)↩
{↩
pos = Find(oldString, pos);↩
if (pos < 0)↩
break;↩
Delete(pos, oldLen);↩
Insert(pos, newString);↩
pos += newLen;↩
// number++;↩
}↩
// return number;↩
}↩
void AString::Delete(unsigned index) throw()↩
{↩
MoveItems(index, index + 1);↩
_len--;↩
}↩
void AString::Delete(unsigned index, unsigned count) throw()↩
{↩
if (index + count > _len)↩
count = _len - index;↩
if (count > 0)↩
{↩
MoveItems(index, index + count);↩
_len -= count;↩
}↩
}↩
void AString::DeleteFrontal(unsigned num) throw()↩
{↩
if (num != 0)↩
{↩
MoveItems(0, num);↩
_len -= num;↩
}↩
}↩
/*↩
AString operator+(const AString &s1, const AString &s2)↩
{↩
AString result(s1);↩
result += s2;↩
return result;↩
}↩
AString operator+(const AString &s, const char *chars)↩
{↩
AString result(s);↩
result += chars;↩
return result;↩
}↩
AString operator+(const char *chars, const AString &s)↩
{↩
AString result(chars);↩
result += s;↩
return result;↩
}↩
AString operator+(const AString &s, char c)↩
{↩
AString result(s);↩
result += c;↩
return result;↩
}↩
*/
/*↩
AString operator+(char c, const AString &s)↩
{↩
AString result(c);↩
result += s;↩
return result;↩
}↩
*/
// ---------- UString ----------↩
void UString::InsertSpace(unsigned index, unsigned size)↩
{↩
Grow(size);↩
MoveItems(index + size, index);↩
}↩
void UString::ReAlloc(unsigned newLimit)↩
{↩
if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221;↩
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);↩
wmemcpy(newBuf, _chars, _len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = newLimit;↩
}↩
void UString::ReAlloc2(unsigned newLimit)↩
{↩
if (newLimit >= k_Alloc_Len_Limit) throw 20130221;↩
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);↩
newBuf[0] = 0;↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = newLimit;↩
}↩
void UString::SetStartLen(unsigned len)↩
{↩
_chars = 0;↩
_chars = MY_STRING_NEW_wchar_t(len + 1);↩
_len = len;↩
_limit = len;↩
}↩
void UString::Grow_1()↩
{↩
unsigned next = _len;↩
next += next / 2;↩
next += 16;↩
next &= ~(unsigned)15;↩
ReAlloc(next - 1);↩
}↩
void UString::Grow(unsigned n)↩
{↩
unsigned freeSize = _limit - _len;↩
if (n <= freeSize)↩
return;↩
unsigned next = _len + n;↩
next += next / 2;↩
next += 16;↩
next &= ~(unsigned)15;↩
ReAlloc(next - 1);↩
}↩
UString::UString(unsigned num, const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (num > len)↩
num = len;↩
SetStartLen(num);↩
wmemcpy(_chars, s, num);↩
_chars[num] = 0;↩
}↩
UString::UString(unsigned num, const UString &s)↩
{↩
if (num > s._len)↩
num = s._len;↩
SetStartLen(num);↩
wmemcpy(_chars, s._chars, num);↩
_chars[num] = 0;↩
}↩
UString::UString(const UString &s, wchar_t c)↩
{↩
SetStartLen(s.Len() + 1);↩
wchar_t *chars = _chars;↩
unsigned len = s.Len();↩
wmemcpy(chars, s, len);↩
chars[len] = c;↩
chars[(size_t)len + 1] = 0;↩
}↩
UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2)↩
{↩
SetStartLen(num1 + num2);↩
wchar_t *chars = _chars;↩
wmemcpy(chars, s1, num1);↩
wmemcpy(chars + num1, s2, num2 + 1);↩
}↩
UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); }↩
UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); }↩
UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); }↩
UString::UString()↩
{↩
_chars = 0;↩
_chars = MY_STRING_NEW_wchar_t(kStartStringCapacity);↩
_len = 0;↩
_limit = kStartStringCapacity - 1;↩
_chars[0] = 0;↩
}↩
UString::UString(wchar_t c)↩
{↩
SetStartLen(1);↩
wchar_t *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
}↩
UString::UString(char c)↩
{↩
SetStartLen(1);↩
wchar_t *chars = _chars;↩
chars[0] = (unsigned char)c;↩
chars[1] = 0;↩
}↩
UString::UString(const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
SetStartLen(len);↩
wmemcpy(_chars, s, len + 1);↩
}↩
UString::UString(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
SetStartLen(len);↩
wchar_t *chars = _chars;↩
for (unsigned i = 0; i < len; i++)↩
chars[i] = (unsigned char)s[i];↩
chars[len] = 0;↩
}↩
UString::UString(const UString &s)↩
{↩
SetStartLen(s._len);↩
wmemcpy(_chars, s._chars, s._len + 1);↩
}↩
UString &UString::operator=(wchar_t c)↩
{↩
if (1 > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = 1;↩
}↩
_len = 1;↩
wchar_t *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
return *this;↩
}↩
UString &UString::operator=(const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (len > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
wmemcpy(_chars, s, len + 1);↩
return *this;↩
}↩
UString &UString::operator=(const UString &s)↩
{↩
if (&s == this)↩
return *this;↩
unsigned len = s._len;↩
if (len > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
wmemcpy(_chars, s._chars, len + 1);↩
return *this;↩
}↩
void UString::SetFrom(const wchar_t *s, unsigned len) // no check↩
{↩
if (len > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
if (len != 0)↩
wmemcpy(_chars, s, len);↩
_chars[len] = 0;↩
_len = len;↩
}↩
void UString::SetFromBstr(BSTR s)↩
{↩
unsigned len = ::SysStringLen(s);↩
if (len > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
_len = len;↩
// if (s)↩
wmemcpy(_chars, s, len + 1);↩
}↩
UString &UString::operator=(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (len > _limit)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
_limit = len;↩
}↩
wchar_t *chars = _chars;↩
for (unsigned i = 0; i < len; i++)↩
chars[i] = (unsigned char)s[i];↩
chars[len] = 0;↩
_len = len;↩
return *this;↩
}↩
void UString::Add_Space() { operator+=(L' '); }↩
void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }↩
void UString::Add_LF()↩
{↩
if (_limit == _len)↩
Grow_1();↩
unsigned len = _len;↩
wchar_t *chars = _chars;↩
chars[len++] = L'\n';↩
chars[len] = 0;↩
_len = len;↩
}↩
UString &UString::operator+=(const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
Grow(len);↩
wmemcpy(_chars + _len, s, len + 1);↩
_len += len;↩
return *this;↩
}↩
UString &UString::operator+=(const UString &s)↩
{↩
Grow(s._len);↩
wmemcpy(_chars + _len, s._chars, s._len + 1);↩
_len += s._len;↩
return *this;↩
}↩
UString &UString::operator+=(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
Grow(len);↩
wchar_t *chars = _chars + _len;↩
for (unsigned i = 0; i < len; i++)↩
chars[i] = (unsigned char)s[i];↩
chars[len] = 0;↩
_len += len;↩
return *this;↩
}↩
void UString::Add_UInt32(UInt32 v)↩
{↩
char sz[16];↩
ConvertUInt32ToString(v, sz);↩
(*this) += sz;↩
}↩
int UString::Find(const wchar_t *s, unsigned startIndex) const throw()↩
{↩
const wchar_t *fs = wcsstr(_chars + startIndex, s);↩
if (!fs)↩
return -1;↩
return (int)(fs - _chars);↩
/*↩
if (s[0] == 0)↩
return startIndex;↩
unsigned len = MyStringLen(s);↩
const wchar_t *p = _chars + startIndex;↩
for (;; p++)↩
{↩
const wchar_t c = *p;↩
if (c != s[0])↩
{↩
if (c == 0)↩
return -1;↩
continue;↩
}↩
unsigned i;↩
for (i = 1; i < len; i++)↩
if (p[i] != s[i])↩
break;↩
if (i == len)↩
return (int)(p - _chars);↩
}↩
*/
}↩
int UString::ReverseFind(wchar_t c) const throw()↩
{↩
if (_len == 0)↩
return -1;↩
const wchar_t *p = _chars + _len - 1;↩
for (;;)↩
{↩
if (*p == c)↩
return (int)(p - _chars);↩
if (p == _chars)↩
return -1;↩
p--;↩
}↩
}↩
int UString::ReverseFind_PathSepar() const throw()↩
{↩
if (_len == 0)↩
return -1;↩
const wchar_t *p = _chars + _len - 1;↩
for (;;)↩
{↩
wchar_t c = *p;↩
if (IS_PATH_SEPAR(c))↩
return (int)(p - _chars);↩
if (p == _chars)↩
return -1;↩
p--;↩
}↩
}↩
void UString::TrimLeft() throw()↩
{↩
const wchar_t *p = _chars;↩
for (;; p++)↩
{↩
wchar_t c = *p;↩
if (c != ' ' && c != '\n' && c != '\t')↩
break;↩
}↩
unsigned pos = (unsigned)(p - _chars);↩
if (pos != 0)↩
{↩
MoveItems(0, pos);↩
_len -= pos;↩
}↩
}↩
void UString::TrimRight() throw()↩
{↩
const wchar_t *p = _chars;↩
unsigned i;↩
for (i = _len; i != 0; i--)↩
{↩
wchar_t c = p[(size_t)i - 1];↩
if (c != ' ' && c != '\n' && c != '\t')↩
break;↩
}↩
if (i != _len)↩
{↩
_chars[i] = 0;↩
_len = i;↩
}↩
}↩
void UString::InsertAtFront(wchar_t c)↩
{↩
if (_limit == _len)↩
Grow_1();↩
MoveItems(1, 0);↩
_chars[0] = c;↩
_len++;↩
}↩
/*↩
void UString::Insert(unsigned index, wchar_t c)↩
{↩
InsertSpace(index, 1);↩
_chars[index] = c;↩
_len++;↩
}↩
*/
void UString::Insert(unsigned index, const wchar_t *s)↩
{↩
unsigned num = MyStringLen(s);↩
if (num != 0)↩
{↩
InsertSpace(index, num);↩
wmemcpy(_chars + index, s, num);↩
_len += num;↩
}↩
}↩
void UString::Insert(unsigned index, const UString &s)↩
{↩
unsigned num = s.Len();↩
if (num != 0)↩
{↩
InsertSpace(index, num);↩
wmemcpy(_chars + index, s, num);↩
_len += num;↩
}↩
}↩
void UString::RemoveChar(wchar_t ch) throw()↩
{↩
wchar_t *src = _chars;↩
for (;;)↩
{↩
wchar_t c = *src++;↩
if (c == 0)↩
return;↩
if (c == ch)↩
break;↩
}↩
wchar_t *dest = src - 1;↩
for (;;)↩
{↩
wchar_t c = *src++;↩
if (c == 0)↩
break;↩
if (c != ch)↩
*dest++ = c;↩
}↩
*dest = 0;↩
_len = (unsigned)(dest - _chars);↩
}↩
// !!!!!!!!!!!!!!! test it if newChar = '\0'↩
void UString::Replace(wchar_t oldChar, wchar_t newChar) throw()↩
{↩
if (oldChar == newChar)↩
return; // 0;↩
// unsigned number = 0;↩
int pos = 0;↩
wchar_t *chars = _chars;↩
while ((unsigned)pos < _len)↩
{↩
pos = Find(oldChar, pos);↩
if (pos < 0)↩
break;↩
chars[(unsigned)pos] = newChar;↩
pos++;↩
// number++;↩
}↩
return; // number;↩
}↩
void UString::Replace(const UString &oldString, const UString &newString)↩
{↩
if (oldString.IsEmpty())↩
return; // 0;↩
if (oldString == newString)↩
return; // 0;↩
unsigned oldLen = oldString.Len();↩
unsigned newLen = newString.Len();↩
// unsigned number = 0;↩
int pos = 0;↩
while ((unsigned)pos < _len)↩
{↩
pos = Find(oldString, pos);↩
if (pos < 0)↩
break;↩
Delete(pos, oldLen);↩
Insert(pos, newString);↩
pos += newLen;↩
// number++;↩
}↩
// return number;↩
}↩
void UString::Delete(unsigned index) throw()↩
{↩
MoveItems(index, index + 1);↩
_len--;↩
}↩
void UString::Delete(unsigned index, unsigned count) throw()↩
{↩
if (index + count > _len)↩
count = _len - index;↩
if (count > 0)↩
{↩
MoveItems(index, index + count);↩
_len -= count;↩
}↩
}↩
void UString::DeleteFrontal(unsigned num) throw()↩
{↩
if (num != 0)↩
{↩
MoveItems(0, num);↩
_len -= num;↩
}↩
}↩
// ---------- UString2 ----------↩
void UString2::ReAlloc2(unsigned newLimit)↩
{↩
if (newLimit >= k_Alloc_Len_Limit) throw 20130221;↩
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);↩
_chars = MY_STRING_NEW_wchar_t(newLimit + 1);↩
}↩
void UString2::SetStartLen(unsigned len)↩
{↩
_chars = 0;↩
_chars = MY_STRING_NEW_wchar_t(len + 1);↩
_len = len;↩
}↩
/*↩
UString2::UString2(wchar_t c)↩
{↩
SetStartLen(1);↩
wchar_t *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
}↩
*/
UString2::UString2(const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
SetStartLen(len);↩
wmemcpy(_chars, s, len + 1);↩
}↩
UString2::UString2(const UString2 &s): _chars(NULL), _len(0)↩
{↩
if (s._chars)↩
{↩
SetStartLen(s._len);↩
wmemcpy(_chars, s._chars, s._len + 1);↩
}↩
}↩
/*↩
UString2 &UString2::operator=(wchar_t c)↩
{↩
if (1 > _len)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1);↩
if (_chars)↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
}↩
_len = 1;↩
wchar_t *chars = _chars;↩
chars[0] = c;↩
chars[1] = 0;↩
return *this;↩
}↩
*/
UString2 &UString2::operator=(const wchar_t *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (len > _len)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
if (_chars)↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
}↩
_len = len;↩
MyStringCopy(_chars, s);↩
return *this;↩
}↩
void UString2::SetFromAscii(const char *s)↩
{↩
unsigned len = MyStringLen(s);↩
if (len > _len)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
if (_chars)↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
}↩
wchar_t *chars = _chars;↩
for (unsigned i = 0; i < len; i++)↩
chars[i] = (unsigned char)s[i];↩
chars[len] = 0;↩
_len = len;↩
}↩
UString2 &UString2::operator=(const UString2 &s)↩
{↩
if (&s == this)↩
return *this;↩
unsigned len = s._len;↩
if (len > _len)↩
{↩
wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);↩
if (_chars)↩
MY_STRING_DELETE(_chars);↩
_chars = newBuf;↩
}↩
_len = len;↩
MyStringCopy(_chars, s._chars);↩
return *this;↩
}↩
bool operator==(const UString2 &s1, const UString2 &s2)↩
{↩
return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0);↩
}↩
bool operator==(const UString2 &s1, const wchar_t *s2)↩
{↩
if (s1.IsEmpty())↩
return (*s2 == 0);↩
return wcscmp(s1.GetRawPtr(), s2) == 0;↩
}↩
bool operator==(const wchar_t *s1, const UString2 &s2)↩
{↩
if (s2.IsEmpty())↩
return (*s1 == 0);↩
return wcscmp(s1, s2.GetRawPtr()) == 0;↩
}↩
// ----------------------------------------↩
/*↩
int MyStringCompareNoCase(const char *s1, const char *s2)↩
{↩
return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));↩
}↩
*/
static inline UINT GetCurrentCodePage()↩
{↩
#if defined(UNDER_CE) || !defined(_WIN32)↩
return CP_ACP;↩
#else
return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;↩
#endif
}↩
#ifdef USE_UNICODE_FSTRING↩
#ifndef _UNICODE↩
AString fs2fas(CFSTR s)↩
{↩
return UnicodeStringToMultiByte(s, GetCurrentCodePage());↩
}↩
FString fas2fs(const char *s)↩
{↩
return MultiByteToUnicodeString(s, GetCurrentCodePage());↩
}↩
FString fas2fs(const AString &s)↩
{↩
return MultiByteToUnicodeString(s, GetCurrentCodePage());↩
}↩
#endif
#else
UString fs2us(const FChar *s)↩
{↩
return MultiByteToUnicodeString(s, GetCurrentCodePage());↩
}↩
UString fs2us(const FString &s)↩
{↩
return MultiByteToUnicodeString(s, GetCurrentCodePage());↩
}↩
FString us2fs(const wchar_t *s)↩
{↩
return UnicodeStringToMultiByte(s, GetCurrentCodePage());↩
}↩
#endif