mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-07-15 00:08:07 -04:00
363 lines
11 KiB
C++
Executable File
363 lines
11 KiB
C++
Executable File
// ======================================================================
|
|
//
|
|
// UnicodeUtils.h
|
|
// copyright (c) 2001 Sony Online Entertainment
|
|
//
|
|
// jwatson
|
|
//
|
|
// Basic Unicode string handling/manipulating functions
|
|
// ======================================================================
|
|
|
|
#ifndef INCLUDED_PlatUnicodeUtils_H
|
|
#define INCLUDED_PlatUnicodeUtils_H
|
|
|
|
#if WIN32
|
|
// stl warning func not inlined
|
|
#pragma warning (disable:4710)
|
|
#pragma warning (disable:4786)
|
|
#endif
|
|
|
|
#include "Unicode.h"
|
|
#include <Base/Archive.h>
|
|
#ifdef WIN32
|
|
#include <ctype.h>
|
|
#else
|
|
#include <wctype.h>
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
#ifdef EXTERNAL_DISTRO
|
|
namespace NAMESPACE
|
|
{
|
|
#endif
|
|
|
|
namespace Plat_Unicode
|
|
{
|
|
|
|
String narrowToWide (const NarrowString & nstr);
|
|
String & narrowToWide (const NarrowString & nstr, String & str); //lint !e1929 // function returning a reference
|
|
|
|
NarrowString wideToNarrow (const String & nstr);
|
|
NarrowString & wideToNarrow (const String & nstr, NarrowString & str); //lint !e1929 // function returning a reference
|
|
NarrowString toLower (const NarrowString & nstr);
|
|
NarrowString toUpper (const NarrowString & nstr);
|
|
String toLower (const String & nstr);
|
|
String toUpper (const String & nstr);
|
|
|
|
const String getTrim (const String & str, const unicode_char_t * white = whitespace);
|
|
String & trim (String & str, const unicode_char_t * white = whitespace);
|
|
|
|
bool getFirstToken (const String & str, size_t pos, size_t & endpos, String & token, const unicode_char_t * sepChars = whitespace);
|
|
bool getNthToken (const String & str, const size_t n, size_t & pos, size_t & endpos, String & token, const unicode_char_t * sepChars = whitespace);
|
|
size_t skipWhitespace (const String & str, size_t pos, const unicode_char_t * white = whitespace);
|
|
|
|
const NarrowString getTrim (const NarrowString & str, const char * white = ascii_whitespace);
|
|
NarrowString & trim (NarrowString & str, const char * white = ascii_whitespace);
|
|
|
|
bool getFirstToken (const NarrowString & str, size_t pos, size_t & endpos, NarrowString & token, const char * sepChars = ascii_whitespace);
|
|
bool getNthToken (const NarrowString & str, const size_t n, size_t & pos, size_t & endpos, NarrowString & token, const char * sepChars = ascii_whitespace);
|
|
size_t skipWhitespace (const NarrowString & str, size_t pos, const char * white = ascii_whitespace);
|
|
|
|
enum FieldAlignment
|
|
{
|
|
FA_LEFT,
|
|
FA_RIGHT,
|
|
FA_CENTER
|
|
};
|
|
|
|
String & appendStringField (String & dst, const String & src, size_t width, FieldAlignment fa = FA_LEFT, unicode_char_t pad = ' ', bool truncate = false);
|
|
String & appendStringField (String & dst, const NarrowString & src, size_t width, FieldAlignment fa = FA_LEFT, unicode_char_t pad = ' ', bool truncate = false);
|
|
|
|
/**
|
|
* Compare substrings of str2 and str1, each starting with pos and containing n characters
|
|
*/
|
|
|
|
|
|
/**
|
|
* Compares str1 and str2, where str1 is a String and str2 is templated,
|
|
* thus could be a std::string as well. Set reverseCompare to true if you
|
|
* want to begin comparison at end of string--a useful optimization if your
|
|
* strings tend to differ at the end.
|
|
*/
|
|
template <typename T> bool caseInsensitiveCompare (const String & str1, const T & str2, bool reverseCompare = false)
|
|
{
|
|
const size_t len1 = str1.size();
|
|
const size_t len2 = str2.size();
|
|
|
|
if (len1 != len2)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!reverseCompare)
|
|
{
|
|
for (size_t i = 0; i < len1; i++)
|
|
{
|
|
if ( towlower(str1[i]) != towlower(str2[i]) )
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (size_t i = len1; i > 0; i--)
|
|
{
|
|
if ( towlower(str1[i-1]) != towlower(str2[i-1]) )
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Compares str1 and str2, where str1 is a String and str2 is templated,
|
|
* thus could be a std::string as well. Unlike caseInsensitiveCompare, this
|
|
* version returns an int for < or > comparisons, and comparison must start
|
|
* at the front. Note that this kind of comparison does not allow the shortcut
|
|
* of first comparing sizes--every character must be compared up to the last one.
|
|
*/
|
|
template <typename T> int caseInsensitiveCompareInt (const String & str1, const T & str2)
|
|
{
|
|
const size_t len1 = str1.size();
|
|
const size_t len2 = str2.size();
|
|
|
|
size_t len;
|
|
if (len1 < len2)
|
|
len = len1;
|
|
else
|
|
len = len2;
|
|
|
|
// iterate over smallest length
|
|
for (size_t i = 0; i < len; i++)
|
|
{
|
|
if ( towlower(str1[i]) < towlower(str2[i]) )
|
|
return -1;
|
|
else if ( towlower(str1[i]) > towlower(str2[i]) )
|
|
return 1;
|
|
}
|
|
|
|
// Equal so far, thus: if len1 < len2, the result is less-than, else
|
|
// if len1 = len2, the result is equal, else the result is greater-than.
|
|
|
|
if (len1 < len2)
|
|
return -1;
|
|
else if (len1 == len2)
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* Optimized implementation of isWhitespace. Must be kept in line with ::whitespace array
|
|
*/
|
|
|
|
template <typename T> bool isWhitespace (T c)
|
|
{
|
|
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
|
|
}
|
|
|
|
/*
|
|
* @todo: uncomment when caseInsensitiveCompare matures
|
|
*
|
|
template <typename T> class CompareNoCasePredicate
|
|
{
|
|
public:
|
|
bool operator()( T & a, T & b ) const
|
|
{
|
|
return caseInsensitiveCompare (a, b) < 0;
|
|
};
|
|
};
|
|
|
|
template <typename T> class EqualsNoCasePredicate
|
|
{
|
|
public:
|
|
bool operator()( T & a, T & b ) const
|
|
{
|
|
return caseInsensitiveCompare (a, b) == 0;
|
|
};
|
|
};
|
|
*/
|
|
|
|
//-----------------------------------------------------------------
|
|
//-- implementation
|
|
//-----------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Utility to convert a string and obtain the result by value
|
|
*/
|
|
|
|
inline String narrowToWide (const NarrowString & nstr)
|
|
{
|
|
// return String (nstr.begin (), nstr.end ()); // STLPort original
|
|
String s;
|
|
unsigned index = 0;
|
|
s.resize(nstr.size());
|
|
const NarrowString::const_iterator end = nstr.end();
|
|
for (NarrowString::const_iterator iter = nstr.begin(); iter != end; ++iter)
|
|
{
|
|
s[index++] = *iter;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Utility to convert a string and obtain the result by reference
|
|
*/
|
|
|
|
inline String & narrowToWide (const NarrowString & nstr, String & str)
|
|
{
|
|
// return str.assign (nstr.begin (), nstr.end ()); // STLport original
|
|
unsigned index = 0;
|
|
str.resize(nstr.size());
|
|
const NarrowString::const_iterator end = nstr.end();
|
|
for (NarrowString::const_iterator iter = nstr.begin(); iter != end; ++iter)
|
|
{
|
|
str[index++] = *iter;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
|
|
* Utility to convert a string and obtain the result by value
|
|
|
|
* This should only be used when the Unicode string is known to contain only 8 bit assignable values
|
|
|
|
*/
|
|
|
|
inline NarrowString wideToNarrow (const String & str)
|
|
{
|
|
// return NarrowString (str.begin (), str.end ()); // STLPort original
|
|
NarrowString s;
|
|
unsigned index = 0;
|
|
s.resize(str.size());
|
|
const String::const_iterator end = str.end();
|
|
for (String::const_iterator iter = str.begin(); iter != end; ++iter)
|
|
{
|
|
s[index++] = (char)*iter;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
|
|
* Utility to convert a string and obtain the result by reference
|
|
|
|
* This should only be used when the Unicode string is known to contain only 8 bit assignable values
|
|
|
|
*/
|
|
|
|
inline NarrowString & wideToNarrow (const String & str, NarrowString & nstr)
|
|
{
|
|
// return nstr.assign (str.begin (), str.end ()); // STLPort original
|
|
unsigned index = 0;
|
|
nstr.resize(str.size());
|
|
const String::const_iterator end = str.end();
|
|
for (String::const_iterator iter = str.begin(); iter != end; ++iter)
|
|
{
|
|
nstr[index++] = (char)*iter;
|
|
}
|
|
return nstr;
|
|
}
|
|
|
|
/**
|
|
* Get the trimmed version of str by value.
|
|
*/
|
|
|
|
inline const String getTrim (const String & str, const unicode_char_t * white)
|
|
{
|
|
const size_t first_nonspace = str.find_first_not_of ( white );
|
|
const size_t last_nonspace = str.find_last_not_of ( white );
|
|
return (first_nonspace == str.npos ? str : str.substr (first_nonspace, last_nonspace == str.npos ? last_nonspace : (last_nonspace - first_nonspace + 1)));
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Trim the specified string and return a reference to it.
|
|
*/
|
|
|
|
inline String & trim (String & str, const unicode_char_t * white)
|
|
{
|
|
return (str = getTrim (str, white));
|
|
}
|
|
|
|
/**
|
|
* Get the trimmed version of str by value.
|
|
*/
|
|
|
|
inline const NarrowString getTrim (const NarrowString & str, const char * white)
|
|
{
|
|
const size_t first_nonspace = str.find_first_not_of ( white );
|
|
const size_t last_nonspace = str.find_last_not_of ( white );
|
|
return (first_nonspace == str.npos ? str : str.substr (first_nonspace, last_nonspace == str.npos ? last_nonspace : (last_nonspace - first_nonspace + 1)));
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Trim the specified string and return a reference to it.
|
|
*/
|
|
inline NarrowString & trim (NarrowString & str, const char * white)
|
|
{
|
|
return (str = getTrim (str, white));
|
|
}
|
|
/**
|
|
* Return the first non-white position starting with pos. returns str.npos if there is no non-white characer after pos
|
|
*/
|
|
inline size_t skipWhitespace (const String & str, size_t pos, const unicode_char_t * white)
|
|
{
|
|
return str.find_first_not_of (white, pos);
|
|
}
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Return the first non-white position starting with pos. returns str.npos if there is no non-white characer after pos
|
|
*/
|
|
|
|
inline size_t skipWhitespace (const NarrowString & str, size_t pos, const char * white)
|
|
{
|
|
return str.find_first_not_of (white, pos);
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
/**
|
|
* Append src to dst, padding the field as needed, and truncating the field if desired.
|
|
*/
|
|
|
|
inline String & appendStringField (String & dst, const NarrowString & src, size_t width, FieldAlignment fa, unicode_char_t pad, bool truncate)
|
|
{
|
|
return appendStringField (dst, narrowToWide (src), width, fa, pad, truncate);
|
|
}
|
|
// ======================================================================
|
|
};
|
|
|
|
// ======================================================================
|
|
// Extensions to Base/Archive for String
|
|
// ======================================================================
|
|
//class Base::ByteStream;
|
|
//-----------------------------------------------------------------------
|
|
namespace Base
|
|
{
|
|
extern void get(ByteStream::ReadIterator & source, Plat_Unicode::String & target);
|
|
extern void put(ByteStream & target, const Plat_Unicode::String & source);
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
// namespace Base
|
|
|
|
};
|
|
#ifdef EXTERNAL_DISTRO
|
|
};
|
|
#endif
|
|
|
|
#endif
|