Added TransferServer project and CTServiceGameAPI library

This commit is contained in:
Anonymous
2014-01-18 06:31:13 -07:00
parent b33724e9f7
commit a5b073e4f2
87 changed files with 13669 additions and 0 deletions
@@ -0,0 +1,9 @@
// ======================================================================
//
// FirstUnicode.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "FirstUnicode.h"
@@ -0,0 +1,26 @@
// ======================================================================
//
// FirstUnicode.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_PlatFirstUnicode_H
#define INCLUDED_PlatFirstUnicode_H
// ======================================================================
// stl unref inline func removed
#ifdef WIN32
// C4514 unreferenced inline/local function has been removed
// C4786 'identifier' : identifier was truncated to 'number' characters in the debug information
#pragma warning (disable:4514 4786)
#endif
// ======================================================================
#endif
@@ -0,0 +1,26 @@
// ======================================================================
//
// Unicode.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "FirstUnicode.h"
#include "Unicode.h"
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
};
#ifdef EXTERNAL_DISTRO
};
#endif
// ======================================================================
@@ -0,0 +1,58 @@
// ======================================================================
// Unicode.h
// copyright (c) 2001 Sony Online Entertainment
//
// jwatson
//
// Basic Unicode primitives and string handling/manipulating functions
// ======================================================================
#ifndef INCLUDED_PlatUnicode_H
#define INCLUDED_PlatUnicode_H
#if WIN32
#pragma warning (disable:4710)
#pragma warning (disable:4786)
// stl warning func not inlined
#pragma warning (disable:4514)
#endif
#include <string>
//-----------------------------------------------------------------
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
typedef unsigned short unicode_char_t;
/**
* Standard Unicode string is UTF-16
*/
typedef std::basic_string<unicode_char_t> String;
/**
* NarrowString is a ascii string.
*/
typedef std::string NarrowString;
const unicode_char_t whitespace [] = { ' ', '\n', '\r', '\t', 0 };
const unicode_char_t endlines [] = { '\r', '\n', 0 };
const char ascii_whitespace [] = { ' ', '\n', '\r', '\t', 0 };
const char ascii_endlines [] = { '\r', '\n', 0 };
};
#ifdef EXTERNAL_DISTRO
};
#endif
//-----------------------------------------------------------------
#endif
@@ -0,0 +1,267 @@
// ======================================================================
//
// UnicodeBlocks.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Unicode 3.0 compliant Blocks.
//
// ======================================================================
#include "FirstUnicode.h"
#include "UnicodeBlocks.h"
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
using namespace Plat_Unicode::Blocks;
using Plat_Unicode::unicode_char_t;
//-----------------------------------------------------------------
const Plat_Unicode::Blocks::RawData Plat_Unicode::Blocks::Mapping::ms_defaultBlockData [] =
{
{ Basic_Latin, "Basic Latin",0x0000,0x007F },
{ Latin_1_Supplement,"Latin-1 Supplement",0x0080,0x00FF },
{ Latin_Extended_A, "Latin Extended-A",0x0100,0x017F },
{ Latin_Extended_B, "Latin Extended-B",0x0180,0x024F },
{ IPA_Extensions, "IPA Extensions",0x0250,0x02AF },
{ Spacing_Modifier_Letters, "Spacing Modifier Letters",0x02B0,0x02FF },
{ Combining_Diacritical_Marks, "Combining Diacritical Marks",0x0300,0x036F },
{ Greek, "Greek",0x0370,0x03FF },
{ Cyrillic, "Cyrillic",0x0400,0x04FF },
{ Armenian, "Armenian",0x0530,0x058F },
{ Hebrew, "Hebrew",0x0590,0x05FF },
{ Arabic, "Arabic",0x0600,0x06FF },
{ Syriac, "Syriac ",0x0700,0x074F },
{ Thaana, "Thaana",0x0780,0x07BF },
{ Devanagari, "Devanagari",0x0900,0x097F },
{ Bengali, "Bengali",0x0980,0x09FF },
{ Gurmukhi, "Gurmukhi",0x0A00,0x0A7F },
{ Gujarati, "Gujarati",0x0A80,0x0AFF },
{ Oriya, "Oriya",0x0B00,0x0B7F },
{ Tamil, "Tamil",0x0B80,0x0BFF },
{ Telugu, "Telugu",0x0C00,0x0C7F },
{ Kannada, "Kannada",0x0C80,0x0CFF },
{ Malayalam, "Malayalam",0x0D00,0x0D7F },
{ Sinhala, "Sinhala",0x0D80,0x0DFF },
{ Thai, "Thai",0x0E00,0x0E7F },
{ Lao, "Lao",0x0E80,0x0EFF },
{ Tibetan, "Tibetan",0x0F00,0x0FFF },
{ Myanmar, "Myanmar ",0x1000,0x109F },
{ Georgian, "Georgian",0x10A0,0x10FF },
{ Hangul_Jamo, "Hangul Jamo",0x1100,0x11FF },
{ Ethiopic, "Ethiopic",0x1200,0x137F },
{ Cherokee, "Cherokee",0x13A0,0x13FF },
{ Unified_Canadian_Aboriginal_Syllabics, "Unified Canadian Aboriginal Syllabics",0x1400,0x167F },
{ Ogham, "Ogham",0x1680,0x169F },
{ Runic, "Runic",0x16A0,0x16FF },
{ Khmer, "Khmer",0x1780,0x17FF },
{ Mongolian, "Mongolian",0x1800,0x18AF },
{ Latin_Extended_Additional, "Latin Extended Additional",0x1E00,0x1EFF },
{ Greek_Extended, "Greek Extended",0x1F00,0x1FFF },
{ General_Punctuation, "General Punctuation",0x2000,0x206F },
{ Superscripts_and_Subscripts, "Superscripts and Subscripts",0x2070,0x209F },
{ Currency_Symbols, "Currency Symbols",0x20A0,0x20CF },
{ Combining_Marks_for_Symbols, "Combining Marks for Symbols",0x20D0,0x20FF },
{ Letterlike_Symbols, "Letterlike Symbols",0x2100,0x214F },
{ Number_Forms, "Number Forms",0x2150,0x218F },
{ Arrows, "Arrows",0x2190,0x21FF },
{ Mathematical_Operators, "Mathematical Operators",0x2200,0x22FF },
{ Miscellaneous_Technical, "Miscellaneous Technical",0x2300,0x23FF },
{ Control_Pictures, "Control Pictures",0x2400,0x243F },
{ Optical_Character_Recognition, "Optical Character Recognition",0x2440,0x245F },
{ Enclosed_Alphanumerics, "Enclosed Alphanumerics",0x2460,0x24FF },
{ Box_Drawing, "Box Drawing",0x2500,0x257F },
{ Block_Elements, "Block Elements",0x2580,0x259F },
{ Geometric_Shapes, "Geometric Shapes",0x25A0,0x25FF },
{ Miscellaneous_Symbols, "Miscellaneous Symbols",0x2600,0x26FF },
{ Dingbats, "Dingbats",0x2700,0x27BF },
{ Braille_Patterns, "Braille Patterns",0x2800,0x28FF },
{ CJK_Radicals_Supplement, "CJK Radicals Supplement",0x2E80,0x2EFF },
{ Kangxi_Radicals, "Kangxi Radicals",0x2F00,0x2FDF },
{ Ideographic_Description_Characters, "Ideographic Description Characters",0x2FF0,0x2FFF },
{ CJK_Symbols_and_Punctuation, "CJK Symbols and Punctuation",0x3000,0x303F },
{ Hiragana, "Hiragana",0x3040,0x309F },
{ Katakana, "Katakana",0x30A0,0x30FF },
{ Bopomofo, "Bopomofo",0x3100,0x312F },
{ Hangul_Compatibility_Jamo, "Hangul Compatibility Jamo",0x3130,0x318F },
{ Kanbun, "Kanbun",0x3190,0x319F },
{ Bopomofo_Extended, "Bopomofo Extended",0x31A0,0x31BF },
{ Enclosed_CJK_Letters_and_Months, "Enclosed CJK Letters and Months",0x3200,0x32FF },
{ CJK_Compatibility, "CJK Compatibility",0x3300,0x33FF },
{ CJK_Unified_Ideographs_Extension_A, "CJK Unified Ideographs Extension A",0x3400,0x4DB5 },
{ CJK_Unified_Ideographs, "CJK Unified Ideographs",0x4E00,0x9FFF },
{ Yi_Syllables, "Yi Syllables",0xA000,0xA48F },
{ Yi_Radicals, "Yi Radicals",0xA490,0xA4CF },
{ Hangul_Syllables, "Hangul Syllables",0xAC00,0xD7A3 },
{ High_Surrogates, "High Surrogates",0xD800,0xDB7F },
{ High_Private_Use_Surrogates, "High Private Use Surrogates",0xDB80,0xDBFF },
{ Low_Surrogates, "Low Surrogates",0xDC00,0xDFFF },
{ Private_Use, "Private Use",0xE000,0xF8FF },
{ CJK_Compatibility_Ideographs, "CJK Compatibility Ideographs",0xF900,0xFAFF },
{ Alphabetic_Presentation_Forms, "Alphabetic Presentation Forms",0xFB00,0xFB4F },
{ Arabic_Presentation_Forms_A, "Arabic Presentation Forms-A",0xFB50,0xFDFF },
{ Combining_Half_Marks, "Combining Half Marks",0xFE20,0xFE2F },
{ CJK_Compatibility_Forms, "CJK Compatibility Forms",0xFE30,0xFE4F },
{ Small_Form_Variants, "Small Form Variants",0xFE50,0xFE6F },
{ Arabic_Presentation_Forms_B, "Arabic Presentation Forms-B",0xFE70,0xFEFE },
{ Specials_1, "Specials",0xFEFF,0xFEFF },
{ Halfwidth_and_Fullwidth_Forms, "Halfwidth and Fullwidth Forms",0xFF00,0xFFEF },
{ Specials_2, "Specials 2",0xFFF0,0xFFFD },
{ End_Block_Ids, "End Block Ids",0xFFFE,0xFFFF }
};
//-----------------------------------------------------------------
Mapping * Mapping::ms_singleton = 0;
//-----------------------------------------------------------------
/**
* Initialize the singleton. This must be called before mapping is used.
*/
void Mapping::initSingleton ()
{
explicitDestroy ();
ms_singleton = new Mapping (ms_defaultBlockData);
}
//-----------------------------------------------------------------
/**
* Destroys the singleton
*/
void Mapping::explicitDestroy ()
{
if (ms_singleton)
delete ms_singleton;
ms_singleton = 0;
}
//-----------------------------------------------------------------
/**
* Construct a Mapping from an array of RawData
*/
Mapping::Mapping (const RawData dataArray []) :
m_idMap (),
m_nameMap (),
m_errorData ()
{
size_t i = 0;
for (; dataArray [i].m_id != End_Block_Ids; ++i)
{
m_idMap [dataArray[i].m_id] = Data (dataArray [i]);
m_nameMap [dataArray[i].m_name] = Data (dataArray [i]);
}
m_errorData = Data (dataArray [i]);
}
//----------------------------------------------------------------------
/**
* Construct a complete set of code points in this block.
* @param idset should enter this function empty
*/
const std::set<unicode_char_t> & Data::generateFilteredIdSet (std::set<unicode_char_t> & idset) const
{
{
for (unicode_char_t i = m_start; i < m_end; ++i)
{
idset.insert (i);
}
}
for (RangeGroups_t::const_iterator iter = m_rangeGroups.begin (); iter != m_rangeGroups.end (); ++iter)
{
const RangeGroup & rg = *iter;
if (rg.m_isInclusive)
{
for (RangeGroup::Ranges_t::const_iterator rg_iter = rg.m_ranges.begin (); rg_iter != rg.m_ranges.end (); ++rg_iter)
{
for (unicode_char_t i = (*rg_iter).m_low; i <= (*rg_iter).m_high; ++i)
{
idset.insert (i);
}
}
}
else
{
for (RangeGroup::Ranges_t::const_iterator rg_iter = rg.m_ranges.begin (); rg_iter != rg.m_ranges.end (); ++rg_iter)
{
for (unicode_char_t i = (*rg_iter).m_low; i <= (*rg_iter).m_high; ++i)
{
idset.erase (i);
}
}
}
}
return idset;
}
//-----------------------------------------------------------------
/**
* Add a range group with a given string representation. Valid strings include hexadecimal numbers, dashes, and commas.
* @param inclusive indicates if this group should be additive or subtractive. It is an error to attempt to add code points outside the Block's gross range.
*/
bool Data::addRangeGroup (bool inclusive, const Plat_Unicode::NarrowString & str)
{
RangeGroup rg;
rg.m_isInclusive = inclusive;
size_t tokenStartPos = 0;
while (tokenStartPos != NarrowString::npos)
{
size_t tokenCommaPos = str.find_first_of (',', tokenStartPos);
size_t tokenDashPos = str.find_first_of ('-', tokenStartPos);
Range rng;
// this is a dashed range
if (tokenDashPos < tokenCommaPos)
{
rng.m_low = static_cast<unicode_char_t> (strtoul ( str.substr (tokenStartPos, tokenDashPos - tokenStartPos).c_str (), 0, 16));
tokenStartPos = str.find_first_not_of ('-', tokenDashPos);
if (tokenStartPos == NarrowString::npos)
return false;
rng.m_high = static_cast<unicode_char_t> (strtoul (str.substr (tokenStartPos, tokenCommaPos - tokenStartPos).c_str (), 0, 16));
}
else
{
rng.m_high = rng.m_low = static_cast<unicode_char_t> (strtoul ( str.substr (tokenStartPos, tokenCommaPos - tokenStartPos).c_str (), 0, 16));
}
rg.m_ranges.push_back (rng);
tokenStartPos = str.find_first_not_of (',', tokenCommaPos);
}
m_rangeGroups.push_back (rg);
return true;
};
#ifdef EXTERNAL_DISTRO
};
#endif
// ===================================================================== },
@@ -0,0 +1,404 @@
// ======================================================================
//
// UnicodeBlocks.h
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Unicode 3.0 compliant Blocks.
//
// ======================================================================
#ifndef INCLUDED_PlatUnicodeBlocks_H
#define INCLUDED_PlatUnicodeBlocks_H
#if WIN32
// stl warning func not inlined
#pragma warning (disable:4710)
#pragma warning (disable:4786)
#endif
#include "Unicode.h"
#include <map>
#include <vector>
#include <set>
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
namespace Blocks
{
/**
* The enum values are precisely the beginning of the represented block range.
* These blocks are precisely the blocks defined by Unicode 3.0.
*/
enum Id
{
Basic_Latin = 0x0000,
Latin_1_Supplement = 0x0080,
Latin_Extended_A = 0x0100,
Latin_Extended_B = 0x0180,
IPA_Extensions = 0x0250,
Spacing_Modifier_Letters = 0x02B0,
Combining_Diacritical_Marks = 0x0300,
Greek = 0x0370,
Cyrillic = 0x0400,
Armenian = 0x0530,
Hebrew = 0x0590,
Arabic = 0x0600,
Syriac = 0x0700,
Thaana = 0x0780,
Devanagari = 0x0900,
Bengali = 0x0980,
Gurmukhi = 0x0A00,
Gujarati = 0x0A80,
Oriya = 0x0B00,
Tamil = 0x0B80,
Telugu = 0x0C00,
Kannada = 0x0C80,
Malayalam = 0x0D00,
Sinhala = 0x0D80,
Thai = 0x0E00,
Lao = 0x0E80,
Tibetan = 0x0F00,
Myanmar = 0x1000,
Georgian = 0x10A0,
Hangul_Jamo = 0x1100,
Ethiopic = 0x1200,
Cherokee = 0x13A0,
Unified_Canadian_Aboriginal_Syllabics = 0x1400,
Ogham = 0x1680,
Runic = 0x16A0,
Khmer = 0x1780,
Mongolian = 0x1800,
Latin_Extended_Additional = 0x1E00,
Greek_Extended = 0x1F00,
General_Punctuation = 0x2000,
Superscripts_and_Subscripts = 0x2070,
Currency_Symbols = 0x20A0,
Combining_Marks_for_Symbols = 0x20D0,
Letterlike_Symbols = 0x2100,
Number_Forms = 0x2150,
Arrows = 0x2190,
Mathematical_Operators = 0x2200,
Miscellaneous_Technical = 0x2300,
Control_Pictures = 0x2400,
Optical_Character_Recognition = 0x2440,
Enclosed_Alphanumerics = 0x2460,
Box_Drawing = 0x2500,
Block_Elements = 0x2580,
Geometric_Shapes = 0x25A0,
Miscellaneous_Symbols = 0x2600,
Dingbats = 0x2700,
Braille_Patterns = 0x2800,
CJK_Radicals_Supplement = 0x2E80,
Kangxi_Radicals = 0x2F00,
Ideographic_Description_Characters = 0x2FF0,
CJK_Symbols_and_Punctuation = 0x3000,
Hiragana = 0x3040,
Katakana = 0x30A0,
Bopomofo = 0x3100,
Hangul_Compatibility_Jamo = 0x3130,
Kanbun = 0x3190,
Bopomofo_Extended = 0x31A0,
Enclosed_CJK_Letters_and_Months = 0x3200,
CJK_Compatibility = 0x3300,
CJK_Unified_Ideographs_Extension_A = 0x3400,
CJK_Unified_Ideographs = 0x4E00,
Yi_Syllables = 0xA000,
Yi_Radicals = 0xA490,
Hangul_Syllables = 0xAC00,
High_Surrogates = 0xD800,
High_Private_Use_Surrogates = 0xDB80,
Low_Surrogates = 0xDC00,
Private_Use = 0xE000,
CJK_Compatibility_Ideographs = 0xF900,
Alphabetic_Presentation_Forms = 0xFB00,
Arabic_Presentation_Forms_A = 0xFB50,
Combining_Half_Marks = 0xFE20,
CJK_Compatibility_Forms = 0xFE30,
Small_Form_Variants = 0xFE50,
Arabic_Presentation_Forms_B = 0xFE70,
Specials_1 = 0xFEFF,
Halfwidth_and_Fullwidth_Forms = 0xFF00,
Specials_2 = 0xFFF0,
End_Block_Ids = 0xFFFE
};
//-----------------------------------------------------------------
/**
* A simple pair representing an inclusive range of values
*/
struct Range
{
unicode_char_t m_high;
unicode_char_t m_low;
};
//-----------------------------------------------------------------
/**
* A group of ranges that can be additive or subtractive (inclusive or non)
*/
struct RangeGroup
{
bool m_isInclusive;
typedef std::vector<Range> Ranges_t;
Ranges_t m_ranges;
};
//-----------------------------------------------------------------
/**
* RawData is a simple aggregate data struct used to construct the more complex Data objects
*/
struct RawData
{
Id m_id;
const char * m_name;
unicode_char_t m_start;
unicode_char_t m_end;
};
/**
* Data is the representation of a single Unicode block.
* Including the Id, name, gross start-end range, and a set of RangeGroups (usually subtractive)
*/
struct Data
{
Id m_id;
NarrowString m_name;
unicode_char_t m_start;
unicode_char_t m_end;
typedef std::vector <RangeGroup> RangeGroups_t;
RangeGroups_t m_rangeGroups;
explicit Data (const RawData & rhs);
Data ();
const std::set<unicode_char_t> & generateFilteredIdSet (std::set<unicode_char_t> & ) const;
bool addRangeGroup (bool inclusive, const NarrowString & str);
};
//-----------------------------------------------------------------
/**
* Singleton class.
*
* Mapping creates a method of mapping block Ids _or_ names to Block Data objects.
* @todo: Data objects are duplicate for each map, need to optimize.
*/
class Mapping
{
public:
explicit Mapping (const RawData dataArray[]);
static const Mapping & getDefaultMapping ();
static void explicitDestroy ();
typedef std::map <Id, Data> IdMap_t;
typedef std::map <NarrowString, Data> NameMap_t;
const Data & findBlock (Id id) const;
Data & findBlock (Id id);
const Data & findBlock (const NarrowString &) const;
const Data & findBlock (unicode_char_t code) const;
const IdMap_t & getIdMap () const;
bool addBlock (const Data & data);
static const RawData ms_defaultBlockData [];
private:
Mapping ();
Mapping (const Mapping & rhs);
Mapping & operator= (const Mapping & rhs);
static void initSingleton ();
static Mapping * ms_singleton;
IdMap_t m_idMap;
NameMap_t m_nameMap;
Data m_errorData;
};
//-----------------------------------------------------------------
/**
* Convert a RawData into a Data object
*/
inline Data::Data (const RawData & rhs) :
m_id (rhs.m_id),
m_name (rhs.m_name),
m_start (rhs.m_start),
m_end (rhs.m_end),
m_rangeGroups ()
{
}
//----------------------------------------------------------------------
/**
* Default constructor.
*/
inline Data::Data () :
m_id (End_Block_Ids),
m_name (),
m_start (0),
m_end (0),
m_rangeGroups ()
{
}
//-----------------------------------------------------------------
/**
* Static singleton accessor
*/
inline const Mapping & Mapping::getDefaultMapping ()
{
if (ms_singleton)
return *ms_singleton;
initSingleton ();
return *ms_singleton;
}
//-----------------------------------------------------------------
/**
* Add a block Data object to the mapping. If the block already exists
* in the mapping, the new data overwrites the old.
*/
inline bool Mapping::addBlock (const Data & data)
{
m_idMap [data.m_id] = data;
m_nameMap [data.m_name] = data;
return true;
}
//-----------------------------------------------------------------
/**
* Locate the block data by Id.
* @return a Data with End_Block_Ids Id if the block was not found
*/
inline const Data & Mapping::findBlock (Id id) const
{
const IdMap_t::const_iterator iter = m_idMap.find (id);
if (iter != m_idMap.end ())
return (*iter).second;
else
return m_errorData;
}
//-----------------------------------------------------------------
/**
* Locate the block data by Id.
* @return a Data with End_Block_Ids Id if the block was not found
*/
inline Data & Mapping::findBlock (Id id)
{
const IdMap_t::iterator iter = m_idMap.find (id);
if (iter != m_idMap.end ())
return (*iter).second;
else
return m_errorData;
}
//-----------------------------------------------------------------
/**
* Locate the block data by Name.
* @return a Data with End_Block_Ids Id if the block was not found
*/
inline const Data & Mapping::findBlock (const NarrowString & name) const
{
const NameMap_t::const_iterator iter = m_nameMap.find (name);
if (iter != m_nameMap.end ())
return (*iter).second;
else
return m_errorData;
}
//-----------------------------------------------------------------
/**
* Locate the block data by code point.
* @return a Data with End_Block_Ids Id if the block was not found. This only tests if the code point is in the gross range of the located block.
*/
inline const Data & Mapping::findBlock (unicode_char_t code) const
{
const IdMap_t::const_iterator iter = m_idMap.lower_bound (static_cast<Id>(code));
if (iter != m_idMap.end () && code <= (*iter).second.m_end)
return (*iter).second;
else
return m_errorData;
}
//-----------------------------------------------------------------
/**
* Gets the Id->Data map.
*/
inline const Mapping::IdMap_t & Mapping::getIdMap () const
{
return m_idMap;
}
//-----------------------------------------------------------------
/**
* Tests a character to see if belongs in an ideograph range
*/
inline bool isIdeograph (unicode_char_t code)
{
return ((code >= static_cast<unicode_char_t>(CJK_Unified_Ideographs_Extension_A) && code < static_cast<unicode_char_t>(Yi_Syllables)) ||
(code >= static_cast<unicode_char_t>(Hangul_Syllables) && code < static_cast<unicode_char_t>(CJK_Compatibility_Ideographs)));
}
} //-- namespace Blocks
}; // -- namespace Unicode
#ifdef EXTERNAL_DISTRO
};
#endif
// ======================================================================
#endif
@@ -0,0 +1,71 @@
#if defined (linux) && ((__GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL == 3) || (__GNUC__ == 2 && __GNUC_MINOR__ > 96))
#include <bits/char_traits.h>
#include "Unicode.h"
#ifdef EXTERNAL_DISTRO
using namespace NAMESPACE::Plat_Unicode;
#else
using namespace Plat_Unicode;
#endif
namespace std
{
void char_traits<unicode_char_t>::assign(unicode_char_t &__c1, const unicode_char_t &__c2)
{
__c1 = __c2;
}
bool char_traits<unicode_char_t>::eq(const unicode_char_t &__c1, const unicode_char_t &__c2)
{
return __c1 == __c2;
}
bool char_traits<unicode_char_t>::lt(const unicode_char_t &__c1, const unicode_char_t &__c2)
{
return __c1 < __c2;
}
unicode_char_t *char_traits<unicode_char_t>::copy(unicode_char_t *__s1, const unicode_char_t *__s2, size_t __n)
{
return(__n == 0 ? __s1 : (unicode_char_t*)memcpy(__s1, __s2, __n * sizeof(unicode_char_t)));
}
unicode_char_t *char_traits<unicode_char_t>::move(unicode_char_t *__s1, const unicode_char_t* __s2, size_t _Sz)
{
return (_Sz == 0 ? __s1 : (unicode_char_t*)memmove(__s1, __s2, _Sz * sizeof(unicode_char_t)));
}
const unicode_char_t *char_traits<unicode_char_t>::find(const unicode_char_t* __s, size_t __n, const unicode_char_t & __c)
{
for( ; __n > 0; ++__s, --__n)
if(eq(*__s, __c))
return __s;
return 0;
}
size_t char_traits<unicode_char_t>::length(const unicode_char_t *__s)
{
size_t __i;
for(__i = 0; !eq(__s[__i], 0); ++__i);
return __i;
}
unicode_char_t *char_traits<unicode_char_t>::assign(unicode_char_t *__s, size_t __n, unicode_char_t __c)
{
for(size_t __i = 0; __i < __n; ++__i)
__s[__i] = __c;
return __s;
}
int char_traits<unicode_char_t>::compare(const unicode_char_t *__s1, const unicode_char_t *__s2, size_t __n)
{
for(size_t __i = 0; __i < __n; ++__i)
if(!eq(__s1[__i], __s2[__i]))
return __s1[__i] < __s2[__i] ? -1 : 1;
return 0;
}
}
#endif
@@ -0,0 +1,71 @@
// ======================================================================
//
// Plat_UnicodeCharData.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Plat_Unicode 3.0 compliant Character data formats
// The data is loaded dynamically from the Plat_UnicodeData.txt definition file
//
// ======================================================================
#include "FirstUnicode.h"
#include "UnicodeCharacterData.h"
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
//-----------------------------------------------------------------
#define CAT_NAME(s) { CharData::s, #s }
const CharData::CategoryName CharData::ms_categoryNames [] =
{
CAT_NAME (Lu), // Letter, Uppercase
CAT_NAME (Ll), // Letter, Lowercase
CAT_NAME (Lt), // Letter, Titlecase
CAT_NAME (Lm), // Letter, Modifier
CAT_NAME (Lo), // Letter, Other
CAT_NAME (Mn), // Mark, Non-Spacing
CAT_NAME (Mc), // Mark, Spacing Combining
CAT_NAME (Me), // Mark, Enclosing
CAT_NAME (Nd), // Number, Decimal Digit
CAT_NAME (Nl), // Number, Letter
CAT_NAME (No), // Number, Other
CAT_NAME (Pc), // Punctuation, Connector
CAT_NAME (Pd), // Punctuation, Dash
CAT_NAME (Ps), // Punctuation, Open
CAT_NAME (Pe), // Punctuation, Close
CAT_NAME (Pi), // Punctuation, Initial quote (may behave like Ps or Pe depending on usage)
CAT_NAME (Pf), // Punctuation, Final quote (may behave like Ps or Pe depending on usage)
CAT_NAME (Po), // Punctuation, Other
CAT_NAME (Sm), // Symbol, Math
CAT_NAME (Sc), // Symbol, Currency
CAT_NAME (Sk), // Symbol, Modifier
CAT_NAME (So), // Symbol, Other
CAT_NAME (Zs), // Separator, Space
CAT_NAME (Zl), // Separator, Line
CAT_NAME (Zp), // Separator, Paragraph
CAT_NAME (Cc), // Other, Control
CAT_NAME (Cf), // Other, Format
CAT_NAME (Cs), // Other, Surrogate
CAT_NAME (Co), // Other, Private Use
CAT_NAME (Cn) // Other, Not Assigned (no characters in the file have this property)
};
#undef CAT_NAME
};
#ifdef EXTERNAL_DISTRO
};
#endif
//-----------------------------------------------------------------
// ======================================================================
@@ -0,0 +1,125 @@
// ======================================================================
//
// UnicodeCharData.h
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Unicode 3.0 compliant Character data formats
// The data is loaded dynamically from the UnicodeData.txt definition file
//
// ======================================================================
#ifndef INCLUDED_PlatUnicodeCharData_H
#define INCLUDED_PlatUnicodeCharData_H
#if WIN32
// stl warning func not inlined
#pragma warning (disable:4710)
#pragma warning (disable:4786)
#endif
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
typedef unsigned short unicode_char_t; //lint !e761 redundant typedef
struct CharData;
//-----------------------------------------------------------------
struct CharData
{
enum Category
{
Lu, // Letter, Uppercase
Ll, // Letter, Lowercase
Lt, // Letter, Titlecase
Lm, // Letter, Modifier
Lo, // Letter, Other
Mn, // Mark, Non-Spacing
Mc, // Mark, Spacing Combining
Me, // Mark, Enclosing
Nd, // Number, Decimal Digit
Nl, // Number, Letter
No, // Number, Other
Pc, // Punctuation, Connector
Pd, // Punctuation, Dash
Ps, // Punctuation, Open
Pe, // Punctuation, Close
Pi, // Punctuation, Initial quote (may behave like Ps or Pe depending on usage)
Pf, // Punctuation, Final quote (may behave like Ps or Pe depending on usage)
Po, // Punctuation, Other
Sm, // Symbol, Math
Sc, // Symbol, Currency
Sk, // Symbol, Modifier
So, // Symbol, Other
Zs, // Separator, Space
Zl, // Separator, Line
Zp, // Separator, Paragraph
Cc, // Other, Control
Cf, // Other, Format
Cs, // Other, Surrogate
Co, // Other, Private Use
Cn // Other, Not Assigned (no characters in the file have this property)
};
struct CategoryName
{
Category m_category;
const char * m_str;
};
static const CategoryName ms_categoryNames[];
unicode_char_t m_code;
Category m_category;
/**
* Note: this Unicode system only supports upper and lower case.
* Titlecase is considered uppercase. The case of a character
* is determined by its category (Lu,Ll,or Lt)
*/
unicode_char_t m_reverseCase;
bool isLowerCase () const;
bool isUpperCase () const;
unicode_char_t toUpper () const;
unicode_char_t toLower () const;
};
//-----------------------------------------------------------------
/**
* Is this character lowercase.
*/
inline bool CharData::isLowerCase () const
{
return m_category == Ll;
}
//-----------------------------------------------------------------
/**
* Returns true for upper and title case
*/
inline bool CharData::isUpperCase () const
{
return m_category == Lu || m_category == Lt;
}
};
#ifdef EXTERNAL_DISTRO
};
#endif
// ======================================================================
#endif
@@ -0,0 +1,360 @@
// ======================================================================
//
// UnicodeCharDataMap.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Unicode 3.0 compliant Character data formats
// The data is loaded dynamically from the UnicodeData.txt definition file
//
// ======================================================================
#include "FirstUnicode.h"
#include "UnicodeCharacterDataMap.h"
#include "UnicodeBlocks.h"
#include "UnicodeCharacterData.h"
#include <cstdio>
#include <string>
#include <cassert>
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
CharDataMap * CharDataMap::ms_singleton = 0;
//-----------------------------------------------------------------
CharDataMap::CharDataMap () :
m_blockIds (),
m_contiguousData (0),
m_map (),
m_dataIsValid (false)
{
}
//-----------------------------------------------------------------
CharDataMap::~CharDataMap ()
{
m_map.clear ();
m_blockIds.clear ();
if (m_contiguousData)
{
delete[] m_contiguousData;
m_contiguousData = 0;
}
}
//-----------------------------------------------------------------
void CharDataMap::initSingleton ()
{
explicitDestroy ();
// TODO: default blocks?
ms_singleton = new CharDataMap ();
}
//-----------------------------------------------------------------
void CharDataMap::explicitDestroy ()
{
if (ms_singleton)
delete ms_singleton;
ms_singleton = 0;
}
//-----------------------------------------------------------------
namespace
{
typedef std::map <std::string, CharData::Category> CategoryMap_t;
//-----------------------------------------------------------------
/**
* Load a CharData from a string buffer representing a file.
* The bufpos is set to the beginning of a line after this method returns.
*/
inline bool populateDataFromBuffer (size_t desiredCode,
CharData & charData,
const std::string & buffer,
size_t & bufpos,
const CategoryMap_t & cmap)
{
size_t endpos = 0;
bool found = false;
do
{
size_t tokenNum = 0;
while ( (endpos = buffer.find ( ';', bufpos)) != std::string::npos ) //lint !e737 // loss of sign in promotion - STL bug
{
// code value
if (tokenNum == 0)
{
const size_t code = static_cast <size_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
// we passed the desired line, so it must not exist
if (code > desiredCode)
return found;
// not there yet
else if (code < desiredCode)
break;
charData.m_code = static_cast<unicode_char_t> (code);
}
// General Category
else if (tokenNum == 2)
{
// all category codes are currently 2 characters long
if (endpos - bufpos > 2)
break;
const CategoryMap_t::const_iterator find_iter = cmap.find (buffer.substr (bufpos, 2));
if (find_iter == cmap.end ())
{
break;
}
else
charData.m_category = (*find_iter).second;
}
// Uppercase mapping
else if (charData.isLowerCase ())
{
if (tokenNum == 12)
{
if (endpos - bufpos > 1)
charData.m_reverseCase = static_cast<unicode_char_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
found = true;
break;
}
}
// Lowercase mapping
else if (tokenNum == 13)
{
if (endpos - bufpos > 1)
charData.m_reverseCase = static_cast<unicode_char_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
found = true;
break;
}
bufpos = endpos + 1;
++tokenNum;
}
}
while ( (bufpos = buffer.find ('\n', bufpos)) != std::string::npos && //lint !e737 // loss of sign in promotion - STL bug
(bufpos = buffer.find_first_not_of ('\n', bufpos + 1)) != std::string::npos); //lint !e737 // loss of sign in promotion - STL bug
return found;
}
}
//-----------------------------------------------------------------
/**
* Create a map of CharData's from a UnicodeData.txt standard Unicode 3.0 file, which has been packed into a buffer
*/
CharDataMap::ErrorCode CharDataMap::generateMapFromBuffer (const Blocks::Mapping & blockMapping, const std::string & str_buf)
{
m_dataIsValid = false;
m_map.clear ();
//-- create the category map for use by the inline population function
CategoryMap_t cmap;
{
size_t i = 0;
for (; CharData::ms_categoryNames [i].m_category != CharData::Cn; ++i)
{
cmap [CharData::ms_categoryNames [i].m_str] = CharData::ms_categoryNames [i].m_category;
}
}
typedef std::set<unicode_char_t> IdSet_t;
IdSet_t idSet;
{
for (BlockIdSet_t::const_iterator iter = m_blockIds.begin (); iter != m_blockIds.end (); ++iter)
{
const Blocks::Data & blockData = blockMapping.findBlock (*iter);
if (blockData.m_id != Blocks::End_Block_Ids)
{
blockData.generateFilteredIdSet (idSet);
}
}
}
//-- read all the desired chars from file.
//-- the file must be sorted by code
size_t bufpos = 0;
size_t validChars = 0;
{
for (IdSet_t::const_iterator iter = idSet.begin (); iter != idSet.end (); ++iter)
{
CharData * data = new CharData;
assert (data); //lint !e1924 // c-style cast. MSVC bug
data->m_reverseCase = 0;
if (populateDataFromBuffer (*iter, *data, str_buf, bufpos, cmap) == false)
{
delete data;
continue;
}
else
{
++validChars;
m_map[data->m_code] = data;
}
}
}
//--
//-- pack all the char data into a contiguous block of memory
//--
if (m_contiguousData)
delete[] m_contiguousData;
m_contiguousData = new CharData [validChars];
assert (m_contiguousData); //lint !e1924 // c-style cast. MSVC bug
size_t dataIndex = 0;
for (Map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter, ++dataIndex)
{
m_contiguousData [dataIndex] = *(*iter).second;
delete (*iter).second;
(*iter).second = &m_contiguousData [dataIndex];
}
m_dataIsValid = true;
return ERR_SUCCESS;
}
//----------------------------------------------------------------------
/**
* Create a map of CharData's from a UnicodeData.txt standard Unicode 3.0 file, using cstdio
*/
CharDataMap::ErrorCode CharDataMap::generateMap (const Blocks::Mapping & blockMapping, const char * filename)
{
//-- load data from file as a big std::string
//-- read all the desired chars from file.
//-- the file must be sorted by code
FILE * fl = fopen (filename, "rb");
if (fl == 0)
{
return ERR_NO_FILE;
}
fseek (fl, 0, SEEK_END);
size_t fileLen = static_cast<size_t>(ftell (fl));
fseek (fl, 0, SEEK_SET);
char * buffer = new char [fileLen + 1];
buffer [fileLen] = 0;
assert (buffer); //lint !e1924 // c-style cast. MSVC bug
if (fread (buffer, fileLen, 1, fl) != 1)
{
delete[] buffer;
fclose (fl);
return ERR_READ_FAILED;
}
if (fclose (fl))
{
delete[] buffer;
return ERR_CLOSE_FAILED;
}
std::string str_buf (buffer, fileLen);
delete[] buffer;
return generateMapFromBuffer (blockMapping, str_buf);
}
//-----------------------------------------------------------------
/**
* Add a block Id that this CharacterDataMap is concerned with. Does not change the data map.
*/
void CharDataMap::addBlock (Blocks::Id id)
{
m_blockIds.insert (id);
}
//-----------------------------------------------------------------
/**
* Remove a block Id that this CharacterDataMap is concerned with. Does not change the data map.
*/
void CharDataMap::removeBlock (Blocks::Id id)
{
m_blockIds.erase (id);
}
//-----------------------------------------------------------------
/*
* Add a block Id that this CharacterDataMap is concerned with. Does not change the data map.
*/
void CharDataMap::clearBlocks ()
{
m_blockIds.clear ();
}
// ======================================================================
};
#ifdef EXTERNAL_DISTRO
};
#endif
@@ -0,0 +1,156 @@
// ======================================================================
//
// UnicodeCharDataMap.h
// copyright (c) 2001 Sony Online Entertainment
//
// This contains Unicode 3.0 compliant Character data formats
// The data is loaded dynamically from the UnicodeData.txt definition file
//
// ======================================================================
#ifndef INCLUDED_PlatUnicodeCharDataMap_H
#define INCLUDED_PlatUnicodeCharDataMap_H
#if WIN32
// stl warning func not inlined
#pragma warning (disable:4710)
#pragma warning (disable:4786)
#endif
#include <map>
#include <set>
#include "UnicodeBlocks.h"
// ======================================================================
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Plat_Unicode
{
struct CharData;
//-----------------------------------------------------------------
/**
* Singleton class that allows mapping from code points to CharData objects. This will be
* used to change case of characters, character category testing, etc...
* A CharacterDataMap has a set of Unicode::Block::Id's with which it is solely concerned.
* In this way, you may instantiate many different CharDataMaps if needed.
*/
class CharDataMap
{
public:
enum ErrorCode
{
ERR_SUCCESS = 0,
ERR_NO_FILE,
ERR_READ_FAILED,
ERR_CLOSE_FAILED,
ERR_CHAR_NOT_FOUND,
ERR_FILE_TOO_SHORT
};
typedef std::map <unicode_char_t, CharData *> Map_t;
static CharDataMap & getDefaultMap ();
static void explicitDestroy ();
CharDataMap ();
~CharDataMap ();
void addBlock (Blocks::Id id);
void removeBlock (Blocks::Id id);
void clearBlocks ();
ErrorCode generateMap (const Blocks::Mapping & blockMapping, const char * filename);
ErrorCode generateMapFromBuffer (const Blocks::Mapping & blockMapping, const std::string & str_buf);
bool isValid () const;
const CharData * findCharData (unicode_char_t code) const;
const Map_t & getMap () const;
private:
static void initSingleton ();
typedef std::set<Blocks::Id> BlockIdSet_t;
BlockIdSet_t m_blockIds;
CharData * m_contiguousData;
Map_t m_map;
bool m_dataIsValid;
static CharDataMap * ms_singleton;
};
//-----------------------------------------------------------------
/**
* Singleton accessor.
*/
inline CharDataMap & CharDataMap::getDefaultMap ()
{
if (ms_singleton)
return *ms_singleton;
initSingleton ();
return *ms_singleton;
}
//-----------------------------------------------------------------
/**
* Has the data been loaded successfully?
*/
inline bool CharDataMap::isValid () const
{
return m_dataIsValid;
}
//-----------------------------------------------------------------
/**
* Find a CharData for the given code point.
* @return null if no CharData exists for this code point
*/
inline const CharData * CharDataMap::findCharData (const unicode_char_t code) const
{
if (isValid ())
{
const Map_t::const_iterator iter = m_map.find (code);
if (iter != m_map.end ())
return (*iter).second;
}
return 0;
}
//-----------------------------------------------------------------
/**
* Get the data mapping
*/
inline const CharDataMap::Map_t & CharDataMap::getMap () const
{
return m_map;
}
};
#ifdef EXTERNAL_DISTRO
};
#endif
// ======================================================================
#endif
@@ -0,0 +1,285 @@
// ======================================================================
//
// 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 (), tolower);
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 (), toupper);
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 (), tolower);
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 (), toupper);
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
{
void get(Base::ByteStream::ReadIterator& source, Plat_Unicode::String& target)
{
unsigned int size = 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);
target.assign (ubuf, ubuf + size);
const unsigned int readSize = size * sizeof (Plat_Unicode::unicode_char_t);
source.advance(readSize);
// printf("%d\n", target.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
@@ -0,0 +1,362 @@
// ======================================================================
//
// 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