mirror of
https://github.com/SWG-Source/src.git
synced 2026-10-11 03:13:28 -04:00
Added TransferServer project and CTServiceGameAPI library
This commit is contained in:
@@ -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
|
||||
|
||||
+71
@@ -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
|
||||
+71
@@ -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
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
// ======================================================================
|
||||
+125
@@ -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
|
||||
+360
@@ -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
|
||||
|
||||
+156
@@ -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
|
||||
Reference in New Issue
Block a user