// 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 > 0 x7F || 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 0 x40000000
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 >= 0 x80)
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 ] > = 0 x80 )
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
Messung V0.5 in Prozent C=94 H=96 G=94
¤ Dauer der Verarbeitung: 0.18 Sekunden
¤
*© Formatika GbR, Deutschland