// File: fstring.cpp // Provides: class FString #include "fstring.h" // static class constant const char* const FString::bad_alloc_str = "not enough memory " \ "to alloc a new string"; //---------------------------------------------------------------------- // class FString //---------------------------------------------------------------------- // constructors and destructor //---------------------------------------------------------------------- FString::FString() : string(0) , length(0) , bufsize(0) , c_string(0) { } //---------------------------------------------------------------------- FString::FString (int len) : string(0) , length(0) , bufsize(0) , c_string(0) { if ( len > 0 ) initLength(uInt(len)); else initLength(0); } //---------------------------------------------------------------------- FString::FString (uInt len) : string(0) , length(0) , bufsize(0) , c_string(0) { initLength(len); } //---------------------------------------------------------------------- FString::FString (int len, wchar_t c) : string(0) , length(0) , bufsize(0) , c_string(0) { if ( len > 0 ) _replace ( FString(uInt(len), c).string ); else initLength(0); } //---------------------------------------------------------------------- FString::FString (uInt len, wchar_t c) : string(0) , length(0) , bufsize(0) , c_string(0) { register wchar_t* ps; register wchar_t* pe; initLength(len); ps = string; pe = string + len; while ( pe != ps ) *--pe = c; } //---------------------------------------------------------------------- FString::FString (int len, char c) : string(0) , length(0) , bufsize(0) , c_string(0) { string = 0; length = 0; bufsize = 0; c_string = 0; if ( len > 0 ) _replace ( FString(uInt(len), c).string ); else initLength(0); } //---------------------------------------------------------------------- FString::FString (uInt len, char c) : string(0) , length(0) , bufsize(0) , c_string(0) { register wchar_t* ps; register wchar_t* pe; initLength(len); ps = string; pe = string + len; while ( pe != ps ) *--pe = wchar_t(c); } //---------------------------------------------------------------------- FString::FString (const FString& s) // copy constructor : string(0) , length(0) , bufsize(0) , c_string(0) { if ( s.string ) _replace (s.string); } //---------------------------------------------------------------------- FString::FString (const std::wstring& s) : string(0) , length(0) , bufsize(0) , c_string(0) { if ( ! s.empty() ) _replace ( s.c_str() ); } //---------------------------------------------------------------------- FString::FString (const wchar_t* s) : string(0) , length(0) , bufsize(0) , c_string(0) { if ( s ) _replace (s); } //---------------------------------------------------------------------- FString::FString (const std::string& s) : string(0) , length(0) , bufsize(0) , c_string(0) { if ( s.empty() ) return; const wchar_t* wc_string; wc_string = c_to_wc_str(s.c_str()); if ( wc_string ) { _replace( wc_string ); delete[] wc_string; } } //---------------------------------------------------------------------- FString::FString (const char* s) : string(0) , length(0) , bufsize(0) , c_string(0) { const wchar_t* wc_string; wc_string = c_to_wc_str(s); if ( wc_string ) { _replace( wc_string ); delete[] wc_string; } } //---------------------------------------------------------------------- FString::FString (const wchar_t c) : string(0) , length(0) , bufsize(0) , c_string(0) { wchar_t s[2]; s[0] = c; s[1] = L'\0'; _replace (s); } //---------------------------------------------------------------------- FString::FString (const char c) : string(0) , length(0) , bufsize(0) , c_string(0) { wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; _replace (s); } //---------------------------------------------------------------------- FString::~FString() // destructor { if ( string ) delete[](string); if ( c_string ) delete[](c_string); } // FString operators //---------------------------------------------------------------------- FString& FString::operator = (const FString& s) { if ( s ) _replace (s.string); else clear(); return (*this); } //---------------------------------------------------------------------- FString& FString::operator = (const std::wstring& s) { if ( ! s.empty() ) _replace (s.c_str()); else clear(); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator = (const wchar_t* s) { if ( s ) _replace (s); else clear(); return (*this); } //---------------------------------------------------------------------- FString& FString::operator = (const std::string& s) { const wchar_t* wc_string = c_to_wc_str(s.c_str()); if ( wc_string ) { _replace( wc_string ); delete[] wc_string; } else clear(); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator = (const char* s) { const wchar_t* wc_string = c_to_wc_str(s); if ( wc_string ) { _replace( wc_string ); delete[] wc_string; } else clear(); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator = (const wchar_t c) { wchar_t s[2]; s[0] = c; s[1] = L'\0'; _replace (s); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator = (const char c) { wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; _replace (s); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const FString& s) { _insert (length, s.length, s.string); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const std::wstring& s) { _insert (length, uInt(s.length()), s.c_str()); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const wchar_t* s) { _insert (length, uInt(std::wcslen(s)), s); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const std::string& s) { const wchar_t* wc_string = c_to_wc_str(s.c_str()); if ( wc_string ) { _insert (length, uInt(s.length()), wc_string); delete[] wc_string; } return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const char* s) { const wchar_t* wc_string = c_to_wc_str(s); if ( wc_string ) { _insert (length, uInt(std::strlen(s)), wc_string); delete[] wc_string; } return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const wchar_t c) { wchar_t s[2]; s[0] = c; s[1] = L'\0'; _insert (length, 1, s); return (*this); } //---------------------------------------------------------------------- const FString& FString::operator += (const char c) { wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; _insert (length, 1, s); return (*this); } //---------------------------------------------------------------------- const FString FString::operator + (const FString& s) { FString tmp(string); tmp._insert (length, s.length, s.string); return (tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const std::wstring& s) { FString tmp(string); tmp._insert (length, uInt(s.length()), s.c_str()); return (tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const wchar_t* s) { FString tmp(string); tmp._insert (length, uInt(std::wcslen(s)), s); return (tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const std::string& s) { FString tmp(string); wchar_t* wc_string = c_to_wc_str(s.c_str()); if ( ! wc_string ) return (tmp); tmp._insert (length, uInt(std::wcslen(wc_string)), wc_string); delete[] wc_string; return (tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const char* s) { FString tmp(string); wchar_t* wc_string = c_to_wc_str(s); if ( ! wc_string ) return (tmp); tmp._insert (length, uInt(std::wcslen(wc_string)), wc_string); delete[] wc_string; return (tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const wchar_t c) { wchar_t s[2]; s[0] = c; s[1] = L'\0'; FString tmp(string); tmp._insert (length, 1, s); return(tmp); } //---------------------------------------------------------------------- const FString FString::operator + (const char c) { wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; FString tmp(string); tmp._insert (length, 1, s); return(tmp); } //---------------------------------------------------------------------- wchar_t& FString::operator [] (int pos) { FString& s = *this; assert ( (pos >= 0) && "Invalid index position!" ); return s[uInt(pos)]; } //---------------------------------------------------------------------- wchar_t& FString::operator [] (uInt pos) { assert ( (pos < length) && "Invalid index position!" ); if (pos >= length) throw std::out_of_range(""); return string[pos]; } //---------------------------------------------------------------------- const FString FString::operator () (uInt pos, uInt len) { assert ( (pos < length) && ((pos+len) <= length) ); FString tmp(L""); tmp._insert (0, len, string + pos); return (tmp); } // public methods of FString //---------------------------------------------------------------------- uInt FString::getUTF8length() const { uInt len; const char* s; len = 0; s = c_str(); while ( *s ) len += uInt((*s++ & 0xc0) != 0x80); return len; } //---------------------------------------------------------------------- FString& FString::sprintf (const wchar_t* format, ...) { const int buf_size = 4096; wchar_t buffer[buf_size]; va_list args; va_start (args, format); std::vswprintf (buffer, buf_size, format, args); va_end (args); _replace (buffer); return (*this); } //---------------------------------------------------------------------- FString& FString::sprintf (const char* format, ...) { const wchar_t* wc_string; char buf[1024]; char* buffer; int len; va_list args; buffer = buf; va_start (args, format); len = std::vsnprintf (buffer, sizeof(buf), format, args); va_end (args); if ( len >= int(sizeof(buf)) ) { buffer = new char[len+1](); va_start (args, format); std::vsnprintf (buffer, uLong(len+1), format, args); va_end (args); } wc_string = c_to_wc_str(buffer); if ( wc_string ) { _replace(wc_string); delete[] wc_string; } if ( buffer != buf ) delete[] buffer; return (*this); } //---------------------------------------------------------------------- FString FString::clear() { if ( string ) delete[](string); length = 0; bufsize = 0; string = 0; return (*this); } //---------------------------------------------------------------------- const wchar_t* FString::wc_str() const { return (string); } //---------------------------------------------------------------------- const char* FString::c_str() const { return wc_to_c_str (string); } //---------------------------------------------------------------------- const std::string FString::toString() const { return std::string(c_str(), length); } //---------------------------------------------------------------------- FString FString::toLower() const { register wchar_t* p; FString s(string); p = s.string; if ( p ) { while ( *p ) { *p = wchar_t(std::towlower(uInt(*p))); p++; } } return s; } //---------------------------------------------------------------------- FString FString::toUpper() const { register wchar_t* p; FString s(string); p = s.string; if ( p ) { while ( *p ) { *p = wchar_t(std::towupper(uInt(*p))); p++; } } return s; } //---------------------------------------------------------------------- sInt16 FString::toShort() const { register long num; num = toLong(); if ( num > SHRT_MAX || num < SHRT_MIN ) throw std::overflow_error ("overflow"); return sInt16(num); } //---------------------------------------------------------------------- uInt16 FString::toUShort() const { register uLong num; num = uLong(toLong()); if ( num > USHRT_MAX ) throw std::overflow_error ("overflow"); return uInt16(num); } //---------------------------------------------------------------------- int FString::toInt() const { register long num; num = toLong(); if ( num > INT_MAX || num < INT_MIN ) throw std::overflow_error ("overflow"); return int(num); } //---------------------------------------------------------------------- uInt FString::toUInt() const { register uLong num; num = uLong(toLong()); if ( num > UINT_MAX ) throw std::overflow_error ("overflow"); return uInt(num); } //---------------------------------------------------------------------- long FString::toLong() const { register long num; register long tenth_limit; register long tenth_limit_digit; register wchar_t* p; FString s; num = 0; tenth_limit = LONG_MAX / 10; tenth_limit_digit = LONG_MAX % 10; s = trim(); p = s.string; if ( ! p ) throw std::invalid_argument ("null value"); if ( ! *p ) throw std::invalid_argument ("empty value"); if ( *p == L'-' ) { p++; tenth_limit = -(LONG_MIN / 10); tenth_limit_digit += 1; } else if ( *p == L'+' ) { p++; } while ( std::iswdigit(wint_t(*p)) ) { register uChar d = uChar((*p) - L'0'); if ( num > tenth_limit || (num == tenth_limit && d > tenth_limit_digit) ) { throw std::overflow_error ("overflow"); } num = (num<<3)+(num<<1) + d; // (10 * num) + d p++; } if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) ) throw std::invalid_argument ("no valid number"); return num; } //---------------------------------------------------------------------- uLong FString::toULong() const { register uLong num; register uLong tenth_limit; register uLong tenth_limit_digit; register wchar_t* p; FString s; num = 0; tenth_limit = ULONG_MAX / 10; tenth_limit_digit = ULONG_MAX % 10; s = trim(); p = s.string; if ( ! p ) throw std::invalid_argument ("null value"); if ( ! *p ) throw std::invalid_argument ("empty value"); if ( *p == L'+' ) { p++; } while ( std::iswdigit(wint_t(*p)) ) { register uChar d = uChar((*p) - L'0'); if ( num > tenth_limit || (num == tenth_limit && d > tenth_limit_digit) ) { throw std::overflow_error ("overflow"); } num = (num<<3)+(num<<1) + d; // (10 * num) + d p++; } if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) ) throw std::invalid_argument ("no valid number"); return num; } //---------------------------------------------------------------------- float FString::toFloat() const { register double num; num = toDouble(); if ( num > FLT_MAX || num < FLT_MIN ) throw std::overflow_error ("overflow"); return float(num); } //---------------------------------------------------------------------- double FString::toDouble() const { wchar_t* p; register double ret; if ( ! string ) throw std::invalid_argument ("null value"); if ( ! *string ) throw std::invalid_argument ("empty value"); ret = std::wcstod(string, &p); if ( p != 0 && *p != '\0' ) throw std::invalid_argument ("no valid floating point value"); if ( errno == ERANGE ) { if ( ret >= HUGE_VAL || ret <= -HUGE_VAL ) throw std::overflow_error ("overflow"); if ( std::fabs(ret) < DBL_EPSILON ) // ret == 0.0l throw std::underflow_error ("underflow"); } return ret; } //---------------------------------------------------------------------- FString FString::ltrim() const { register wchar_t* p; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; p = s.string; while ( std::iswspace(uInt(*p)) ) p++; return FString(p); } //---------------------------------------------------------------------- FString FString::rtrim() const { register wchar_t* p; register wchar_t* last; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; p = s.string; last = p + length; while ( std::iswspace(uInt(*--last)) && last > p ); if ( last == p && std::iswspace(uInt(*last)) ) s.clear(); else *(last+1) = '\0'; return s; } //---------------------------------------------------------------------- FString FString::trim() const { // handle NULL and empty string if ( ! (string && *string) ) return (*this); FString s(ltrim()); return s.rtrim(); } //---------------------------------------------------------------------- FString FString::left (int len) const { if ( len > 0) return left (uInt(len)); else return left (uInt(0)); } //---------------------------------------------------------------------- FString FString::left (uInt len) const { register wchar_t* p; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; if ( len > length ) return s; p = s.string; *(p+len) = '\0'; return s; } //---------------------------------------------------------------------- FString FString::right (int len) const { if ( len > 0) return right (uInt(len)); else return right (uInt(0)); } //---------------------------------------------------------------------- FString FString::right (uInt len) const { register wchar_t* p; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; if ( len > length ) return s; p = s.string; p += (length-len); return FString(p); } //---------------------------------------------------------------------- FString FString::mid (int pos, int len) const { if ( pos > 0 ) { if ( len > 0 ) return mid (uInt(pos), uInt(len)); else return mid (uInt(pos), uInt(0)); } else return mid (uInt(0), uInt(0)); } //---------------------------------------------------------------------- FString FString::mid (uInt pos, uInt len) const { register wchar_t* p; register wchar_t* first; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; if ( pos == 0 ) pos = 1; if ( pos <= length && pos+len > length ) len = length - pos + 1; if ( pos > length || pos+len-1 > length || len == 0 ) return FString(L""); p = s.string; first = p + pos - 1; *(first+len) = '\0'; return FString(first); } //---------------------------------------------------------------------- std::vector FString::split (const FString& delimiter) { wchar_t* rest; wchar_t* token; FString s(string); std::vector stringList; // handle NULL and empty string if ( ! (string && *string) ) return stringList; rest = 0; token = extractToken(&rest, s.string, delimiter.wc_str()); while ( token ) { stringList.push_back (FString(token)); token = extractToken (&rest, 0, delimiter.wc_str()); } return stringList; } //---------------------------------------------------------------------- FString& FString::setString (const wchar_t* s) { _replace (s); return (*this); } //---------------------------------------------------------------------- FString& FString::setString (const char* s) { const wchar_t* wc_string = c_to_wc_str(s); if ( wc_string ) { _replace (wc_string); delete[] wc_string; } return (*this); } //---------------------------------------------------------------------- FString& FString::setNumber (long num) { register wchar_t* s; register bool neg; wchar_t buf[30]; s = &buf[29]; if ( num < 0 ) { neg = true; num = -num; } else { neg = false; } *s = '\0'; do { *--s = wchar_t(int(num%10) + '0'); num /= 10; } while ( num ); if ( neg ) *--s = '-'; _replace (s); return *this; } //---------------------------------------------------------------------- FString& FString::setNumber (uLong num) { register wchar_t* s; wchar_t buf[30]; s = &buf[29]; *s = '\0'; do { *--s = wchar_t(int(num%10) + '0'); num /= 10; } while ( num ); _replace (s); return *this; } //---------------------------------------------------------------------- FString& FString::setNumber (lDouble num, int precision) { register wchar_t *s; wchar_t format[20]; // = "%.Lg" s = &format[0]; *s++ = L'%'; *s++ = L'.'; if ( precision > 99 ) precision = 99; if ( precision >= 10 ) { *s++ = precision / 10 + L'0'; *s++ = precision % 10 + L'0'; } else *s++ = precision + L'0'; *s++ = L'L'; *s++ = L'g'; *s = L'\0'; return sprintf(format, num); } //---------------------------------------------------------------------- FString& FString::setFormatedNumber (long num, char separator) { register int n; register wchar_t* s; register bool neg; wchar_t buf[30]; n = 0; s = &buf[29]; if ( separator == 0 ) separator = ' '; if ( num < 0 ) { neg = true; num = -num; } else { neg = false; } *s = L'\0'; do { *--s = wchar_t(int(num%10) + '0'); num /= 10; if ( num && ++n % 3 == 0 ) *--s = separator; } while ( num ); if ( neg ) *--s = '-'; _replace (s); return *this; } //---------------------------------------------------------------------- FString& FString::setFormatedNumber (uLong num, char separator) { register int n; register wchar_t* s; wchar_t buf[30]; n = 0; s = &buf[29]; *s = L'\0'; if ( separator == 0 ) separator = ' '; do { *--s = wchar_t(int(num%10) + '0'); num /= 10; if ( num && ++n % 3 == 0 ) *--s = separator; } while ( num ); _replace (s); return *this; } // FString operators //---------------------------------------------------------------------- bool FString::operator < (const FString& s) const { if ( ! s ) return false; if ( string && ! s.string ) return false; if ( ! string && s.string ) return true; if ( ! (string || s.string) ) return false; return (std::wcscmp(string, s.string) < 0); } //---------------------------------------------------------------------- bool FString::operator < (const std::wstring& s) const { const FString tmp(s); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator < (const wchar_t* s) const { const FString tmp(s); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator < (const std::string& s) const { const FString tmp(s); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator < (const char* s) const { const FString tmp(s); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator < (const wchar_t c) const { const FString tmp(c); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator < (const char c) const { const FString tmp(c); return *this < tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const FString& s) const { if ( ! s ) return false; if ( string && ! s.string ) return false; if ( ! string && s.string ) return true; if ( ! (string || s.string) ) return true; return (std::wcscmp(string, s.string) <= 0); } //---------------------------------------------------------------------- bool FString::operator <= (const std::wstring& s) const { const FString tmp(s); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const wchar_t* s) const { const FString tmp(s); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const std::string& s) const { const FString tmp(s); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const char* s) const { const FString tmp(s); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const wchar_t c) const { const FString tmp(c); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator <= (const char c) const { const FString tmp(c); return *this <= tmp; } //---------------------------------------------------------------------- bool FString::operator == (const FString& s) const { if ( ! s ) return false; if ( (string && ! s.string ) || (! string && s.string) ) return false; if ( ! (string || s.string) ) return true; return (std::wcscmp(string, s.string) == 0); } //---------------------------------------------------------------------- bool FString::operator == (const std::wstring& s) const { const FString tmp(s); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator == (const wchar_t* s) const { const FString tmp(s); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator == (const std::string& s) const { const FString tmp(s); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator == (const char* s) const { const FString tmp(s); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator == (const wchar_t c) const { const FString tmp(c); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator == (const char c) const { const FString tmp(c); return *this == tmp; } //---------------------------------------------------------------------- bool FString::operator != (const FString& s) const { if ( ! s ) return true; if ( (string && ! s.string ) || (! string && s.string) ) return true; if ( ! (string || s.string) ) return false; return (std::wcscmp(string, s.string) != 0); } //---------------------------------------------------------------------- bool FString::operator != (const std::wstring& s) const { const FString tmp(s); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator != (const wchar_t* s) const { const FString tmp(s); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator != (const std::string& s) const { const FString tmp(s); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator != (const char* s) const { const FString tmp(s); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator != (const wchar_t c) const { const FString tmp(c); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator != (const char c) const { const FString tmp(c); return *this != tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const FString& s) const { if ( ! s ) return true; if ( string && ! s.string ) return true; if ( ! string && s.string ) return false; if ( ! (string || s.string) ) return true; return (std::wcscmp(string, s.string) >= 0); } //---------------------------------------------------------------------- bool FString::operator >= (const std::wstring& s) const { const FString tmp(s); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const wchar_t* s) const { const FString tmp(s); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const std::string& s) const { const FString tmp(s); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const char* s) const { const FString tmp(s); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const wchar_t c) const { const FString tmp(c); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator >= (const char c) const { const FString tmp(c); return *this >= tmp; } //---------------------------------------------------------------------- bool FString::operator > (const FString& s) const { if ( ! s ) return true; if ( string && ! s.string ) return true; if ( ! string && s.string ) return false; if ( ! (string || s.string) ) return false; return (std::wcscmp(string, s.string) > 0); } //---------------------------------------------------------------------- bool FString::operator > (const std::wstring& s) const { const FString tmp(s); return *this > tmp; } //---------------------------------------------------------------------- bool FString::operator > (const wchar_t* s) const { const FString tmp(s); return *this > tmp; } //---------------------------------------------------------------------- bool FString::operator > (const std::string& s) const { const FString tmp(s); return *this > tmp; } //---------------------------------------------------------------------- bool FString::operator > (const char* s) const { const FString tmp(s); return *this > tmp; } //---------------------------------------------------------------------- bool FString::operator > (const wchar_t c) const { const FString tmp(c); return *this > tmp; } //---------------------------------------------------------------------- bool FString::operator > (const char c) const { const FString tmp(c); return *this > tmp; } //---------------------------------------------------------------------- const FString& FString::insert (const FString& s, uInt pos) { // assert (pos <= length); if ( pos >= length ) throw std::out_of_range(""); _insert (pos, s.length, s.string); return (*this); } //---------------------------------------------------------------------- const FString& FString::insert (const wchar_t* s, uInt pos) { // assert (pos <= length); if ( pos >= length ) throw std::out_of_range(""); _insert (pos, uInt(std::wcslen(s)), s); return (*this); } //---------------------------------------------------------------------- const FString& FString::insert (const char* s, uInt pos) { return (insert(FString(s), pos)); } //---------------------------------------------------------------------- const FString& FString::insert (const wchar_t c, uInt pos) { return (insert(FString(c), pos)); } //---------------------------------------------------------------------- const FString& FString::insert (const char c, uInt pos) { return (insert(FString(c), pos)); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const FString& to) { register wchar_t* p; uInt from_length, to_length, pos; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; if ( from.isNull() || to.isNull() ) return s; p = s.string; from_length = from.getLength(); to_length = to.getLength(); pos = 0; while ( *p ) { if ( std::wcsncmp(p, from.string, from_length) == 0 ) { s._remove(pos, from_length); s._insert(pos, to_length, to.string); pos += to_length; p = s.string + pos; } else { pos++; p++; } } return s; } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const std::wstring& to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const wchar_t* to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const std::string& to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const char* to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const wchar_t to) { FString to_wchar(to); return replace (from, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const char to) { FString to_char(to); return replace (from, to_char); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const FString& to) { FString from_str(from); return replace (from_str, to); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const std::wstring& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const wchar_t* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const std::string& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const char* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const wchar_t to) { FString from_str(from); FString to_wchar(to); return replace (from_str, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const std::wstring& from, const char to) { FString from_str(from); FString to_char(to); return replace (from_str, to_char); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const FString& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const std::wstring& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const wchar_t* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const std::string& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const char* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const wchar_t to) { FString from_str(from); FString to_wchar(to); return replace (from_str, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const std::string& from, const char to) { FString from_str(from); FString to_char(to); return replace (from_str, to_char); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t* from, const FString& to) { FString from_str(from); return replace (from_str, to); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t* from, const std::wstring& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t* from, const wchar_t* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t* from, const wchar_t to) { FString from_str(from); FString to_wchar(to); return replace (from_str, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t* from, const char to) { FString from_str(from); FString to_char(to); return replace (from_str, to_char); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const FString& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const std::wstring& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const wchar_t* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const std::string& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const char* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const wchar_t to) { FString from_str(from); FString to_wchar(to); return replace (from_str, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const char* from, const char to) { FString from_str(from); FString to_char(to); return replace (from_str, to_char); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const FString& to) { register wchar_t* p; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; if ( to.isNull() ) return s; p = s.string; uInt to_length = to.getLength(); uInt pos = 0; while ( *p ) { if ( wchar_t(*p) == from ) { s._remove(pos, 1); s._insert(pos, to_length, to.wc_str()); pos += to_length; p = s.string + pos; } else { pos++; p++; } } return s; } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const std::wstring& to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const wchar_t* to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const std::string& to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const char* to) { FString to_str(to); return replace (from, to_str); } //---------------------------------------------------------------------- FString FString::replace (const wchar_t from, const wchar_t to) { FString to_wchar(to); return replace (from, to_wchar); } //---------------------------------------------------------------------- FString FString::replace (const char from, const FString& to) { FString from_str(from); return replace (from_str, to); } //---------------------------------------------------------------------- FString FString::replace (const char from, const std::wstring& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char from, const wchar_t* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char from, const std::string& to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char from, const char* to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char from, const wchar_t to) { FString from_str(from); FString to_str(to); return replace (from_str, to_str); } //---------------------------------------------------------------------- FString FString::replace (const char from, const char to) { register wchar_t* p; FString s(string); // handle NULL and empty string if ( ! (string && *string) ) return s; p = s.string; while ( *p ) { if ( char(*p) == from ) *p = to; p++; } return s; } //---------------------------------------------------------------------- FString FString::replaceControlCodes() const { register wchar_t* p; FString s(string); p = s.string; if ( p ) { while ( *p ) { if ( *p <= L'\x1f' ) { *p += L'\x2400'; } else if ( *p == L'\x7f' ) { *p = L'\x2421'; } else if ( *p >= L'\x80' && *p <= L'\x9f' ) { *p = L' '; } else if ( ! std::iswprint(wint_t(*p)) ) *p = L' '; p++; } } return s; } //---------------------------------------------------------------------- FString FString::expandTabs (uInt tabstop) const { uLong last; std::vector tab_split; FString instr(string); FString outstr; tab_split = instr.split("\t"); last = tab_split.size(); for (uInt i=0; i < last; i++) { uInt len = tab_split[i].getLength(); outstr += tab_split[i] + FString(tabstop - len % tabstop, L' '); } return outstr; } //---------------------------------------------------------------------- FString FString::removeDel() const { register wchar_t* p; FString s(string); p = s.string; if ( p ) { uInt i=0; uInt d=0; while ( *p ) { if ( *p == 0x7f ) { d++; } else if ( d > 0 ) { d--; } else { s.string[i] = *p; i++; } p++; } s.string[i] = L'\0'; s.length = i; } return s; } //---------------------------------------------------------------------- FString FString::removeBackspaces() const { register wchar_t* p; FString s(string); p = s.string; if ( p ) { uInt i=0; while ( *p ) { if ( *p != L'\b' ) { s.string[i] = *p; i++; } else if ( i > 0 ) { i--; } p++; } s.string[i] = L'\0'; s.length = i; } return s; } //---------------------------------------------------------------------- const FString& FString::overwrite (const FString& s, uInt pos) { if (length >= (pos + s.length)) { std::wcsncpy (string + pos, s.string, s.length); } else { std::wcsncpy (string + pos, s.string, length - pos); _insert (length, pos + s.length - length, s.string + length - pos); } return (*this); } //---------------------------------------------------------------------- const FString& FString::overwrite (const wchar_t* s, uInt pos) { uInt len = uInt(std::wcslen(s)); if (length >= (pos+len) ) { std::wcsncpy (string + pos, s, len); } else { std::wcsncpy (string + pos, s, length - pos); _insert (length, pos + len - length, s + length - pos); } return (*this); } //---------------------------------------------------------------------- const FString& FString::overwrite (const wchar_t c, uInt pos) { if ( length >= (pos+1) ) { string[pos] = c; } return (*this); } //---------------------------------------------------------------------- const FString& FString::remove (uInt pos, uInt len) { assert ((pos < length) && ((pos + len) <= length)); _remove (pos, len); return (*this); } //---------------------------------------------------------------------- bool FString::includes (const FString& s) { return (std::wcsstr(string, s.string) != 0); } //---------------------------------------------------------------------- bool FString::includes (const wchar_t* s) { return (std::wcsstr(string, s) != 0); } //---------------------------------------------------------------------- bool FString::includes (const char* s) { bool ret; const wchar_t* wc_string = c_to_wc_str(s); if ( ! wc_string ) return false; ret = bool(std::wcsstr(string, wc_string) != 0); delete[] wc_string; return (ret); } //---------------------------------------------------------------------- bool FString::includes (const wchar_t c) { wchar_t s[2]; s[0] = c; s[1] = L'\0'; return (std::wcsstr(string, s) != 0); } //---------------------------------------------------------------------- bool FString::includes (const char c) { wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; return (std::wcsstr(string, s) != 0); } // private methods of FString //---------------------------------------------------------------------- inline void FString::initLength (uInt len) { if ( len == 0 ) return; length = len; bufsize = FWDBUFFER + len + 1; string = new wchar_t[bufsize](); std::wmemset (string, L'\0', bufsize); } //---------------------------------------------------------------------- inline void FString::_replace (const wchar_t* s) { if ( string ) delete[](string); length = uInt(std::wcslen(s)); bufsize = FWDBUFFER + length + 1; try { string = new wchar_t[bufsize](); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << ex.what() << std::endl; return; } /* catch (std::exception& e) { std::cerr << "not enough memory for a new FString object " << e.what() << std::endl; return; }*/ std::wcscpy (string, s); } //---------------------------------------------------------------------- inline void FString::_insert (uInt pos, uInt len, const wchar_t* s) { if ( ! string ) { // string is null length = len; bufsize = FWDBUFFER + length + 1; try { string = new wchar_t[bufsize](); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return; } std::wcscpy (string, s); return; } else { uInt x; if ( (length + len + 1) <= bufsize ) { // output string <= bufsize for (x = length; x > pos-1; x--) // shifting right side + '\0' string[x+len] = string[x]; for (x=0; x < len; x++) // insert string string[x+pos] = s[x]; length += len; } else { wchar_t* sptr; // output string > bufsize bufsize = FWDBUFFER + length + len + 1; try { sptr = new wchar_t[bufsize](); // generate new string } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return; } uInt y = 0; for (x=0; x < pos; x++) // left side sptr[y++] = string[x]; for (x=0; x < len; x++) // insert string sptr[y++] = s[x]; for (x=pos; x < length+1; x++) // right side + '\0' sptr[y++] = string[x]; length += len; delete[](string); // delete old string string = sptr; } } } //---------------------------------------------------------------------- inline void FString::_remove (uInt pos, uInt len) { if ( (bufsize - length - 1 + len) <= FWDBUFFER ) { // shifting left side to pos for (uInt i=pos; (i+len) < length+1; i++) string[i] = string[i+len]; length -= len; } else { wchar_t* sptr; bufsize = length + 1 - len + FWDBUFFER; try { sptr = new wchar_t[bufsize](); // generate new string } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return; } uInt x, y = 0; for (x=0; x < pos; x++) // left side sptr[y++] = string[x]; for (x=pos+len; x < length+1; x++) // right side + '\0' sptr[y++] = string[x]; delete[](string); // delete old string string = sptr; length -= len; } } //---------------------------------------------------------------------- inline char* FString::wc_to_c_str (const wchar_t* s) const { int mblength, size, dest_size; const wchar_t* src; if ( ! s ) // handle NULL string return 0; if ( ! *s ) // handle empty string { try { // Generate a empty string ("") c_string = new char[1](); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return 0; } return c_string; } if ( c_string ) delete[](c_string); size = int(std::wcslen(s)) + 1; dest_size = size * int(CHAR_SIZE); src = s; std::mbstate_t state; std::memset (&state, '\0', sizeof(mbstate_t)); try { c_string = new char[dest_size](); // pre-initialiaze the whole string with '\0' std::memset (c_string, '\0', std::size_t(dest_size)); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return 0; } mblength = int(std::wcsrtombs (c_string, &src, uLong(dest_size), &state)); if ( mblength == -1 && errno != EILSEQ ) { delete[](c_string); c_string = 0; return const_cast(""); } return c_string; } //---------------------------------------------------------------------- inline wchar_t* FString::c_to_wc_str (const char* s) const { int wclength, size, dest_size; const char* src; wchar_t* dest; if ( ! s ) // handle NULL string return 0; if ( ! *s ) // handle empty string { try { // Generate a empty wide string (L"") return (new wchar_t[1]()); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return 0; } } size = int(std::strlen(s)) + 1; dest_size = size * int(CHAR_SIZE); src = s; std::mbstate_t state; std::memset (&state, '\0', sizeof(mbstate_t)); try { dest = new wchar_t[size](); // pre-initialiaze the whole string with '\0' std::wmemset (dest, L'\0', std::size_t(size)); } catch (const std::bad_alloc& ex) { std::cerr << bad_alloc_str << " " << ex.what() << std::endl; return 0; } wclength = int(std::mbsrtowcs (dest, &src, uLong(dest_size), &state)); if ( wclength == -1 ) { if ( src != s ) return dest; else { delete[] dest; return 0; } } if ( wclength == size ) dest[size-1] = '\0'; if ( wclength ) return dest; else { delete[] dest; return 0; } } //---------------------------------------------------------------------- inline wchar_t* FString::extractToken ( wchar_t** rest , const wchar_t* s , const wchar_t* delim ) { register wchar_t* token; token = ( s ) ? const_cast(s) : *rest; if ( ! *token ) return 0; *rest = std::wcspbrk(token, delim); if ( *rest ) *(*rest)++ = '\0'; else *rest = token + std::wcslen(token); return token; } // FString non-member operators //---------------------------------------------------------------------- std::ostream& operator << (std::ostream& outstr, const FString& s) { if ( s.length ) outstr << s.wc_to_c_str( s.string ); return (outstr); } //---------------------------------------------------------------------- std::istream& operator >> (std::istream& instr, FString& s) { const wchar_t* wc_str; char buf[FString::INPBUFFER + 1]; instr.getline (buf, FString::INPBUFFER); wc_str = s.c_to_wc_str(buf); if ( wc_str ) { s._replace (wc_str); delete[] wc_str; } return (instr); } //---------------------------------------------------------------------- std::wostream& operator << (std::wostream& outstr, const FString& s) { if ( s.length ) outstr << s.string; return (outstr); } //---------------------------------------------------------------------- std::wistream& operator >> (std::wistream& instr, FString& s) { wchar_t buf[FString::INPBUFFER + 1]; instr.getline (buf, FString::INPBUFFER); s._replace (buf); return (instr); } //---------------------------------------------------------------------- const FString operator + (const FString& s1, const FString& s2) { FString tmp(s1); tmp._insert ( uInt(std::wcslen(s1.wc_str())) , uInt(std::wcslen(s2.wc_str())) , s2.wc_str() ); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const FString& s, const wchar_t c) { FString tmp(s); tmp._insert ( uInt(std::wcslen(s.wc_str())), 1, &c); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const std::wstring& s1, const FString& s2) { FString tmp(s1); tmp._insert ( uInt(std::wcslen(s1.c_str())) , uInt(std::wcslen(s2.wc_str())) , s2.wc_str() ); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const wchar_t* s1, const FString& s2) { FString tmp(s1); tmp._insert ( uInt(std::wcslen(s1)) , uInt(std::wcslen(s2.wc_str())) , s2.wc_str() ); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const std::string& s1, const FString& s2) { FString tmp(s1); tmp._insert ( tmp.getLength() , uInt(std::wcslen(s2.wc_str())) , s2.wc_str() ); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const char* s1, const FString& s2) { FString tmp(s1); tmp._insert ( tmp.getLength() , uInt(std::wcslen(s2.wc_str())) , s2.wc_str() ); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const wchar_t c, const FString& s) { FString tmp(c); tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const char c, const FString& s) { FString tmp(c); tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); return (tmp); } //---------------------------------------------------------------------- const FString operator + (const wchar_t c, const std::wstring& s) { FString tmp(c); tmp._insert (1, uInt(s.length()), s.c_str()); return (tmp); }