mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-07-15 00:08:07 -04:00
298 lines
8.0 KiB
C++
Executable File
298 lines
8.0 KiB
C++
Executable File
// ======================================================================
|
|
//
|
|
// Unicode.cpp
|
|
// copyright (c) 2001 Sony Online Entertainment
|
|
//
|
|
// ======================================================================
|
|
|
|
#include "FirstUnicode.h"
|
|
#include "UnicodeUtils.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#if defined (linux)
|
|
#include <ctype.h>
|
|
#endif
|
|
|
|
// ======================================================================
|
|
|
|
#ifdef EXTERNAL_DISTRO
|
|
namespace NAMESPACE
|
|
{
|
|
#endif
|
|
|
|
namespace Plat_Unicode
|
|
{
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Return by value a lowered version of nstr
|
|
*/
|
|
|
|
NarrowString toLower (const NarrowString & nstr)
|
|
{
|
|
NarrowString retval (nstr.c_str());
|
|
std::transform (retval.begin (), retval.end (), retval.begin (), trueLower);
|
|
return retval;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Return by value an uppered version of nstr
|
|
*/
|
|
|
|
NarrowString toUpper (const NarrowString & nstr)
|
|
{
|
|
NarrowString retval (nstr);
|
|
std::transform (retval.begin (), retval.end (), retval.begin (), trueUpper);
|
|
return retval;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Return by value a lowered version of str.
|
|
* This currently only works properly with ASCII.
|
|
* @todo: implement this for all unicode blocks.
|
|
*/
|
|
|
|
String toLower (const String & nstr)
|
|
{
|
|
String retval (nstr);
|
|
std::transform (retval.begin (), retval.end (), retval.begin (), trueLower);
|
|
return retval;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Return by value an uppered version of str.
|
|
* This currently only works properly with ASCII.
|
|
* @todo: implement this for all unicode blocks.
|
|
*/
|
|
|
|
String toUpper (const String & nstr)
|
|
{
|
|
String retval (nstr);
|
|
std::transform (retval.begin (), retval.end (), retval.begin (), trueUpper);
|
|
return retval;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Append src to dst, padding the field as needed, and truncating the field if desired.
|
|
*/
|
|
|
|
String & appendStringField (String & dst, const String & src, size_t width, FieldAlignment fa, unicode_char_t pad, bool truncate)
|
|
{
|
|
|
|
if (src.length () > width && truncate)
|
|
return dst.append (src.substr (0, width));
|
|
|
|
if (src.length () >= width)
|
|
return dst.append (src);
|
|
|
|
const size_t diff = width - src.length ();
|
|
|
|
if (fa == FA_RIGHT)
|
|
dst.append (diff, pad);
|
|
else if (fa == FA_CENTER)
|
|
dst.append (diff/2, pad);
|
|
|
|
dst.append (src);
|
|
|
|
if (fa == FA_LEFT)
|
|
dst.append (diff, pad);
|
|
else if (fa == FA_CENTER)
|
|
dst.append (diff - diff/2, pad);
|
|
|
|
return dst;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Find the first token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
|
*/
|
|
|
|
bool getFirstToken (const String & str, size_t pos, size_t & endpos, String & token, const unicode_char_t * sepChars)
|
|
{
|
|
const size_t first_nonspace = str.find_first_not_of ( sepChars, pos );
|
|
|
|
if (first_nonspace != std::string::npos)
|
|
{
|
|
const size_t first_space = str.find_first_of (sepChars, first_nonspace );
|
|
|
|
if (first_space != std::string::npos)
|
|
token = str.substr (first_nonspace, first_space - first_nonspace);
|
|
else
|
|
token = str.substr (first_nonspace);
|
|
|
|
endpos = first_space;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Find the first token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
|
*/
|
|
|
|
bool getFirstToken (const NarrowString & str, size_t pos, size_t & endpos, NarrowString & token, const char * sepChars)
|
|
{
|
|
const size_t first_nonspace = str.find_first_not_of ( sepChars, pos );
|
|
|
|
if (first_nonspace != std::string::npos)
|
|
{
|
|
const size_t first_space = str.find_first_of (sepChars, first_nonspace );
|
|
if (first_space != std::string::npos)
|
|
token = str.substr (first_nonspace, first_space - first_nonspace);
|
|
else
|
|
token = str.substr (first_nonspace);
|
|
|
|
endpos = first_space;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Find the nth token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
|
* pos is updated to point to the first character of token in str.
|
|
*/
|
|
|
|
bool getNthToken (const String & str, const size_t n, size_t & pos, size_t & endpos, String & token, const unicode_char_t * sepChars)
|
|
{
|
|
size_t desired_first_nonspace = 0;
|
|
size_t space = 0;
|
|
|
|
//check for trivial case
|
|
if(n == 0)
|
|
desired_first_nonspace = pos;
|
|
else
|
|
{
|
|
for (size_t i = 0; i < n; ++i)
|
|
{
|
|
//find the first whitespace character
|
|
space = str.find_first_of ( sepChars, pos );
|
|
if (space == std::string::npos)
|
|
return false;
|
|
//now find the next non-whitespace character after it
|
|
desired_first_nonspace = str.find_first_not_of( sepChars, space );
|
|
if (desired_first_nonspace == std::string::npos)
|
|
return false;
|
|
pos = desired_first_nonspace;
|
|
}
|
|
}
|
|
//find the end of the token
|
|
const size_t first_space = str.find_first_of (sepChars, desired_first_nonspace );
|
|
//now get that token
|
|
if (first_space != std::string::npos)
|
|
token = str.substr (desired_first_nonspace, first_space - desired_first_nonspace);
|
|
else
|
|
token = str.substr (desired_first_nonspace);
|
|
|
|
endpos = desired_first_nonspace;
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
/**
|
|
* Find the nth token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
|
* pos is updated to point to the first character of token in str.
|
|
*/
|
|
|
|
bool getNthToken (const NarrowString & str, const size_t n, size_t & pos, size_t & endpos, NarrowString & token, const char * sepChars)
|
|
{
|
|
size_t desired_first_nonspace = 0;
|
|
size_t space = 0;
|
|
|
|
//check for trivial case
|
|
if(n == 0)
|
|
desired_first_nonspace = pos;
|
|
else
|
|
{
|
|
for (size_t i = 0; i < n; ++i)
|
|
{
|
|
//find the first whitespace character
|
|
space = str.find_first_of ( sepChars, pos );
|
|
if (space == std::string::npos)
|
|
return false;
|
|
//now find the next non-whitespace character after it
|
|
desired_first_nonspace = str.find_first_not_of( sepChars, space );
|
|
if (desired_first_nonspace == std::string::npos)
|
|
return false;
|
|
pos = desired_first_nonspace;
|
|
}
|
|
}
|
|
//find the end of the token
|
|
const size_t first_space = str.find_first_of (sepChars, desired_first_nonspace );
|
|
//now get that token
|
|
if (first_space != std::string::npos)
|
|
token = str.substr (desired_first_nonspace, first_space - desired_first_nonspace);
|
|
else
|
|
token = str.substr (desired_first_nonspace);
|
|
|
|
endpos = desired_first_nonspace;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// ======================================================================
|
|
// Extensions to Base/Archive for String
|
|
// ======================================================================
|
|
|
|
namespace Base
|
|
{
|
|
unsigned get(Base::ByteStream::ReadIterator& source, Plat_Unicode::String& target)
|
|
{
|
|
unsigned int size = 0;
|
|
|
|
if (source.getSize() < sizeof(size))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
get (source, size);
|
|
|
|
const unsigned char * const buf = source.getBuffer();
|
|
const Plat_Unicode::unicode_char_t * const ubuf = reinterpret_cast<const Plat_Unicode::unicode_char_t *>(buf);
|
|
unsigned int readSize = size * sizeof (Plat_Unicode::unicode_char_t);
|
|
|
|
if (source.getSize() < readSize)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
target.assign (ubuf, ubuf + size);
|
|
|
|
source.advance(readSize);
|
|
// printf("%d\n", target.size());
|
|
return (readSize + sizeof(size));
|
|
}
|
|
|
|
void put(Base::ByteStream& target, const Plat_Unicode::String& source)
|
|
{
|
|
const unsigned int size = source.size ();
|
|
put (target, size);
|
|
target.put (source.data(), size * sizeof (Plat_Unicode::unicode_char_t));
|
|
}
|
|
|
|
};
|
|
|
|
|
|
#ifdef EXTERNAL_DISTRO
|
|
};
|
|
#endif
|