finalcut/src/fstring.cpp

2626 lines
56 KiB
C++
Raw Normal View History

// File: fstring.cpp
// Provides: class FString
2015-05-23 13:35:12 +02:00
#include "fstring.h"
// static class constant
2017-03-17 22:59:06 +01:00
const char* const FString::bad_alloc_str = "not enough memory " \
"to alloc a new string";
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
// class FString
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
FString::FString()
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FString::FString (int len)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
if ( len > 0 )
2015-05-23 13:35:12 +02:00
initLength(uInt(len));
else
initLength(0);
}
//----------------------------------------------------------------------
FString::FString (uInt len)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
initLength(len);
}
//----------------------------------------------------------------------
FString::FString (int len, wchar_t c)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
if ( len > 0 )
_assign ( FString(uInt(len), c).string );
2015-05-23 13:35:12 +02:00
else
initLength(0);
}
//----------------------------------------------------------------------
FString::FString (uInt len, wchar_t c)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
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)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
string = 0;
length = 0;
bufsize = 0;
c_string = 0;
2015-05-26 23:15:49 +02:00
if ( len > 0 )
_assign ( FString(uInt(len), c).string );
2015-05-23 13:35:12 +02:00
else
initLength(0);
}
//----------------------------------------------------------------------
FString::FString (uInt len, char c)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
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 )
_assign (s.string);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FString::FString (const std::wstring& s)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
if ( ! s.empty() )
_assign ( s.c_str() );
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString::FString (const wchar_t* s)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
if ( s )
_assign (s);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString::FString (const std::string& s)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
if ( s.empty() )
return;
const wchar_t* wc_string;
wc_string = c_to_wc_str(s.c_str());
if ( wc_string )
2015-05-23 13:35:12 +02:00
{
_assign( wc_string );
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
FString::FString (const char* s)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
const wchar_t* wc_string;
wc_string = c_to_wc_str(s);
2015-05-23 13:35:12 +02:00
2015-09-20 05:44:50 +02:00
if ( wc_string )
2015-05-23 13:35:12 +02:00
{
_assign (wc_string);
2015-09-30 22:39:02 +02:00
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
FString::FString (const wchar_t c)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = c;
s[1] = L'\0';
_assign (s);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString::FString (const char c)
2015-09-20 05:44:50 +02:00
: string(0)
, length(0)
, bufsize(0)
, c_string(0)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = wchar_t(c & 0xff);
s[1] = L'\0';
_assign (s);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString::~FString() // destructor
{
if ( string )
delete[](string);
2015-05-23 13:35:12 +02:00
if ( c_string )
delete[](c_string);
}
// FString operators
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FString& FString::operator = (const FString& s)
2015-05-23 13:35:12 +02:00
{
if ( s )
_assign (s.string);
else
clear();
return (*this);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString& FString::operator = (const std::wstring& s)
2015-05-23 13:35:12 +02:00
{
if ( ! s.empty() )
_assign (s.c_str());
else
clear();
2015-05-23 13:35:12 +02:00
return (*this);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString& FString::operator = (const wchar_t* s)
2015-05-23 13:35:12 +02:00
{
if ( s )
_assign (s);
2015-05-23 13:35:12 +02:00
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 )
{
_assign( wc_string );
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
else
clear();
return (*this);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString& FString::operator = (const char* s)
2015-05-23 13:35:12 +02:00
{
const wchar_t* wc_string = c_to_wc_str(s);
if ( wc_string )
{
_assign( wc_string );
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
else
clear();
2015-05-23 13:35:12 +02:00
return (*this);
}
//----------------------------------------------------------------------
const FString& FString::operator = (const wchar_t c)
{
wchar_t s[2];
s[0] = c;
s[1] = L'\0';
_assign (s);
return (*this);
}
//----------------------------------------------------------------------
const FString& FString::operator = (const char c)
{
wchar_t s[2];
s[0] = wchar_t(c & 0xff);
s[1] = L'\0';
_assign (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);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString& FString::operator += (const wchar_t* s)
2015-05-23 13:35:12 +02:00
{
_insert (length, uInt(std::wcslen(s)), s);
return (*this);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
const FString& FString::operator += (const std::string& s)
{
const wchar_t* wc_string = c_to_wc_str(s.c_str());
if ( wc_string )
2015-09-30 22:39:02 +02:00
{
_insert (length, uInt(s.length()), wc_string);
delete[] wc_string;
2015-09-30 22:39:02 +02:00
}
return (*this);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
const FString& FString::operator += (const char* s)
{
const wchar_t* wc_string = c_to_wc_str(s);
2015-05-23 13:35:12 +02:00
if ( wc_string )
2015-05-23 13:35:12 +02:00
{
_insert (length, uInt(std::strlen(s)), wc_string);
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
return (*this);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
const FString& FString::operator += (const wchar_t c)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = c;
s[1] = L'\0';
_insert (length, 1, s);
return (*this);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString& FString::operator += (const char c)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = wchar_t(c & 0xff);
s[1] = L'\0';
_insert (length, 1, s);
return (*this);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const FString& s)
2015-05-23 13:35:12 +02:00
{
FString tmp(string);
tmp._insert (length, s.length, s.string);
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const std::wstring& s)
2015-05-23 13:35:12 +02:00
{
FString tmp(string);
tmp._insert (length, uInt(s.length()), s.c_str());
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const wchar_t* s)
2015-05-23 13:35:12 +02:00
{
FString tmp(string);
tmp._insert (length, uInt(std::wcslen(s)), s);
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const std::string& s)
2015-05-23 13:35:12 +02:00
{
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);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const char* s)
2015-05-23 13:35:12 +02:00
{
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);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const wchar_t c)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = c;
s[1] = L'\0';
FString tmp(string);
tmp._insert (length, 1, s);
return(tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString FString::operator + (const char c)
2015-05-23 13:35:12 +02:00
{
wchar_t s[2];
s[0] = wchar_t(c & 0xff);
s[1] = L'\0';
FString tmp(string);
tmp._insert (length, 1, s);
return(tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
wchar_t& FString::operator [] (int pos)
2015-05-23 13:35:12 +02:00
{
FString& s = *this;
assert ( (pos >= 0) && "Invalid index position!" );
return s[uInt(pos)];
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
wchar_t& FString::operator [] (uInt pos)
2015-05-23 13:35:12 +02:00
{
assert ( (pos < length) && "Invalid index position!" );
if (pos >= length)
throw std::out_of_range("");
return string[pos];
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString& FString::operator () ()
2015-05-23 13:35:12 +02:00
{
return (*this);
2015-05-23 13:35:12 +02:00
}
// public methods of FString
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
uInt FString::getUTF8length() const
2015-05-23 13:35:12 +02:00
{
uInt len;
const char* s;
2015-05-23 13:35:12 +02:00
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);
2015-05-23 13:35:12 +02:00
va_end (args);
_assign (buffer);
2015-05-23 13:35:12 +02:00
return (*this);
}
//----------------------------------------------------------------------
FString& FString::sprintf (const char* format, ...)
{
2015-09-20 05:44:50 +02:00
const wchar_t* wc_string;
2015-05-23 13:35:12 +02:00
char buf[1024];
char* buffer;
int len;
va_list args;
buffer = buf;
va_start (args, format);
2017-03-26 20:40:04 +02:00
len = vsnprintf (buffer, sizeof(buf), format, args);
2015-05-23 13:35:12 +02:00
va_end (args);
if ( len >= int(sizeof(buf)) )
{
2015-09-30 22:39:02 +02:00
buffer = new char[len+1]();
2015-05-23 13:35:12 +02:00
va_start (args, format);
2017-03-26 20:40:04 +02:00
vsnprintf (buffer, uLong(len+1), format, args);
2015-05-23 13:35:12 +02:00
va_end (args);
}
2015-09-20 05:44:50 +02:00
wc_string = c_to_wc_str(buffer);
2015-09-20 05:44:50 +02:00
if ( wc_string )
2015-05-23 13:35:12 +02:00
{
_assign(wc_string);
2015-09-30 22:39:02 +02:00
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
if ( buffer != buf )
delete[] buffer;
return (*this);
}
//----------------------------------------------------------------------
FString FString::clear()
{
if ( string )
delete[](string);
2015-05-23 13:35:12 +02:00
length = 0;
bufsize = 0;
string = 0;
return (*this);
}
//----------------------------------------------------------------------
const wchar_t* FString::wc_str() const
{
return (string);
}
//----------------------------------------------------------------------
const char* FString::c_str() const
{
if ( string )
return wc_to_c_str (string);
else
return 0;
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const std::string FString::toString() const
{
return std::string(c_str(), length);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FString FString::toLower() const
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
p = s.string;
if ( p )
{
while ( *p )
{
*p = wchar_t(std::towlower(wint_t(*p)));
2015-05-23 13:35:12 +02:00
p++;
}
}
2015-05-23 13:35:12 +02:00
return s;
}
//----------------------------------------------------------------------
FString FString::toUpper() const
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
p = s.string;
if ( p )
{
while ( *p )
{
*p = wchar_t(std::towupper(wint_t(*p)));
2015-05-23 13:35:12 +02:00
p++;
}
}
2015-05-23 13:35:12 +02:00
return s;
}
//----------------------------------------------------------------------
sInt16 FString::toShort() const
{
register long num;
2015-09-22 04:18:20 +02:00
num = toLong();
if ( num > SHRT_MAX || num < SHRT_MIN )
throw std::overflow_error ("overflow");
return sInt16(num);
}
//----------------------------------------------------------------------
uInt16 FString::toUShort() const
{
register uLong num;
2015-09-22 04:18:20 +02:00
num = uLong(toLong());
if ( num > USHRT_MAX )
throw std::overflow_error ("overflow");
return uInt16(num);
}
//----------------------------------------------------------------------
int FString::toInt() const
{
register long num;
2015-09-22 04:18:20 +02:00
num = toLong();
if ( num > INT_MAX || num < INT_MIN )
throw std::overflow_error ("overflow");
return int(num);
}
//----------------------------------------------------------------------
uInt FString::toUInt() const
{
register uLong num;
2015-09-22 04:18:20 +02:00
num = uLong(toLong());
if ( num > UINT_MAX )
throw std::overflow_error ("overflow");
return uInt(num);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
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;
2015-09-22 04:18:20 +02:00
s = trim();
2015-05-23 13:35:12 +02:00
p = s.string;
if ( ! p )
throw std::invalid_argument ("null value");
if ( ! *p )
throw std::invalid_argument ("empty value");
if ( *p == L'-' )
2015-05-23 13:35:12 +02:00
{
p++;
tenth_limit = -(LONG_MIN / 10);
tenth_limit_digit += 1;
}
else if ( *p == L'+' )
{
p++;
}
2016-11-20 18:26:15 +01:00
while ( std::iswdigit(wint_t(*p)) )
{
register uChar d = uChar((*p) - L'0');
if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) )
2015-05-23 13:35:12 +02:00
{
throw std::overflow_error ("overflow");
2015-05-23 13:35:12 +02:00
}
num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++;
2015-05-23 13:35:12 +02:00
}
2016-11-20 18:26:15 +01:00
if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) )
throw std::invalid_argument ("no valid number");
2015-05-23 13:35:12 +02:00
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;
2015-09-22 04:18:20 +02:00
s = trim();
2015-05-23 13:35:12 +02:00
p = s.string;
if ( ! p )
throw std::invalid_argument ("null value");
if ( ! *p )
throw std::invalid_argument ("empty value");
if ( *p == L'+' )
2015-05-23 13:35:12 +02:00
{
p++;
}
2016-11-20 18:26:15 +01:00
while ( std::iswdigit(wint_t(*p)) )
{
register uChar d = uChar((*p) - L'0');
if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) )
2015-05-23 13:35:12 +02:00
{
throw std::overflow_error ("overflow");
2015-05-23 13:35:12 +02:00
}
num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++;
2015-05-23 13:35:12 +02:00
}
2016-11-20 18:26:15 +01:00
if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) )
throw std::invalid_argument ("no valid number");
2015-05-23 13:35:12 +02:00
return num;
}
//----------------------------------------------------------------------
float FString::toFloat() const
{
register double num;
2015-09-22 04:18:20 +02:00
num = toDouble();
if ( num > double(FLT_MAX) || num < double(FLT_MIN) )
throw std::overflow_error ("overflow");
return float(num);
}
//----------------------------------------------------------------------
double FString::toDouble() const
{
wchar_t* p;
register double ret;
2015-09-22 04:18:20 +02:00
if ( ! string )
throw std::invalid_argument ("null value");
2015-09-22 04:18:20 +02:00
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FString FString::ltrim() const
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
p = s.string;
while ( std::iswspace(wint_t(*p)) )
2015-05-23 13:35:12 +02:00
p++;
2015-05-23 13:35:12 +02:00
return FString(p);
}
//----------------------------------------------------------------------
FString FString::rtrim() const
{
register wchar_t* p;
register wchar_t* last;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
p = s.string;
last = p + length;
while ( std::iswspace(wint_t(*--last)) && last > p );
if ( last == p && std::iswspace(wint_t(*last)) )
2015-05-23 13:35:12 +02:00
s.clear();
else
*(last+1) = '\0';
return s;
}
//----------------------------------------------------------------------
FString FString::trim() const
{
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return (*this);
2015-09-22 04:18:20 +02:00
FString s(ltrim());
2015-05-23 13:35:12 +02:00
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
2015-05-23 13:35:12 +02:00
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
if ( len > length )
return s;
2015-05-23 13:35:12 +02:00
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
2015-05-23 13:35:12 +02:00
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
if ( len > length )
return s;
2015-05-23 13:35:12 +02:00
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
2015-05-23 13:35:12 +02:00
{
register wchar_t* p;
register wchar_t* first;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
if ( pos == 0 )
pos = 1;
2015-05-23 13:35:12 +02:00
if ( pos <= length && pos+len > length )
len = length - pos + 1;
2015-05-23 13:35:12 +02:00
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> FString::split (const FString& delimiter)
{
wchar_t* rest;
wchar_t* token;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
std::vector<FString> stringList;
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return stringList;
rest = 0;
token = extractToken(&rest, s.string, delimiter.wc_str());
while ( token )
{
2015-05-28 22:48:15 +02:00
stringList.push_back (FString(token));
token = extractToken (&rest, 0, delimiter.wc_str());
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
return stringList;
}
//----------------------------------------------------------------------
FString& FString::setString (const wchar_t* s)
{
_assign (s);
2015-05-23 13:35:12 +02:00
return (*this);
}
//----------------------------------------------------------------------
FString& FString::setString (const char* s)
{
2015-09-20 05:44:50 +02:00
const wchar_t* wc_string = c_to_wc_str(s);
2015-09-20 05:44:50 +02:00
if ( wc_string )
2015-05-23 13:35:12 +02:00
{
_assign (wc_string);
2015-09-30 22:39:02 +02:00
delete[] wc_string;
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
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;
}
2015-05-23 13:35:12 +02:00
*s = '\0';
2015-05-23 13:35:12 +02:00
do
{
*--s = L"0123456789"[num % 10];
2015-05-23 13:35:12 +02:00
num /= 10;
}
while ( num );
2015-05-23 13:35:12 +02:00
if ( neg )
*--s = '-';
_assign (s);
2015-05-23 13:35:12 +02:00
return *this;
}
//----------------------------------------------------------------------
FString& FString::setNumber (uLong num)
{
register wchar_t* s;
wchar_t buf[30];
s = &buf[29];
*s = '\0';
do
{
*--s = L"0123456789"[num % 10];
2015-05-23 13:35:12 +02:00
num /= 10;
}
while ( num );
2015-05-23 13:35:12 +02:00
_assign (s);
2015-05-23 13:35:12 +02:00
return *this;
}
//----------------------------------------------------------------------
FString& FString::setNumber (lDouble num, int precision)
{
register wchar_t *s;
wchar_t format[20]; // = "%.<precision>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);
}
//----------------------------------------------------------------------
2015-05-23 13:35:12 +02:00
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 = ' ';
2015-05-23 13:35:12 +02:00
if ( num < 0 )
{
neg = true;
num = -num;
}
else
{
neg = false;
}
2015-05-23 13:35:12 +02:00
*s = L'\0';
2015-05-23 13:35:12 +02:00
do
{
*--s = L"0123456789"[num % 10];
2015-05-23 13:35:12 +02:00
num /= 10;
2015-05-23 13:35:12 +02:00
if ( num && ++n % 3 == 0 )
*--s = separator;
}
while ( num );
2015-05-23 13:35:12 +02:00
if ( neg )
*--s = '-';
_assign (s);
2015-05-23 13:35:12 +02:00
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 = ' ';
2015-05-23 13:35:12 +02:00
do
{
*--s = L"0123456789"[num % 10];
2015-05-23 13:35:12 +02:00
num /= 10;
2015-05-23 13:35:12 +02:00
if ( num && ++n % 3 == 0 )
*--s = separator;
}
while ( num );
2015-05-23 13:35:12 +02:00
_assign (s);
2015-05-23 13:35:12 +02:00
return *this;
}
// FString operators
//----------------------------------------------------------------------
bool FString::operator < (const FString& s) const
{
if ( ! s )
return false;
2015-05-23 13:35:12 +02:00
if ( string && ! s.string )
return false;
2015-05-23 13:35:12 +02:00
if ( ! string && s.string )
return true;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return false;
return (std::wcscmp(string, s.string) < 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FString::operator <= (const FString& s) const
{
if ( ! s )
return false;
2015-05-23 13:35:12 +02:00
if ( string && ! s.string )
return false;
2015-05-23 13:35:12 +02:00
if ( ! string && s.string )
return true;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return true;
return (std::wcscmp(string, s.string) <= 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FString::operator == (const FString& s) const
{
if ( ! s )
return false;
2015-05-23 13:35:12 +02:00
if ( (string && ! s.string ) || (! string && s.string) )
return false;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return true;
return (std::wcscmp(string, s.string) == 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FString::operator != (const FString& s) const
{
if ( ! s )
return true;
2015-05-23 13:35:12 +02:00
if ( (string && ! s.string ) || (! string && s.string) )
return true;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return false;
return (std::wcscmp(string, s.string) != 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FString::operator >= (const FString& s) const
{
if ( ! s )
return true;
2015-05-23 13:35:12 +02:00
if ( string && ! s.string )
return true;
2015-05-23 13:35:12 +02:00
if ( ! string && s.string )
return false;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return true;
return (std::wcscmp(string, s.string) >= 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
bool FString::operator > (const FString& s) const
{
if ( ! s )
return true;
2015-05-23 13:35:12 +02:00
if ( string && ! s.string )
return true;
2015-05-23 13:35:12 +02:00
if ( ! string && s.string )
return false;
if ( ! (string || s.string) )
2015-05-23 13:35:12 +02:00
return false;
return (std::wcscmp(string, s.string) > 0);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------
2015-05-23 13:35:12 +02:00
const FString& FString::insert (const FString& s, uInt pos)
{
// assert (pos <= length);
if ( pos >= length )
throw std::out_of_range("");
2015-05-23 13:35:12 +02:00
_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);
2015-05-23 13:35:12 +02:00
return (*this);
}
//----------------------------------------------------------------------
const FString& FString::insert (const char* s, uInt pos)
{
return (insert(FString(s), pos));
}
2015-05-28 22:48:15 +02:00
//----------------------------------------------------------------------
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));
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FString FString::replace (const FString& from, const FString& to)
{
register wchar_t* p;
uInt from_length, to_length, pos;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
if ( from.isNull() || to.isNull() )
return s;
2015-05-23 13:35:12 +02:00
p = s.string;
from_length = from.getLength();
to_length = to.getLength();
pos = 0;
2015-05-23 13:35:12 +02:00
while ( *p )
{
if ( std::wcsncmp(p, from.string, from_length) == 0 )
2015-05-23 13:35:12 +02:00
{
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;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
2015-05-23 13:35:12 +02:00
if ( to.isNull() )
return s;
2015-05-23 13:35:12 +02:00
p = s.string;
uInt to_length = to.getLength();
uInt pos = 0;
2015-05-23 13:35:12 +02:00
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++;
}
}
2015-05-23 13:35:12 +02:00
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;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
// handle NULL and empty string
if ( ! (string && *string) )
2015-05-23 13:35:12 +02:00
return s;
p = s.string;
2015-05-23 13:35:12 +02:00
while ( *p )
{
if ( char(*p) == from )
*p = to;
2015-05-23 13:35:12 +02:00
p++;
}
2015-05-23 13:35:12 +02:00
return s;
}
//----------------------------------------------------------------------
FString FString::replaceControlCodes() const
{
register wchar_t* p;
2015-09-22 04:18:20 +02:00
FString s(string);
2015-05-23 13:35:12 +02:00
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;
}
//----------------------------------------------------------------------
2017-03-26 20:40:04 +02:00
FString FString::expandTabs (int tabstop) const
{
uLong last;
std::vector<FString> tab_split;
FString instr(string);
FString outstr;
2017-03-26 20:40:04 +02:00
if ( tabstop <= 0 )
return instr;
tab_split = instr.split("\t");
last = tab_split.size();
for (uInt i=0; i < last; i++)
{
uInt len = tab_split[i].getLength();
2017-03-26 20:40:04 +02:00
uInt tab_len = uInt(tabstop);
outstr += tab_split[i] + FString(tab_len - (len % tab_len), 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::_assign (const wchar_t* s)
{
if ( s == string )
return;
uInt new_length = uInt(std::wcslen(s));
if ( ! string || new_length > bufsize - 1 )
{
if ( string )
delete[](string);
bufsize = FWDBUFFER + new_length + 1;
try
{
string = new wchar_t[bufsize]();
}
catch (const std::bad_alloc& ex)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
return;
}
}
2017-04-11 00:30:27 +02:00
std::wcsncpy (string, s, bufsize);
length = new_length;
}
//----------------------------------------------------------------------
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;
}
2017-04-11 00:30:27 +02:00
std::wcsncpy (string, s, bufsize);
return;
}
else
{
uInt x;
if ( (length + len + 1) <= bufsize )
{
// output string <= bufsize
for (x = length; x+1 > pos; 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<char*>("");
}
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));
2015-05-23 13:35:12 +02:00
if ( wclength == -1 )
2015-05-23 13:35:12 +02:00
{
if ( src != s )
return dest;
else
2015-05-23 13:35:12 +02:00
{
delete[] dest;
return 0;
2015-05-23 13:35:12 +02:00
}
}
if ( wclength == size )
dest[size-1] = '\0';
if ( wclength )
return dest;
else
2015-05-23 13:35:12 +02:00
{
delete[] dest;
return 0;
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
inline wchar_t* FString::extractToken ( wchar_t** rest
, const wchar_t* s
, const wchar_t* delim )
2015-05-23 13:35:12 +02:00
{
register wchar_t* token;
token = ( s ) ? const_cast<wchar_t*>(s) : *rest;
2015-05-23 13:35:12 +02:00
if ( ! *token )
return 0;
2015-05-23 13:35:12 +02:00
*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);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
std::istream& operator >> (std::istream& instr, FString& s)
2015-05-23 13:35:12 +02:00
{
const wchar_t* wc_str;
char buf[FString::INPBUFFER + 1];
2015-05-23 13:35:12 +02:00
instr.getline (buf, FString::INPBUFFER);
wc_str = s.c_to_wc_str(buf);
2015-05-23 13:35:12 +02:00
if ( wc_str )
2015-05-23 13:35:12 +02:00
{
s._assign (wc_str);
delete[] wc_str;
2015-05-23 13:35:12 +02:00
}
return (instr);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
std::wostream& operator << (std::wostream& outstr, const FString& s)
2015-05-23 13:35:12 +02:00
{
if ( s.length )
outstr << s.string;
return (outstr);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
std::wistream& operator >> (std::wistream& instr, FString& s)
2015-05-23 13:35:12 +02:00
{
wchar_t buf[FString::INPBUFFER + 1];
instr.getline (buf, FString::INPBUFFER);
s._assign (buf);
return (instr);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const FString& s1, const FString& s2)
2015-05-23 13:35:12 +02:00
{
FString tmp(s1);
tmp._insert ( uInt(std::wcslen(s1.wc_str()))
, uInt(std::wcslen(s2.wc_str()))
, s2.wc_str() );
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const FString& s, const wchar_t c)
2015-05-23 13:35:12 +02:00
{
FString tmp(s);
tmp._insert ( uInt(std::wcslen(s.wc_str())), 1, &c);
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const std::wstring& s1, const FString& s2)
2015-05-23 13:35:12 +02:00
{
FString tmp(s1);
tmp._insert ( uInt(std::wcslen(s1.c_str()))
, uInt(std::wcslen(s2.wc_str()))
, s2.wc_str() );
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const wchar_t* s1, const FString& s2)
2015-05-23 13:35:12 +02:00
{
FString tmp(s1);
tmp._insert ( uInt(std::wcslen(s1))
, uInt(std::wcslen(s2.wc_str()))
, s2.wc_str() );
return (tmp);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const std::string& s1, const FString& s2)
2015-05-23 13:35:12 +02:00
{
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);
2015-05-23 13:35:12 +02:00
}
2015-05-28 22:48:15 +02:00
//----------------------------------------------------------------------
const FString operator + (const char c, const FString& s)
2015-05-28 22:48:15 +02:00
{
FString tmp(c);
tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str());
return (tmp);
2015-05-28 22:48:15 +02:00
}
//----------------------------------------------------------------------
const FString operator + (const wchar_t c, const std::wstring& s)
2015-05-28 22:48:15 +02:00
{
FString tmp(c);
tmp._insert (1, uInt(s.length()), s.c_str());
return (tmp);
2015-05-28 22:48:15 +02:00
}