2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2004-06-11 04:55:09 +02:00
|
|
|
#ifndef CStr_CPP_FIRST
|
|
|
|
#define CStr_CPP_FIRST
|
|
|
|
|
2003-11-30 17:39:22 +01:00
|
|
|
#include "Network/Serialization.h"
|
2004-06-03 03:43:33 +02:00
|
|
|
#include <cassert>
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-06-11 04:55:09 +02:00
|
|
|
#define UNIDOUBLER_HEADER "CStr.cpp"
|
|
|
|
#include "UniDoubler.h"
|
|
|
|
|
2004-09-06 13:15:43 +02:00
|
|
|
// Only include these function definitions in the first instance of CStr.cpp:
|
2004-10-31 21:29:09 +01:00
|
|
|
CStrW::CStrW(const CStr8 &asciStr) : std::wstring(asciStr.begin(), asciStr.end()) {}
|
2004-12-05 19:26:43 +01:00
|
|
|
CStr8::CStr8(const CStrW &wideStr) : std:: string(wideStr.begin(), wideStr.end()) {}
|
2004-09-06 13:15:43 +02:00
|
|
|
|
2005-01-12 15:31:47 +01:00
|
|
|
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
|
|
|
CStr8 CStrW::utf8() const
|
|
|
|
{
|
|
|
|
// Adapted from http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
|
|
|
|
|
|
|
|
CStr8 result;
|
|
|
|
|
|
|
|
const wchar_t* source = &*begin();
|
|
|
|
for (size_t i = 0; i < Length(); ++i)
|
|
|
|
{
|
|
|
|
unsigned short bytesToWrite;
|
|
|
|
wchar_t ch = (*this)[i];
|
|
|
|
|
|
|
|
if (ch < 0x80) bytesToWrite = 1;
|
|
|
|
else if (ch < 0x800) bytesToWrite = 2;
|
|
|
|
else if (ch < 0x10000) bytesToWrite = 3;
|
|
|
|
else if (ch <= 0x7FFFFFFF) bytesToWrite = 4;
|
|
|
|
else bytesToWrite = 3, ch = 0x0000FFFD; // replacement character
|
|
|
|
|
|
|
|
char buf[4];
|
|
|
|
char* target = &buf[bytesToWrite];
|
|
|
|
switch (bytesToWrite)
|
|
|
|
{
|
|
|
|
case 4: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
|
|
|
case 3: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
|
|
|
case 2: *--target = ((ch | 0x80) & 0xBF); ch >>= 6;
|
|
|
|
case 1: *--target = (ch | firstByteMark[bytesToWrite]);
|
|
|
|
}
|
|
|
|
result += CStr(buf, bytesToWrite);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-11 04:55:09 +02:00
|
|
|
#else
|
|
|
|
|
|
|
|
#include "CStr.h"
|
|
|
|
using namespace std;
|
|
|
|
|
2004-06-18 15:22:26 +02:00
|
|
|
#include <sstream>
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Construction and assignment from numbers:
|
|
|
|
|
|
|
|
#define NUM_TYPE(T) \
|
|
|
|
CStr::CStr(T Number) \
|
|
|
|
{ \
|
|
|
|
std::tstringstream ss; \
|
|
|
|
ss << Number; \
|
|
|
|
ss >> *this; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CStr& CStr::operator=(T Number) \
|
|
|
|
{ \
|
|
|
|
std::tstringstream ss; \
|
|
|
|
ss << Number; \
|
|
|
|
ss >> *this; \
|
|
|
|
return *this; \
|
|
|
|
}
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
NUM_TYPE(int)
|
|
|
|
NUM_TYPE(long)
|
|
|
|
NUM_TYPE(unsigned int)
|
|
|
|
NUM_TYPE(unsigned long)
|
|
|
|
NUM_TYPE(float)
|
|
|
|
NUM_TYPE(double)
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
#undef NUM_TYPE
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Conversion to numbers:
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-06-01 18:51:37 +02:00
|
|
|
int CStr::ToInt() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return _ttoi(c_str());
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-06-01 18:51:37 +02:00
|
|
|
unsigned int CStr::ToUInt() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return uint(_ttoi(c_str()));
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-06-01 18:51:37 +02:00
|
|
|
long CStr::ToLong() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return _ttol(c_str());
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-06-01 18:51:37 +02:00
|
|
|
unsigned long CStr::ToULong() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return ulong(_ttol(c_str()));
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-06-01 18:51:37 +02:00
|
|
|
float CStr::ToFloat() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return (float)_tstod(c_str(), NULL);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
double CStr::ToDouble() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return _tstod(c_str(), NULL);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Retrieves at most 'len' characters, starting at 'start'
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr CStr::GetSubstring(size_t start, size_t len) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return substr(start, len);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Search the string for another string
|
2004-06-18 15:22:26 +02:00
|
|
|
long CStr::Find(const CStr& Str) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t Pos = find(Str, 0);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
if (Pos != npos)
|
2004-06-21 18:29:47 +02:00
|
|
|
return (long)Pos;
|
2003-10-03 16:10:38 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Search the string for another string
|
2004-06-01 18:51:37 +02:00
|
|
|
long CStr::Find(const TCHAR &tchar) const
|
2004-05-29 05:53:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t Pos = find(tchar, 0);
|
2004-05-29 05:53:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
if (Pos != npos)
|
2004-06-21 18:29:47 +02:00
|
|
|
return (long)Pos;
|
2004-05-29 05:53:38 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Search the string for another string
|
2004-06-01 18:51:37 +02:00
|
|
|
long CStr::Find(const int &start, const TCHAR &tchar) const
|
2004-05-29 05:53:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t Pos = find(tchar, start);
|
2004-05-29 05:53:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
if (Pos != npos)
|
2004-06-21 18:29:47 +02:00
|
|
|
return (long)Pos;
|
2004-05-29 05:53:38 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2004-12-09 17:54:02 +01:00
|
|
|
long CStr::FindInsensitive(const int &start, const TCHAR &tchar) const { return LCase().Find(start, _totlower(tchar)); }
|
|
|
|
long CStr::FindInsensitive(const TCHAR &tchar) const { return LCase().Find(_totlower(tchar)); }
|
|
|
|
long CStr::FindInsensitive(const CStr& Str) const { return LCase().Find(Str.LCase()); }
|
|
|
|
|
|
|
|
|
2004-06-18 15:22:26 +02:00
|
|
|
long CStr::ReverseFind(const CStr& Str) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t Pos = rfind(Str, length() );
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
if (Pos != npos)
|
2004-06-21 18:29:47 +02:00
|
|
|
return (long)Pos;
|
2003-10-03 16:10:38 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lowercase and uppercase
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr CStr::LowerCase() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
tstring NewString = *this;
|
|
|
|
for (size_t i = 0; i < length(); i++)
|
|
|
|
NewString[i] = (TCHAR)_totlower((*this)[i]);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
return NewString;
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr CStr::UpperCase() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
tstring NewString = *this;
|
|
|
|
for (size_t i = 0; i < length(); i++)
|
|
|
|
NewString[i] = (TCHAR)_totupper((*this)[i]);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
return NewString;
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Lazy versions
|
2004-10-31 21:29:09 +01:00
|
|
|
// code duplication because return by value overhead if they were merely an alias
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr CStr::LCase() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
tstring NewString = *this;
|
|
|
|
for (size_t i = 0; i < length(); i++)
|
|
|
|
NewString[i] = (TCHAR)_totlower((*this)[i]);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
return NewString;
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr CStr::UCase() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
tstring NewString = *this;
|
|
|
|
for (size_t i = 0; i < length(); i++)
|
|
|
|
NewString[i] = (TCHAR)_totupper((*this)[i]);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
return NewString;
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Retrieve the substring of the first n characters
|
2005-01-12 15:31:47 +01:00
|
|
|
CStr CStr::Left(size_t len) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2005-01-12 15:31:47 +01:00
|
|
|
assert(len <= length());
|
2004-10-31 21:29:09 +01:00
|
|
|
return substr(0, len);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Retrieve the substring of the last n characters
|
2005-01-12 15:31:47 +01:00
|
|
|
CStr CStr::Right(size_t len) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2005-01-12 15:31:47 +01:00
|
|
|
assert(len <= length());
|
2004-10-31 21:29:09 +01:00
|
|
|
return substr(length()-len, len);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Remove all occurrences of some character or substring
|
2004-06-18 15:22:26 +02:00
|
|
|
void CStr::Remove(const CStr& Str)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2003-11-30 17:39:22 +01:00
|
|
|
size_t FoundAt = 0;
|
2004-10-31 21:29:09 +01:00
|
|
|
while (FoundAt != npos)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
FoundAt = find(Str, 0);
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
if (FoundAt != npos)
|
|
|
|
erase(FoundAt, Str.length());
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Replace all occurrences of some substring by another
|
2004-06-18 15:22:26 +02:00
|
|
|
void CStr::Replace(const CStr& ToReplace, const CStr& ReplaceWith)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2003-11-30 17:39:22 +01:00
|
|
|
size_t Pos = 0;
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
while (Pos != npos)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
Pos = find(ToReplace, Pos);
|
|
|
|
if (Pos != npos)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
erase(Pos, ToReplace.length());
|
|
|
|
insert(Pos, ReplaceWith);
|
|
|
|
Pos += ReplaceWith.length();
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-28 14:13:27 +01:00
|
|
|
CStr CStr::UnescapeBackslashes()
|
|
|
|
{
|
|
|
|
// Currently only handle \n and \\, because they're the only interesting ones
|
|
|
|
CStr NewString;
|
|
|
|
bool escaping = false;
|
|
|
|
for (size_t i = 0; i < length(); i++)
|
|
|
|
{
|
|
|
|
TCHAR ch = (*this)[i];
|
|
|
|
if (escaping)
|
|
|
|
{
|
|
|
|
switch (ch)
|
|
|
|
{
|
|
|
|
case _T('n'): NewString += _T('\n'); break;
|
|
|
|
default: NewString += ch; break;
|
|
|
|
}
|
|
|
|
escaping = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ch == _T('\\'))
|
|
|
|
escaping = true;
|
|
|
|
else
|
|
|
|
NewString += ch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NewString;
|
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Returns a trimmed string, removes whitespace from the left/right/both
|
|
|
|
CStr CStr::Trim(PS_TRIM_MODE Mode) const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-06-21 18:29:47 +02:00
|
|
|
size_t Left = 0, Right = 0;
|
2003-10-03 16:10:38 +02:00
|
|
|
|
|
|
|
switch (Mode)
|
|
|
|
{
|
|
|
|
case PS_TRIM_LEFT:
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
for (Left = 0; Left < length(); Left++)
|
|
|
|
if (_istspace((*this)[Left]) == false)
|
2003-10-03 16:10:38 +02:00
|
|
|
break; // end found, trim 0 to Left-1 inclusive
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case PS_TRIM_RIGHT:
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
Right = length();
|
2003-12-01 13:14:21 +01:00
|
|
|
while (Right--)
|
2004-10-31 21:29:09 +01:00
|
|
|
if (_istspace((*this)[Right]) == false)
|
2003-10-03 16:10:38 +02:00
|
|
|
break; // end found, trim len-1 to Right+1 inclusive
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case PS_TRIM_BOTH:
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
for (Left = 0; Left < length(); Left++)
|
|
|
|
if (_istspace((*this)[Left]) == false)
|
2003-10-03 16:10:38 +02:00
|
|
|
break; // end found, trim 0 to Left-1 inclusive
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
Right = length();
|
2003-12-01 13:14:21 +01:00
|
|
|
while (Right--)
|
2004-10-31 21:29:09 +01:00
|
|
|
if (_istspace((*this)[Right]) == false)
|
2003-10-03 16:10:38 +02:00
|
|
|
break; // end found, trim len-1 to Right+1 inclusive
|
|
|
|
} break;
|
2004-06-21 18:29:47 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
debug_warn("CStr::Trim: invalid Mode");
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
return substr(Left, Right-Left+1);
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Concatenation:
|
2003-10-03 16:10:38 +02:00
|
|
|
|
2004-06-18 15:22:26 +02:00
|
|
|
CStr CStr::operator+(const CStr& Str)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return std::operator+(*this, std::tstring(Str));
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr CStr::operator+(const TCHAR* Str)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return std::operator+(*this, std::tstring(Str));
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Joining ASCII and Unicode strings:
|
|
|
|
#ifndef _UNICODE
|
|
|
|
CStr8 CStr::operator+(const CStrW& Str)
|
2003-11-24 03:18:41 +01:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return std::operator+(*this, CStr8(Str));
|
2003-11-24 03:18:41 +01:00
|
|
|
}
|
2004-10-31 21:29:09 +01:00
|
|
|
#else
|
|
|
|
CStrW CStr::operator+(const CStr8& Str)
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return std::operator+(*this, CStrW(Str));
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
2004-10-31 21:29:09 +01:00
|
|
|
#endif
|
2003-10-03 16:10:38 +02:00
|
|
|
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr::operator const TCHAR*() const
|
2003-10-03 16:10:38 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return c_str();
|
2003-10-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2003-11-30 17:39:22 +01:00
|
|
|
|
2004-05-22 01:46:16 +02:00
|
|
|
size_t CStr::GetHashCode() const
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return (size_t)fnv_hash64(data(), length());
|
2004-05-24 22:25:48 +02:00
|
|
|
// janwas asks: do we care about the hash being 64 bits?
|
|
|
|
// it is truncated here on 32-bit systems; why go 64 bit at all?
|
2004-05-22 01:46:16 +02:00
|
|
|
}
|
|
|
|
|
2004-08-16 17:19:17 +02:00
|
|
|
#ifdef _UNICODE
|
|
|
|
/*
|
|
|
|
CStrW is always serialized to/from UTF-16
|
|
|
|
*/
|
|
|
|
|
|
|
|
u8 *CStrW::Serialize(u8 *buffer) const
|
2003-11-30 17:39:22 +01:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t len = length();
|
|
|
|
size_t i = 0;
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
*(u16 *)(buffer + i*2) = htons((*this)[i]); // convert to network order (big-endian)
|
|
|
|
*(u16 *)(buffer+i*2) = 0;
|
|
|
|
return buffer+len*2+2;
|
2003-11-30 17:39:22 +01:00
|
|
|
}
|
|
|
|
|
2004-08-16 17:19:17 +02:00
|
|
|
const u8 *CStrW::Deserialize(const u8 *buffer, const u8 *bufferend)
|
2003-11-30 17:39:22 +01:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
const u16 *strend = (const u16 *)buffer;
|
2004-06-11 04:55:09 +02:00
|
|
|
while ((const u8 *)strend < bufferend && *strend) strend++;
|
|
|
|
if ((const u8 *)strend >= bufferend) return NULL;
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
resize(strend - (const u16 *)buffer);
|
|
|
|
size_t i = 0;
|
|
|
|
const u16 *ptr = (const u16 *)buffer;
|
|
|
|
|
|
|
|
std::wstring::iterator str = begin();
|
|
|
|
while (ptr < strend)
|
|
|
|
*(str++) = (TCHAR)ntohs(*(ptr++)); // convert from network order (big-endian)
|
2004-06-11 04:55:09 +02:00
|
|
|
|
|
|
|
return (const u8 *)(strend+1);
|
2004-06-02 17:31:55 +02:00
|
|
|
}
|
2005-01-17 05:52:02 +01:00
|
|
|
|
|
|
|
uint CStr::GetSerializedLength() const
|
|
|
|
{
|
|
|
|
return uint(length()*2 + 2);
|
|
|
|
}
|
|
|
|
|
2004-08-16 17:19:17 +02:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
CStr8 is always serialized to/from ASCII (or whatever 8-bit codepage stored
|
|
|
|
in the CStr)
|
|
|
|
*/
|
|
|
|
|
|
|
|
u8 *CStr8::Serialize(u8 *buffer) const
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t len = length();
|
|
|
|
size_t i = 0;
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
buffer[i] = (*this)[i];
|
|
|
|
buffer[i] = 0;
|
|
|
|
return buffer+len+1;
|
2004-08-16 17:19:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const u8 *CStr8::Deserialize(const u8 *buffer, const u8 *bufferend)
|
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
const u8 *strend = buffer;
|
2004-08-16 17:19:17 +02:00
|
|
|
while (strend < bufferend && *strend) strend++;
|
|
|
|
if (strend >= bufferend) return NULL;
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
*this = std::string(buffer, strend);
|
2004-08-16 17:19:17 +02:00
|
|
|
|
|
|
|
return strend+1;
|
|
|
|
}
|
2005-01-17 05:52:02 +01:00
|
|
|
|
|
|
|
uint CStr::GetSerializedLength() const
|
|
|
|
{
|
|
|
|
return uint(length() + 1);
|
|
|
|
}
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
#endif // _UNICODE
|
2004-06-11 04:55:09 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
#endif // CStr_CPP_FIRST
|