mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
- ripped out a lot of unused code dealing with utf8
This commit is contained in:
parent
d0006db4a1
commit
4a0617b12c
@ -675,7 +675,7 @@ void MenuStateJoinGame::keyPress(SDL_KeyboardEvent c) {
|
||||
//text.insert(text.end()-1, key);
|
||||
char szCharText[20]="";
|
||||
snprintf(szCharText,20,"%c",key);
|
||||
char *utfStr = String::ConvertToUTF8(&szCharText[0]);
|
||||
char *utfStr = ConvertToUTF8(&szCharText[0]);
|
||||
if(text.size() > 0) {
|
||||
text.insert(text.end() -1, utfStr[0]);
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ void MenuStateKeysetup::keyDown(SDL_KeyboardEvent key) {
|
||||
|
||||
char szCharText[20]="";
|
||||
snprintf(szCharText,20,"%c",hotkeyChar);
|
||||
char *utfStr = String::ConvertToUTF8(&szCharText[0]);
|
||||
char *utfStr = ConvertToUTF8(&szCharText[0]);
|
||||
|
||||
char szBuf[8096] = "";
|
||||
snprintf(szBuf,8096,"%s [%s][%d][%d][%d][%d]",keyName.c_str(),utfStr,key.keysym.sym,hotkeyChar,key.keysym.unicode,key.keysym.mod);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* TA3D, a remake of Total Annihilation
|
||||
/* Portions taken from:
|
||||
Copyright (C) 2005 Roland BROCHARD
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -18,38 +18,13 @@
|
||||
#ifndef _SHARED_UTIL_W_STRING_H__
|
||||
#define _SHARED_UTIL_W_STRING_H__
|
||||
|
||||
# include <sstream>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include <cstdarg>
|
||||
# include <string>
|
||||
#include <string>
|
||||
#include "data_types.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
//! \name Macros for Shared::Util::String
|
||||
//@{
|
||||
|
||||
//! Macro to append some data to the string
|
||||
# define TA3D_WSTR_APPEND std::stringstream out; \
|
||||
out << v; \
|
||||
append(out.str());\
|
||||
return *this
|
||||
|
||||
//! Macro to convert the string into a given type
|
||||
# define TA3D_WSTR_CAST_OP(X) X v; \
|
||||
fromString<X>(v, *this); \
|
||||
return v;
|
||||
|
||||
//! Macro to append the value of a boolean (true -> "true", false -> "false")
|
||||
# define TA3D_WSTR_APPEND_BOOL(X) append(X ? "true" : "false")
|
||||
|
||||
//@} // Macros for Shared::Util::String
|
||||
|
||||
|
||||
# define TA3D_WSTR_SEPARATORS " \t\r\n"
|
||||
|
||||
#ifndef WIN32
|
||||
using Shared::Platform::byte;
|
||||
@ -59,569 +34,36 @@ using namespace Shared::Platform;
|
||||
|
||||
namespace Shared { namespace Util {
|
||||
|
||||
/*! \class String
|
||||
** \brief A String implementation for `TA3D`
|
||||
**
|
||||
** \code
|
||||
** Shared::Util::String a("abcd");
|
||||
** std::cout << a << std::endl; // display: `abcd`
|
||||
** Shared::Util::String b(10 + 2);
|
||||
** std::cout << b << std::endl; // display: `12`
|
||||
** Shared::Util::String c(10.3);
|
||||
** std::cout << c << std::endl; // display: `10.3`
|
||||
**
|
||||
** // The same with the operator `<<`
|
||||
** Shared::Util::String d;
|
||||
** d << "Value : " << 42;
|
||||
** std::cout << d << std::endl; // display: `Value : 42`
|
||||
** \endcode
|
||||
**
|
||||
** Here is an example to show when to use static methods :
|
||||
** \code
|
||||
** Shared::Util::String s = "HelLo wOrLd";
|
||||
** std::cout << Shared::Util::String::ToLower(s) << std::endl; // `hello world`
|
||||
** std::cout << s << std::endl; // `HelLo wOrLd`
|
||||
** std::cout << s.toLower() << std::endl; // `hello world`
|
||||
** std::cout << s << std::endl; // `hello world`
|
||||
** \endcode
|
||||
/*!
|
||||
** \brief Convert a string from ASCII to UTF8
|
||||
** \param s The string to convert
|
||||
** \return A new Null-terminated String (must be deleted with the keyword `delete[]`), even if s is NULL
|
||||
*/
|
||||
class String : public std::string
|
||||
{
|
||||
public:
|
||||
//! A String list
|
||||
typedef std::list<String> List;
|
||||
//! A String vector
|
||||
typedef std::vector<String> Vector;
|
||||
char* ConvertToUTF8(const char* s);
|
||||
|
||||
//! Char Case
|
||||
enum CharCase
|
||||
{
|
||||
//! The string should remain untouched
|
||||
soCaseSensitive,
|
||||
//! The string should be converted to lowercase
|
||||
soIgnoreCase
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
** \brief Copy then Convert the case (lower case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToLower(const char* s) {return String(s).toLower();}
|
||||
/*!
|
||||
** \brief Copy then Convert the case (lower case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToLower(const wchar_t* s) {return String(s).toLower();}
|
||||
/*!
|
||||
** \brief Copy then Convert the case (lower case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToLower(const String& s) {return String(s).toLower();}
|
||||
|
||||
/*!
|
||||
** \brief Copy then Convert the case (upper case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToUpper(const char* s) {return String(s).toUpper();}
|
||||
/*!
|
||||
** \brief Copy then Convert the case (upper case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToUpper(const wchar_t* s) {return String(s).toUpper();}
|
||||
/*!
|
||||
** \brief Copy then Convert the case (upper case) of characters in the string using the UTF8 charset
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ToUpper(const String& s) {return String(s).toUpper();}
|
||||
|
||||
/*!
|
||||
** \brief Remove trailing and leading spaces
|
||||
** \param s The string to convert
|
||||
** \param trimChars The chars to remove
|
||||
** \return A new string
|
||||
*/
|
||||
static String Trim(const char* s, const String& trimChars = TA3D_WSTR_SEPARATORS) {return String(s).trim(trimChars);}
|
||||
/*!
|
||||
** \brief Remove trailing and leading spaces
|
||||
** \param s The string to convert
|
||||
** \param trimChars The chars to remove
|
||||
** \return A new string
|
||||
*/
|
||||
static String Trim(const wchar_t* s, const String& trimChars = TA3D_WSTR_SEPARATORS) {return String(s).trim(trimChars);}
|
||||
/*!
|
||||
** \brief Remove trailing and leading spaces
|
||||
** \param s The string to convert
|
||||
** \param trimChars The chars to remove
|
||||
** \return A new string
|
||||
*/
|
||||
static String Trim(const String& s, const String& trimChars = TA3D_WSTR_SEPARATORS) {return String(s).trim(trimChars);}
|
||||
|
||||
/*!
|
||||
** \brief Convert all antislashes into slashes
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ConvertAntiSlashesIntoSlashes(const String& s) {return String(s).convertAntiSlashesIntoSlashes();}
|
||||
|
||||
/*!
|
||||
** \brief Convert all slashes into antislashes
|
||||
** \param s The string to convert
|
||||
** \return A new string
|
||||
*/
|
||||
static String ConvertSlashesIntoAntiSlashes(const String& s) {return String(s).convertSlashesIntoAntiSlashes();}
|
||||
|
||||
/*!
|
||||
** \brief Extract the key and its value from a string (mainly provided by TDF files)
|
||||
**
|
||||
** \param s A line (ex: ` category=core vtol ctrl_v level1 weapon notsub ;`)
|
||||
** \param[out] key The key that has been found
|
||||
** \param[out] value The associated value
|
||||
** \param chcase The key will be converted to lowercase if equals to `soIgnoreCase`
|
||||
**
|
||||
** \code
|
||||
** String k, v;
|
||||
**
|
||||
** // -> k='category'
|
||||
** // -> v='core vtol ctrl_v level1 weapon notsub'
|
||||
** String::ToKeyValue(" category=core vtol ctrl_v level1 weapon notsub ;", k, v)
|
||||
**
|
||||
** // -> k='foo'
|
||||
** // -> v='bar'
|
||||
** String::ToKeyValue(" foo = bar ; ");
|
||||
**
|
||||
** // -> k='}' v=''
|
||||
** String::ToKeyValue(" } ", k, v);
|
||||
**
|
||||
** // -> k='[' v='Example of Section'
|
||||
** String::ToKeyValue(" [Example of Section] ", k, v);
|
||||
**
|
||||
** // -> k='foo' v='bar'
|
||||
** String::ToKeyValue(" foo=bar; // comment", k, v);
|
||||
**
|
||||
** // -> k='foo' v='bar'
|
||||
** String::ToKeyValue(" foo=bar; // comments here; ", k, v);
|
||||
** \endcode
|
||||
*/
|
||||
static void ToKeyValue(const String& s, String& key, String& value, const enum CharCase chcase = soCaseSensitive);
|
||||
|
||||
/*!
|
||||
** \brief Find the index of a string in a vector
|
||||
** \param l The vector
|
||||
** \param s The string to look for
|
||||
** \return The index of the string found, -1 otherwise
|
||||
*/
|
||||
static int FindInList(const String::Vector& l, const char* s);
|
||||
static int FindInList(const String::Vector& l, const String& s);
|
||||
|
||||
|
||||
/*!
|
||||
** \brief Convert a string from ASCII to UTF8
|
||||
** \param s The string to convert
|
||||
** \return A new Null-terminated String (must be deleted with the keyword `delete[]`), even if s is NULL
|
||||
*/
|
||||
static char* ConvertToUTF8(const char* s);
|
||||
/*!
|
||||
** \brief Convert a string from ASCII to UTF8
|
||||
** \param s The string to convert
|
||||
** \param len The length of the string
|
||||
** \param[out] The new size
|
||||
** \return A new Null-terminated String (must be deleted with the keyword `delete[]`), even if s is NULL
|
||||
*/
|
||||
static char* ConvertToUTF8(const char* s, const Shared::Platform::uint32 len);
|
||||
static char* ConvertToUTF8(const char* s, const Shared::Platform::uint32 len, Shared::Platform::uint32& newSize);
|
||||
|
||||
/*!
|
||||
** \brief Convert a string from ASCII to UTF8
|
||||
** \param s The string to convert
|
||||
** \return A new String
|
||||
*/
|
||||
static String ConvertToUTF8(const String& s);
|
||||
|
||||
static char* ConvertFromUTF8(const char* str);
|
||||
|
||||
/*!
|
||||
** \brief Formatted string
|
||||
** \param format The format of the new string
|
||||
** \return A new string
|
||||
*/
|
||||
static String Format(const String& f, ...);
|
||||
static String Format(const char* f, ...);
|
||||
|
||||
public:
|
||||
//! \name Constructors and Destructor
|
||||
//@{
|
||||
//! Default constructor
|
||||
String() :std::string() {}
|
||||
//! Constructor by copy
|
||||
String(const String& v, size_type pos = 0, size_type n = npos) :std::string(v, pos, n) {}
|
||||
//! Constructor with a default value from a std::string
|
||||
String(const std::string& v) :std::string(v) {}
|
||||
//! Constructor with a default value from a wide string (wchar_t*)
|
||||
String(const wchar_t* v) :std::string() {if (v) *this << v;}
|
||||
//! Constructor with a default value from a string (char*)
|
||||
String(const char* v) :std::string() { if (v) append(v); }
|
||||
//! Constructor with a default value from a string (char*) and a length
|
||||
String(const char* v, String::size_type n) :std::string(v, n) {}
|
||||
//! Constructor with a default value from a single char
|
||||
String(const char v) :std::string() {*this += v;}
|
||||
//! Constructor with a default value from an int (8 bits)
|
||||
String(const int8_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an int (16 bits)
|
||||
String(const int16_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an int (32 bits)
|
||||
String(const int32_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an int (64 bits)
|
||||
String(const int64_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an unsigned int (8 bits)
|
||||
String(const uint8_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an unsigned int (16 bits)
|
||||
String(const uint16_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an unsigned int (32 bits)
|
||||
String(const uint32_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from an unsigned int (64 bits)
|
||||
String(const uint64_t v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from a float
|
||||
String(const float v) :std::string() {*this << v;}
|
||||
//! Constructor with a default value from a double
|
||||
String(const double v) :std::string() {*this << v;}
|
||||
//! Destructor
|
||||
~String() {}
|
||||
//@}
|
||||
|
||||
|
||||
//! \name The operator `<<`
|
||||
//@{
|
||||
//! Append a string (char*)
|
||||
String& operator << (const char* v) {append(v);return *this;}
|
||||
//! Append a string (stl)
|
||||
String& operator << (const std::string& v) {append(v);return *this;}
|
||||
//! Append a string (Shared::Util::String)
|
||||
String& operator << (const String& v) {append(v);return *this;}
|
||||
//! Append a single char
|
||||
String& operator << (const char v) {*(static_cast<std::string*>(this)) += v; return *this;}
|
||||
//! Append a wide string (wchar_t*)
|
||||
String& operator << (const wchar_t* v);
|
||||
//! Append an int (8 bits)
|
||||
String& operator << (const int8_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an unsigned int (8 bits)
|
||||
String& operator << (const uint8_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an int (16 bits)
|
||||
String& operator << (const int16_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an unsigned int (16 bits)
|
||||
String& operator << (const uint16_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an int (32 bits)
|
||||
String& operator << (const int32_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an unsigned int (32 bits)
|
||||
String& operator << (const uint32_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an int (64 bits)
|
||||
String& operator << (const int64_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Append an unsigned int (64 bits)
|
||||
String& operator << (const uint64_t v) {TA3D_WSTR_APPEND;}
|
||||
//! Convert then Append a float
|
||||
String& operator << (const float v) {TA3D_WSTR_APPEND;}
|
||||
//! Convert then Append a double
|
||||
String& operator << (const double v) {TA3D_WSTR_APPEND;}
|
||||
//! Convert then Append a boolean (will be converted into "true" or "false")
|
||||
String& operator << (const bool v) {TA3D_WSTR_APPEND_BOOL(v);return *this;}
|
||||
//@}
|
||||
|
||||
|
||||
//! \name Convertions
|
||||
//@{
|
||||
//! Convert this string into an int (8 bits)
|
||||
int8_t toInt8() const {TA3D_WSTR_CAST_OP(int8_t);}
|
||||
//! Convert this string into an int (16 bits)
|
||||
int16_t toInt16() const {TA3D_WSTR_CAST_OP(int16_t);}
|
||||
//! Convert this string into an int (32 bits)
|
||||
int32_t toInt32() const {TA3D_WSTR_CAST_OP(int32_t);}
|
||||
//! Convert this string into an int (64 bits)
|
||||
int64_t toInt64() const {TA3D_WSTR_CAST_OP(int64_t);}
|
||||
//! Convert this string into an unsigned int (8 bits)
|
||||
uint8_t toUInt8() const {TA3D_WSTR_CAST_OP(uint8_t);}
|
||||
//! Convert this string into an unsigned int (16 bits)
|
||||
uint16_t toUInt16() const {TA3D_WSTR_CAST_OP(uint16_t);}
|
||||
//! Convert this string into an unsigned int (32 bits)
|
||||
uint32_t toUInt32() const {TA3D_WSTR_CAST_OP(uint32_t);}
|
||||
//! Convert this string into an unsigned int (64 bits)
|
||||
uint64_t toUInt64() const {TA3D_WSTR_CAST_OP(uint64_t);}
|
||||
//! Convert this string into a float
|
||||
float toFloat() const {TA3D_WSTR_CAST_OP(float);}
|
||||
//! Convert this string into a float with a default value if empty
|
||||
float toFloat(const float def) const {if (empty()) return def;TA3D_WSTR_CAST_OP(float);}
|
||||
//! Convert this string into a double
|
||||
double toDouble() const {TA3D_WSTR_CAST_OP(double);}
|
||||
//! Convert this string into a bool (true if the lower case value is equals to "true", "1" or "on")
|
||||
bool toBool() const;
|
||||
|
||||
//! \name The operator `+=` (with the same abilities than the operator `<<`)
|
||||
//@{
|
||||
//! Append a string (char*)
|
||||
String& operator += (const char* v) {append(v); return *this;}
|
||||
//! Append a string (stl)
|
||||
String& operator += (const std::string& v) {append(v); return *this;}
|
||||
//! Append a string (Shared::Util::String)
|
||||
String& operator += (const Shared::Util::String& v) {append(v); return *this; }
|
||||
//! Append a single char
|
||||
String& operator += (const char v) {*(static_cast<std::string*>(this)) += (char)v; return *this;}
|
||||
//! Append a wide string (wchar_t*)
|
||||
String& operator += (const wchar_t* v) {*this << v; return *this;}
|
||||
//! Append an int (8 bits)
|
||||
String& operator += (const int8_t v) {*this << v; return *this;}
|
||||
//! Append an unsigned int (8 bits)
|
||||
String& operator += (const uint8_t v) {*this << v; return *this;}
|
||||
//! Append an int (16 bits)
|
||||
String& operator += (const int16_t v) {*this << v; return *this; }
|
||||
//! Append an unsigned int (16 bits)
|
||||
String& operator += (const uint16_t v) {*this << v; return *this; }
|
||||
//! Append an int (32 bits)
|
||||
String& operator += (const int32_t v) {*this << v; return *this; }
|
||||
//! Append an unsigned int (32 bits)
|
||||
String& operator += (const uint32_t v) {*this << v; return *this; }
|
||||
//! Append an int (64 bits)
|
||||
String& operator += (const int64_t v) {*this << v; return *this; }
|
||||
//! Append an unsigned int (64 bits)
|
||||
String& operator += (const uint64_t v) {*this << v; return *this; }
|
||||
//! Convert then Append a float
|
||||
String& operator += (const float v) {*this << v; return *this; }
|
||||
//! Convert then Append a double
|
||||
String& operator += (const double v) {*this << v; return *this; }
|
||||
//! Convert then Append a boolean (will be converted into "true" or "false")
|
||||
String& operator += (const bool v) {TA3D_WSTR_APPEND_BOOL(v); return *this; }
|
||||
//@}
|
||||
|
||||
|
||||
//! \name The operator `+`
|
||||
//@{
|
||||
//! Create a new String from the concatenation of *this and a string
|
||||
const String operator + (const String& rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a char
|
||||
const String operator + (const char rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a widechar
|
||||
const String operator + (const wchar_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a const char*
|
||||
const String operator + (const char* rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a wide string
|
||||
const String operator + (const wchar_t* rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a signed int (8 bits)
|
||||
const String operator + (const int8_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a signed int (16 bits)
|
||||
const String operator + (const int16_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a signed int (32 bits)
|
||||
const String operator + (const int32_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a signed int (64 bits)
|
||||
const String operator + (const int64_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and an unsigned int (8 bits)
|
||||
const String operator + (const uint8_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and an unsigned int (16 bits)
|
||||
const String operator + (const uint16_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and an unsigned int (32 bits)
|
||||
const String operator + (const uint32_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and an unsigned int (64 bits)
|
||||
const String operator + (const uint64_t rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a float
|
||||
const String operator + (const float rhs) { return String(*this) += rhs; }
|
||||
//! Create a new String from the concatenation of *this and a double
|
||||
const String operator + (const double rhs) { return String(*this) += rhs; }
|
||||
//@}
|
||||
|
||||
|
||||
//! \name Case convertion
|
||||
//@{
|
||||
/*!
|
||||
** \brief Convert the case (lower case) of characters in the string using the UTF8 charset
|
||||
** \return Returns *this
|
||||
*/
|
||||
String& toLower();
|
||||
/*!
|
||||
** \brief Convert the case (upper case) of characters in the string using the UTF8 charset
|
||||
** \return Returns *this
|
||||
*/
|
||||
String& toUpper();
|
||||
//@} Case convertion
|
||||
|
||||
|
||||
/*!
|
||||
** \brief Remove trailing and leading spaces
|
||||
** \param trimChars The chars to remove
|
||||
** \return Returns *this
|
||||
*/
|
||||
String& trim(const String& trimChars = TA3D_WSTR_SEPARATORS);
|
||||
|
||||
|
||||
//! \name Split
|
||||
//@{
|
||||
|
||||
/*!
|
||||
** \brief Divide a string into several parts
|
||||
** \param[out] All found parts
|
||||
** \param sepearators Sequence of chars considered as a separator
|
||||
** \param emptyBefore True to clear the vector before fulfill it
|
||||
** \warning Do not take care of string representation (with `'` or `"`)
|
||||
*/
|
||||
void split(String::Vector& out, const String& separators = TA3D_WSTR_SEPARATORS, const bool emptyBefore = true) const;
|
||||
/*!
|
||||
** \brief Divide a string into several parts
|
||||
** \param[out] All found parts
|
||||
** \param sepearators Sequence of chars considered as a separator
|
||||
** \param emptyBefore True to clear the list before fulfill it
|
||||
** \warning Do not take care of string representation (with `'` or `"`)
|
||||
*/
|
||||
void split(String::List& out, const String& separators = TA3D_WSTR_SEPARATORS, const bool emptyBefore = true) const;
|
||||
|
||||
//@} Split
|
||||
|
||||
|
||||
/*!
|
||||
** \brief Extract the key and its value from a string (mainly provided by TDF files)
|
||||
**
|
||||
** \param[out] key The key that has been found
|
||||
** \param[out] value The associated value
|
||||
**
|
||||
** \see String::ToKeyValue()
|
||||
*/
|
||||
void toKeyValue(String& key, String& value, const enum CharCase chcase = soCaseSensitive) const
|
||||
{ToKeyValue(*this, key, value, chcase);}
|
||||
|
||||
/*!
|
||||
** \brief Convert all antislashes into slashes
|
||||
** \return Returns *this
|
||||
*/
|
||||
String& convertAntiSlashesIntoSlashes();
|
||||
|
||||
/*!
|
||||
** \brief Convert all slashes into antislashes
|
||||
** \return Returns *this
|
||||
*/
|
||||
String& convertSlashesIntoAntiSlashes();
|
||||
|
||||
/*!
|
||||
** \brief Get the hash value of this string
|
||||
*/
|
||||
Shared::Platform::uint32 hashValue() const;
|
||||
|
||||
/*!
|
||||
** \brief Convert the string from ASCII to UTF8
|
||||
** \return Always *this
|
||||
*/
|
||||
String& convertToUTF8() {*this = ConvertToUTF8(*this); return *this;}
|
||||
|
||||
/*!
|
||||
** \brief Replace a substr by another one
|
||||
** \param toSearch The string to look for
|
||||
** \param replaceWith The string replacement
|
||||
** \param option Option when looking for the string `toSearch`
|
||||
** \return Always *this
|
||||
*/
|
||||
String& findAndReplace(const String& toSearch, const String& replaceWith, const enum String::CharCase option = soCaseSensitive);
|
||||
String& findAndReplace(char toSearch, const char replaceWith, const enum String::CharCase option = soCaseSensitive);
|
||||
|
||||
/*!
|
||||
** \brief Reset the current value with a formatted string
|
||||
** \param f The format of the new string
|
||||
** \return Always *this
|
||||
*/
|
||||
String& format(const String& f, ...);
|
||||
String& format(const char* f, ...);
|
||||
|
||||
/*!
|
||||
** \brief Append a formatted string
|
||||
** \param f The format of the new string
|
||||
** \return Always *this
|
||||
*/
|
||||
String& appendFormat(const String& f, ...);
|
||||
String& appendFormat(const char* f, ...);
|
||||
String& vappendFormat(const char* f, va_list parg);
|
||||
|
||||
|
||||
/*!
|
||||
** \brief Detect if the string matches the given pattern
|
||||
** \param pattern
|
||||
** \return true if match
|
||||
*/
|
||||
bool match(const String &pattern);
|
||||
|
||||
/*!
|
||||
** \brief returns a substring assuming current string is an UTF8 String
|
||||
** \param pos
|
||||
** \param len
|
||||
** \return the substring
|
||||
*/
|
||||
String substrUTF8(int pos = 0, int len = -1) const;
|
||||
|
||||
/*!
|
||||
** \brief returns the String size assuming it's in UTF8
|
||||
** \return the number of UTF8 symbols
|
||||
*/
|
||||
int sizeUTF8() const;
|
||||
|
||||
private:
|
||||
/*!
|
||||
** \brief Convert a string into another type, given by the template parameter `T`
|
||||
** \param[out] t The destination variable
|
||||
** \param s The string to convert
|
||||
** \param f The base to use for the convertion (std::hex, std::dec, ...)
|
||||
** \return True if the operation succeeded, False otherwise
|
||||
*/
|
||||
template <class T>
|
||||
bool fromString(T& t, const String& s) const
|
||||
{
|
||||
std::istringstream iss(s);
|
||||
if (s.size() > 2)
|
||||
{
|
||||
if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||
iss >> std::hex;
|
||||
else if (s[0] == '0' && s[1] != 'x' && s[1] != 'X')
|
||||
iss >> std::oct;
|
||||
else
|
||||
iss >> std::dec;
|
||||
}
|
||||
else
|
||||
iss >> std::dec;
|
||||
return !(iss >> t).fail();
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
static int ASCIItoUTF8(const Shared::Platform::byte c, Shared::Platform::byte *out);
|
||||
#else
|
||||
static int ASCIItoUTF8(const byte c, byte *out);
|
||||
#endif
|
||||
}; // class String
|
||||
|
||||
|
||||
|
||||
//int ASCIItoUTF8(const byte c, byte *out);
|
||||
char* ConvertFromUTF8(const char* str);
|
||||
|
||||
/*!
|
||||
** \brief Convert an UTF-8 String into a WideChar String
|
||||
** \This class must be removed as soon as possible and is only here to prevent against
|
||||
** stange bugs with the previous implementation
|
||||
*/
|
||||
struct WString
|
||||
{
|
||||
public:
|
||||
WString(const char* s);
|
||||
WString(const String& str);
|
||||
WString(const std::string& str);
|
||||
|
||||
void fromUtf8(const char* s, size_t length);
|
||||
const wchar_t* cw_str() const {return pBuffer;}
|
||||
|
||||
private:
|
||||
wchar_t pBuffer[5120];
|
||||
wchar_t pBuffer[8096];
|
||||
};
|
||||
|
||||
|
||||
void strrev(char *p);
|
||||
void strrev_utf8(char *p);
|
||||
void strrev_utf8(std::string &p);
|
||||
bool is_string_all_ascii(std::string str);
|
||||
|
||||
}} // namespace TA3D
|
||||
}}
|
||||
|
||||
#endif // _SHARED_UTIL_W_STRING_H__
|
||||
|
@ -88,7 +88,7 @@ void Properties::load(const string &path, bool clearCurrentProperties) {
|
||||
if(lineBuffer[0] != '\0') {
|
||||
// If the file is NOT in UTF-8 format convert each line
|
||||
if(is_utf8_language == false && Font::forceLegacyFonts == false) {
|
||||
char *utfStr = String::ConvertToUTF8(&lineBuffer[0]);
|
||||
char *utfStr = ConvertToUTF8(&lineBuffer[0]);
|
||||
|
||||
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
|
||||
|
||||
@ -98,7 +98,7 @@ void Properties::load(const string &path, bool clearCurrentProperties) {
|
||||
delete [] utfStr;
|
||||
}
|
||||
else if(is_utf8_language == true && Font::forceLegacyFonts == true) {
|
||||
char *asciiStr = String::ConvertFromUTF8(&lineBuffer[0]);
|
||||
char *asciiStr = ConvertFromUTF8(&lineBuffer[0]);
|
||||
|
||||
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* TA3D, a remake of Total Annihilation
|
||||
/* Portions taken from:
|
||||
Copyright (C) 2005 Roland BROCHARD
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -13,326 +13,91 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//#include "../stdafx.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared { namespace Util {
|
||||
|
||||
namespace
|
||||
{
|
||||
int stdLowerCase (int c)
|
||||
{
|
||||
return tolower(c);
|
||||
}
|
||||
|
||||
int stdUpperCase (int c)
|
||||
{
|
||||
return toupper(c);
|
||||
}
|
||||
#ifndef WIN32
|
||||
int ASCIItoUTF8(const Shared::Platform::byte c, Shared::Platform::byte *out) {
|
||||
#else
|
||||
int ASCIItoUTF8(const byte c, byte *out) {
|
||||
#endif
|
||||
if (c < 0x80) {
|
||||
*out = c;
|
||||
return 1;
|
||||
}
|
||||
else if(c < 0xC0) {
|
||||
out[0] = 0xC2;
|
||||
out[1] = c;
|
||||
return 2;
|
||||
}
|
||||
out[0] = 0xC3;
|
||||
out[1] = c - 0x40;
|
||||
return 2;
|
||||
}
|
||||
|
||||
String&
|
||||
String::operator << (const wchar_t* v)
|
||||
{
|
||||
size_t l = wcslen(v);
|
||||
char* b = new char[l + 1];
|
||||
#ifndef WINDOWS
|
||||
wcstombs(&b[0], v, l);
|
||||
#else
|
||||
size_t i;
|
||||
wcstombs_s(&i, &b[0], l, v, l);
|
||||
#endif
|
||||
append(b);
|
||||
delete [] b;
|
||||
return *this;
|
||||
char* ConvertToUTF8(const char* s, Shared::Platform::uint32 len, Shared::Platform::uint32& newSize) {
|
||||
if (NULL == s || '\0' == *s) {
|
||||
char* ret = new char[1];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
*ret = '\0';
|
||||
return ret;
|
||||
}
|
||||
#ifndef WIN32
|
||||
Shared::Platform::byte tmp[4];
|
||||
#else
|
||||
byte tmp[4];
|
||||
#endif
|
||||
newSize = 1;
|
||||
|
||||
#ifndef WIN32
|
||||
for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++)
|
||||
#else
|
||||
for(byte *p = (byte*)s ; *p ; p++)
|
||||
#endif
|
||||
newSize += ASCIItoUTF8(*p, tmp);
|
||||
|
||||
char* ret = new char[newSize];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
|
||||
#ifndef WIN32
|
||||
Shared::Platform::byte *q = (Shared::Platform::byte*)ret;
|
||||
for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++)
|
||||
#else
|
||||
byte *q = (byte*)ret;
|
||||
for(byte *p = (byte*)s ; *p ; p++)
|
||||
|
||||
#endif
|
||||
q += ASCIItoUTF8(*p, q);
|
||||
*q = '\0'; // A bit paranoid
|
||||
return ret;
|
||||
}
|
||||
|
||||
String&
|
||||
String::toLower()
|
||||
{
|
||||
std::transform (this->begin(), this->end(), this->begin(), stdLowerCase);
|
||||
return *this;
|
||||
char* ConvertToUTF8(const char* s, const Shared::Platform::uint32 len) {
|
||||
Shared::Platform::uint32 nws;
|
||||
return ConvertToUTF8(s, len, nws);
|
||||
}
|
||||
|
||||
String&
|
||||
String::toUpper()
|
||||
{
|
||||
std::transform (this->begin(), this->end(), this->begin(), stdUpperCase);
|
||||
return *this;
|
||||
}
|
||||
char* ConvertToUTF8(const char* s) {
|
||||
if (NULL != s && *s != '\0')
|
||||
return ConvertToUTF8(s, strlen(s));
|
||||
char* ret = new char[1];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
*ret = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool String::toBool() const
|
||||
{
|
||||
if (empty() || "0" == *this)
|
||||
return false;
|
||||
if ("1" == *this)
|
||||
return true;
|
||||
String s(*this);
|
||||
s.toLower();
|
||||
return ("true" == s || "on" == s);
|
||||
}
|
||||
|
||||
|
||||
String&
|
||||
String::trim(const String& trimChars)
|
||||
{
|
||||
// Find the first character position after excluding leading blank spaces
|
||||
std::string::size_type startpos = this->find_first_not_of(trimChars);
|
||||
// Find the first character position from reverse af
|
||||
std::string::size_type endpos = this->find_last_not_of(trimChars);
|
||||
|
||||
// if all spaces or empty return an empty string
|
||||
if ((std::string::npos == startpos) || (std::string::npos == endpos))
|
||||
*this = "";
|
||||
else
|
||||
*this = this->substr(startpos, endpos - startpos + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
String::split(String::Vector& out, const String& separators, const bool emptyBefore) const
|
||||
{
|
||||
// Empty the container
|
||||
if (emptyBefore)
|
||||
out.clear();
|
||||
String s(*this);
|
||||
while (!s.empty()) {
|
||||
String::size_type i = s.find_first_of(separators);
|
||||
if (i == std::string::npos)
|
||||
{
|
||||
out.push_back(String::Trim(s));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(String::Trim(s.substr(0, i)));
|
||||
s = s.substr(i + 1, s.size() - i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
String::split(String::List& out, const String& separators, const bool emptyBefore) const
|
||||
{
|
||||
// Empty the container
|
||||
if (emptyBefore)
|
||||
out.clear();
|
||||
String s(*this);
|
||||
while (!s.empty()) {
|
||||
String::size_type i = s.find_first_of(separators);
|
||||
if (i == std::string::npos)
|
||||
{
|
||||
out.push_back(String::Trim(s));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(String::Trim(s.substr(0, i)));
|
||||
s = s.substr(i + 1, s.size() - i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void String::ToKeyValue(const String& s, String& key, String& value, const enum String::CharCase chcase)
|
||||
{
|
||||
// The first usefull character
|
||||
String::size_type pos = s.find_first_not_of(TA3D_WSTR_SEPARATORS);
|
||||
if (pos == String::npos)
|
||||
{
|
||||
// The string is empty
|
||||
key.clear();
|
||||
value.clear();
|
||||
return;
|
||||
}
|
||||
// Begining of a section
|
||||
if (s[pos] == '[')
|
||||
{
|
||||
key = "[";
|
||||
pos = s.find_first_not_of(TA3D_WSTR_SEPARATORS, pos + 1);
|
||||
String::size_type end = s.find_first_of(']', pos);
|
||||
if (end != String::npos)
|
||||
{
|
||||
end = s.find_last_not_of(TA3D_WSTR_SEPARATORS, end - 1);
|
||||
if (pos != String::npos && end != String::npos)
|
||||
value = s.substr(pos, end - pos + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The first `=` character
|
||||
String::size_type equal = s.find_first_of('=', pos);
|
||||
if (equal == String::npos)
|
||||
{
|
||||
// otherwise it is only a string
|
||||
value.clear();
|
||||
// But it may be a comment
|
||||
String::size_type slashes = s.find("//", pos);
|
||||
if (pos == slashes)
|
||||
{
|
||||
key.clear();
|
||||
return;
|
||||
}
|
||||
String::size_type end = s.find_last_not_of(TA3D_WSTR_SEPARATORS, slashes - 1);
|
||||
key = s.substr(pos, end - pos + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// We can extract our key
|
||||
String::size_type end = s.find_last_not_of(TA3D_WSTR_SEPARATORS, equal - 1);
|
||||
key = s.substr(pos, 1 + end - pos);
|
||||
String::size_type slashes = key.rfind("//");
|
||||
// Remove any comments
|
||||
if (slashes != String::npos)
|
||||
{
|
||||
value.clear();
|
||||
if (slashes == 0) // the key is a comment actually
|
||||
key.clear();
|
||||
else
|
||||
{
|
||||
// Get only the good part
|
||||
slashes = key.find_last_not_of(TA3D_WSTR_SEPARATORS, slashes - 1);
|
||||
key = key.substr(0, slashes + 1);
|
||||
if (chcase == soIgnoreCase)
|
||||
key.toLower();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (chcase == soIgnoreCase)
|
||||
key.toLower();
|
||||
|
||||
// Left-Trim for the value
|
||||
equal = s.find_first_not_of(TA3D_WSTR_SEPARATORS, equal + 1);
|
||||
if (String::npos == equal)
|
||||
{
|
||||
value.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Looking for the first semicolon
|
||||
bool needReplaceSemicolons(false);
|
||||
String::size_type semicolon = s.find_first_of(';', equal);
|
||||
while (semicolon != String::npos && s[semicolon - 1] == '\\')
|
||||
{
|
||||
semicolon = s.find_first_of(';', semicolon + 1);
|
||||
needReplaceSemicolons = true;
|
||||
}
|
||||
if (semicolon == String::npos)
|
||||
{
|
||||
// if none is present, looks for a comment to strip it
|
||||
slashes = s.find("//", equal);
|
||||
slashes = s.find_last_not_of(TA3D_WSTR_SEPARATORS, slashes - 1);
|
||||
value = s.substr(equal, 1 + slashes - equal);
|
||||
value.findAndReplace("\\r", "", soCaseSensitive);
|
||||
value.findAndReplace("\\n", "\n", soCaseSensitive);
|
||||
if (needReplaceSemicolons)
|
||||
value.findAndReplace("\\;", ";", soCaseSensitive);
|
||||
return;
|
||||
}
|
||||
// Remove spaces before the semicolon and after the `=`
|
||||
semicolon = s.find_last_not_of(TA3D_WSTR_SEPARATORS, semicolon - 1);
|
||||
|
||||
// We can extract the value
|
||||
if (semicolon >= equal)
|
||||
{
|
||||
value = s.substr(equal, 1 + semicolon - equal);
|
||||
value.findAndReplace("\\r", "", soCaseSensitive);
|
||||
value.findAndReplace("\\n", "\n", soCaseSensitive);
|
||||
if (needReplaceSemicolons)
|
||||
value.findAndReplace("\\;", ";", soCaseSensitive);
|
||||
}
|
||||
else
|
||||
value.clear();
|
||||
}
|
||||
|
||||
|
||||
String& String::convertAntiSlashesIntoSlashes()
|
||||
{
|
||||
for (String::iterator i = this->begin(); i != this->end(); ++i)
|
||||
{
|
||||
if (*i == '\\')
|
||||
*i = '/';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::convertSlashesIntoAntiSlashes()
|
||||
{
|
||||
for (String::iterator i = this->begin(); i != this->end(); ++i)
|
||||
{
|
||||
if (*i == '/')
|
||||
*i = '\\';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Shared::Platform::uint32 String::hashValue() const
|
||||
{
|
||||
Shared::Platform::uint32 hash = 0;
|
||||
for (String::const_iterator i = this->begin(); i != this->end(); ++i)
|
||||
hash = (hash << 5) - hash + *i;
|
||||
return hash;
|
||||
}
|
||||
|
||||
int String::FindInList(const String::Vector& l, const char* s)
|
||||
{
|
||||
int indx(0);
|
||||
for (String::Vector::const_iterator i = l.begin(); i != l.end(); ++i, ++indx)
|
||||
{
|
||||
if(s == *i)
|
||||
return indx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int String::FindInList(const String::Vector& l, const String& s)
|
||||
{
|
||||
int indx(0);
|
||||
for (String::Vector::const_iterator i = l.begin(); i != l.end(); ++i, ++indx)
|
||||
{
|
||||
if(s == *i)
|
||||
return indx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char* String::ConvertFromUTF8(const char* str) {
|
||||
|
||||
/*
|
||||
int length = strlen(str);
|
||||
char *pBuffer = new char[length * 8];
|
||||
memset(pBuffer,0,length * 8);
|
||||
|
||||
int len = 0;
|
||||
for(unsigned int i = 0 ; i < length; i++)
|
||||
{
|
||||
if (((Shared::Platform::byte)str[i]) < 0x80)
|
||||
{
|
||||
pBuffer[len++] = ((Shared::Platform::byte)str[i]);
|
||||
continue;
|
||||
}
|
||||
if (((Shared::Platform::byte)str[i]) >= 0xC0)
|
||||
{
|
||||
wchar_t c = ((Shared::Platform::byte)str[i++]) - 0xC0;
|
||||
while(((Shared::Platform::byte)str[i]) >= 0x80)
|
||||
c = (c << 6) | (((Shared::Platform::byte)str[i++]) - 0x80);
|
||||
--i;
|
||||
pBuffer[len++] = c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pBuffer[len] = 0;
|
||||
return pBuffer;
|
||||
*/
|
||||
|
||||
char* ConvertFromUTF8(const char* str) {
|
||||
const unsigned char *in = reinterpret_cast<const unsigned char*>(str);
|
||||
int len = strlen(str);
|
||||
char *out = new char[len*8];
|
||||
@ -397,352 +162,6 @@ namespace Shared { namespace Util {
|
||||
return out;
|
||||
}
|
||||
|
||||
char* String::ConvertToUTF8(const char* s)
|
||||
{
|
||||
if (NULL != s && *s != '\0')
|
||||
return ConvertToUTF8(s, strlen(s));
|
||||
char* ret = new char[1];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
*ret = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* String::ConvertToUTF8(const char* s, const Shared::Platform::uint32 len)
|
||||
{
|
||||
Shared::Platform::uint32 nws;
|
||||
return ConvertToUTF8(s, len, nws);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
int String::ASCIItoUTF8(const Shared::Platform::byte c, Shared::Platform::byte *out) {
|
||||
#else
|
||||
int String::ASCIItoUTF8(const byte c, byte *out) {
|
||||
#endif
|
||||
if (c < 0x80)
|
||||
{
|
||||
*out = c;
|
||||
return 1;
|
||||
}
|
||||
else if(c < 0xC0)
|
||||
{
|
||||
out[0] = 0xC2;
|
||||
out[1] = c;
|
||||
return 2;
|
||||
}
|
||||
out[0] = 0xC3;
|
||||
out[1] = c - 0x40;
|
||||
return 2;
|
||||
}
|
||||
|
||||
char* String::ConvertToUTF8(const char* s, Shared::Platform::uint32 len, Shared::Platform::uint32& newSize)
|
||||
{
|
||||
if (NULL == s || '\0' == *s)
|
||||
{
|
||||
char* ret = new char[1];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
*ret = '\0';
|
||||
return ret;
|
||||
}
|
||||
#ifndef WIN32
|
||||
Shared::Platform::byte tmp[4];
|
||||
#else
|
||||
byte tmp[4];
|
||||
#endif
|
||||
newSize = 1;
|
||||
|
||||
#ifndef WIN32
|
||||
for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++)
|
||||
#else
|
||||
for(byte *p = (byte*)s ; *p ; p++)
|
||||
#endif
|
||||
newSize += ASCIItoUTF8(*p, tmp);
|
||||
|
||||
char* ret = new char[newSize];
|
||||
//LOG_ASSERT(NULL != ret);
|
||||
assert(NULL != ret);
|
||||
|
||||
#ifndef WIN32
|
||||
Shared::Platform::byte *q = (Shared::Platform::byte*)ret;
|
||||
for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++)
|
||||
#else
|
||||
byte *q = (byte*)ret;
|
||||
for(byte *p = (byte*)s ; *p ; p++)
|
||||
|
||||
#endif
|
||||
q += ASCIItoUTF8(*p, q);
|
||||
*q = '\0'; // A bit paranoid
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
String String::ConvertToUTF8(const String& s)
|
||||
{
|
||||
if (s.empty())
|
||||
return String();
|
||||
char* ret = ConvertToUTF8(s.c_str(), s.size());
|
||||
if (ret)
|
||||
{
|
||||
String s(ret);
|
||||
delete[] ret;
|
||||
return s;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
String& String::findAndReplace(char toSearch, const char replaceWith, const enum String::CharCase option)
|
||||
{
|
||||
if (option == soIgnoreCase)
|
||||
{
|
||||
toSearch = tolower(toSearch);
|
||||
for (String::iterator i = this->begin(); i != this->end(); ++i)
|
||||
{
|
||||
if (tolower(*i) == toSearch)
|
||||
*i = replaceWith;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String::iterator i = this->begin(); i != this->end(); ++i)
|
||||
{
|
||||
if (*i == toSearch)
|
||||
*i = replaceWith;
|
||||
}
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::findAndReplace(const String& toSearch, const String& replaceWith, const enum String::CharCase option)
|
||||
{
|
||||
if (soCaseSensitive == option)
|
||||
{
|
||||
String::size_type p = 0;
|
||||
String::size_type siz = toSearch.size();
|
||||
while ((p = this->find(toSearch, p)) != String::npos)
|
||||
this->replace(p, siz, replaceWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
*this = String::ToLower(*this).findAndReplace(String::ToLower(toSearch), replaceWith, soCaseSensitive);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::format(const String& f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
this->clear();
|
||||
vappendFormat(f.c_str(), parg);
|
||||
|
||||
va_end(parg);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::format(const char* f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
this->clear();
|
||||
vappendFormat(f, parg);
|
||||
|
||||
va_end(parg);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::appendFormat(const String& f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
vappendFormat(f.c_str(), parg);
|
||||
|
||||
va_end(parg);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::appendFormat(const char* f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
vappendFormat(f, parg);
|
||||
|
||||
va_end(parg);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String& String::vappendFormat(const char* f, va_list parg)
|
||||
{
|
||||
char* b;
|
||||
#if defined TA3D_PLATFORM_WINDOWS
|
||||
// Implement vasprintf() by hand with two calls to vsnprintf()
|
||||
// Remove this when Microsoft adds support for vasprintf()
|
||||
#if defined TA3D_PLATFORM_MSVC
|
||||
int sizeneeded = _vsnprintf(NULL, 0, f, parg) + 1;
|
||||
#else
|
||||
int sizeneeded = vsnprintf(NULL, 0, f, parg) + 1;
|
||||
#endif
|
||||
if (sizeneeded < 0)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
b = new char[sizeneeded];
|
||||
if (b == NULL)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
#if defined TA3D_PLATFORM_MSVC
|
||||
if (_vsnprintf(b, sizeneeded, f, parg) < 0)
|
||||
#else
|
||||
if (vsnprintf(b, sizeneeded, f, parg) < 0)
|
||||
#endif
|
||||
{
|
||||
delete[] b;
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
if (vasprintf(&b, f, parg) < 0)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
this->append(b);
|
||||
delete[] b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String String::Format(const String& f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
String s;
|
||||
s.vappendFormat(f.c_str(), parg);
|
||||
|
||||
va_end(parg);
|
||||
return s;
|
||||
}
|
||||
|
||||
String String::Format(const char* f, ...)
|
||||
{
|
||||
va_list parg;
|
||||
va_start(parg, f);
|
||||
|
||||
String s;
|
||||
s.vappendFormat(f, parg);
|
||||
|
||||
va_end(parg);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool String::match(const String &pattern)
|
||||
{
|
||||
if (pattern.empty())
|
||||
return empty();
|
||||
|
||||
int e = 0;
|
||||
int prev = -1;
|
||||
for(unsigned int i = 0 ; i < size() ; i++)
|
||||
if (pattern[e] == '*')
|
||||
{
|
||||
if (e + 1 == pattern.size())
|
||||
return true;
|
||||
while(pattern[e+1] == '*') e++;
|
||||
if (e + 1 == pattern.size())
|
||||
return true;
|
||||
|
||||
prev = e;
|
||||
if (pattern[e+1] == (*this)[i])
|
||||
e+=2;
|
||||
}
|
||||
else if(pattern[e] == (*this)[i])
|
||||
e++;
|
||||
else if(prev >= 0)
|
||||
e = prev;
|
||||
else
|
||||
return false;
|
||||
return e == pattern.size();
|
||||
}
|
||||
|
||||
String String::substrUTF8(int pos, int len) const
|
||||
{
|
||||
if (len < 0)
|
||||
len = sizeUTF8() - len + 1 - pos;
|
||||
String res;
|
||||
int utf8_pos = 0;
|
||||
for(; pos > 0 ; pos--)
|
||||
#ifndef WIN32
|
||||
if (((Shared::Platform::byte)(*this)[utf8_pos]) >= 0xC0)
|
||||
#else
|
||||
if (((byte)(*this)[utf8_pos]) >= 0xC0)
|
||||
#endif
|
||||
{
|
||||
utf8_pos++;
|
||||
#ifndef WIN32
|
||||
while (((Shared::Platform::byte)(*this)[utf8_pos]) >= 0x80 && ((Shared::Platform::byte)(*this)[utf8_pos]) < 0xC0)
|
||||
#else
|
||||
while (((byte)(*this)[utf8_pos]) >= 0x80 && ((byte)(*this)[utf8_pos]) < 0xC0)
|
||||
#endif
|
||||
utf8_pos++;
|
||||
}
|
||||
else
|
||||
utf8_pos++;
|
||||
|
||||
for(; len > 0 ; len--)
|
||||
{
|
||||
#ifndef WIN32
|
||||
if (((Shared::Platform::byte)(*this)[utf8_pos]) >= 0x80)
|
||||
#else
|
||||
if (((byte)(*this)[utf8_pos]) >= 0x80)
|
||||
#endif
|
||||
{
|
||||
res << (char)(*this)[utf8_pos];
|
||||
utf8_pos++;
|
||||
#ifndef WIN32
|
||||
while (((Shared::Platform::byte)(*this)[utf8_pos]) >= 0x80 && ((Shared::Platform::byte)(*this)[utf8_pos]) < 0xC0)
|
||||
#else
|
||||
while (((byte)(*this)[utf8_pos]) >= 0x80 && ((byte)(*this)[utf8_pos]) < 0xC0)
|
||||
#endif
|
||||
{
|
||||
res << (char)(*this)[utf8_pos];
|
||||
utf8_pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res << ((char)(*this)[utf8_pos]);
|
||||
utf8_pos++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int String::sizeUTF8() const
|
||||
{
|
||||
int len = 0;
|
||||
for(unsigned int i = 0 ; i < this->size() ; i++)
|
||||
#ifndef WIN32
|
||||
if (((Shared::Platform::byte)(*this)[i]) >= 0xC0 || ((Shared::Platform::byte)(*this)[i]) < 0x80)
|
||||
#else
|
||||
if (((byte)(*this)[i]) >= 0xC0 || ((byte)(*this)[i]) < 0x80)
|
||||
#endif
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
WString::WString(const char* s)
|
||||
{
|
||||
if (s)
|
||||
@ -751,13 +170,11 @@ namespace Shared { namespace Util {
|
||||
pBuffer[0] = 0;
|
||||
}
|
||||
|
||||
WString::WString(const String& s)
|
||||
WString::WString(const std::string& s)
|
||||
{
|
||||
fromUtf8(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WString::fromUtf8(const char* str, size_t length)
|
||||
{
|
||||
int len = 0;
|
||||
@ -889,4 +306,7 @@ namespace Shared { namespace Util {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user