2003-09-21 23:24:53 +02:00
|
|
|
/*
|
|
|
|
CStr.h
|
|
|
|
by Caecus
|
|
|
|
Caecus@0ad.wildfiregames.com
|
|
|
|
|
|
|
|
Overview:
|
|
|
|
|
|
|
|
Contains CStr class which is a versatile class for making string use easy.
|
|
|
|
Basic functionality implemented via STL string, so performance is limited
|
|
|
|
based on the STL implementation we use.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
CStr MyString = _T("Hello, World.");
|
2004-06-01 18:51:37 +02:00
|
|
|
int MyNum = 126;
|
2003-09-21 23:24:53 +02:00
|
|
|
MyString += _T(" I'm the number ") += CStr(MyNumber);
|
|
|
|
|
|
|
|
// Prints "Hello, World. I'm the number 126"
|
2003-11-10 03:02:28 +01:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
_tcout << (LPCTSTR)MyString << endl;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
|
|
|
MyString = _("2341");
|
|
|
|
MyNum = MyString.ToInt();
|
|
|
|
|
|
|
|
// Prints "2341"
|
|
|
|
_tcout << MyNum << endl;
|
|
|
|
|
|
|
|
More Info:
|
|
|
|
http://wildfiregames.com/0ad/codepit/TDD/CStr.html
|
|
|
|
|
2005-06-01 22:12:45 +02:00
|
|
|
|
|
|
|
[[ This documentation is out of date; CStr is always 8 bits, and CStrW is always
|
|
|
|
sizeof(wchar_t) (16 or 32). Don't use _T; CStrW constants are just L"string". ]]
|
|
|
|
|
2003-09-21 23:24:53 +02:00
|
|
|
*/
|
|
|
|
|
2004-06-18 15:33:06 +02:00
|
|
|
// history:
|
|
|
|
// 19 May 04, Mark Thompson (mot20@cam.ac.uk / mark@wildfiregames.com)
|
|
|
|
// 2004-06-18 janwas: replaced conversion buffer with stringstream
|
2004-10-31 21:29:09 +01:00
|
|
|
// 2004-10-31 Philip: Changed to inherit from std::[w]string
|
2004-05-22 01:46:16 +02:00
|
|
|
|
2004-06-11 04:55:09 +02:00
|
|
|
#ifndef CSTR_H_FIRST
|
|
|
|
#define CSTR_H_FIRST
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
enum PS_TRIM_MODE { PS_TRIM_LEFT, PS_TRIM_RIGHT, PS_TRIM_BOTH };
|
2004-06-11 04:55:09 +02:00
|
|
|
|
|
|
|
#ifndef IN_UNIDOUBLER
|
2004-10-31 21:29:09 +01:00
|
|
|
#define UNIDOUBLER_HEADER "CStr.h"
|
|
|
|
#include "UniDoubler.h"
|
2004-06-11 04:55:09 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2005-06-01 22:12:45 +02:00
|
|
|
// Include this section when in unidoubler mode, and when this unicode/ascii
|
|
|
|
// version has not already been included.
|
|
|
|
#if defined(IN_UNIDOUBLER) && ( (defined(_UNICODE) && !defined(CSTR_H_U)) || (!defined(_UNICODE) && !defined(CSTR_H_A)) )
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2005-06-01 22:12:45 +02:00
|
|
|
#ifdef _UNICODE
|
|
|
|
#define CSTR_H_U
|
|
|
|
#else
|
|
|
|
#define CSTR_H_A
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string>
|
2004-07-10 22:56:15 +02:00
|
|
|
#include "ps/utf16string.h"
|
2003-11-10 03:02:28 +01:00
|
|
|
|
2004-09-06 13:15:43 +02:00
|
|
|
class CStr8;
|
|
|
|
class CStrW;
|
|
|
|
|
2003-09-21 23:24:53 +02:00
|
|
|
// CStr class, the mother of all strings
|
2005-08-09 23:26:40 +02:00
|
|
|
class CStr: public std::tstring
|
2003-09-21 23:24:53 +02:00
|
|
|
{
|
2005-06-01 22:12:45 +02:00
|
|
|
// The two variations must be friends with each other
|
2004-08-16 17:19:17 +02:00
|
|
|
#ifdef _UNICODE
|
|
|
|
friend class CStr8;
|
2004-09-06 13:15:43 +02:00
|
|
|
#else
|
|
|
|
friend class CStrW;
|
2004-08-16 17:19:17 +02:00
|
|
|
#endif
|
2005-06-01 22:12:45 +02:00
|
|
|
|
2003-09-21 23:24:53 +02:00
|
|
|
public:
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
2004-08-16 17:19:17 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr() {}
|
|
|
|
CStr(const CStr& String) : std::tstring(String) {}
|
2005-06-01 22:12:45 +02:00
|
|
|
CStr(const tchar* String) : std::tstring(String) {}
|
|
|
|
CStr(const tchar* String, size_t Length)
|
2004-10-31 21:29:09 +01:00
|
|
|
: std::tstring(String, Length) {}
|
2005-06-01 22:12:45 +02:00
|
|
|
CStr(const tchar Char) : std::tstring(1, Char) {} // std::string's constructor is (repeats, chr)
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr(std::tstring String) : std::tstring(String) {}
|
2005-12-17 03:33:57 +01:00
|
|
|
|
|
|
|
// Named constructor, to avoid overload overload.
|
2006-07-20 16:37:58 +02:00
|
|
|
static CStr Repeat(const CStr& String, size_t Reps);
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2006-02-03 21:36:15 +01:00
|
|
|
// CStr(8|W) construction from utf16strings.
|
|
|
|
// allowed on MSVC as of 2006-02-03 because utf16string is
|
|
|
|
// now distinct from CStrW.
|
|
|
|
CStr(utf16string String) : std::tstring(String.begin(), String.end()) {}
|
2004-10-31 21:29:09 +01:00
|
|
|
|
2005-01-12 15:31:47 +01:00
|
|
|
// Transparent CStrW/8 conversion. Non-ASCII characters are not
|
|
|
|
// handled correctly.
|
2004-10-31 21:29:09 +01:00
|
|
|
#ifndef _UNICODE
|
2006-07-20 16:37:58 +02:00
|
|
|
CStr8(const CStrW& wideStr);
|
2004-10-31 21:29:09 +01:00
|
|
|
#else
|
|
|
|
CStrW(const CStr8 &asciiStr);
|
|
|
|
#endif
|
|
|
|
|
2006-11-07 22:03:13 +01:00
|
|
|
// Conversion to/from UTF-8, encoded in a CStr8.
|
|
|
|
// Common non-ASCII characters are handled correctly.
|
|
|
|
// Characters outside the BMP (above 0xFFFF) are *not* handled correctly.
|
|
|
|
// FromUTF8 may fail, if converting from invalid UTF-8 data - the empty
|
|
|
|
// string will be returned.
|
2005-05-10 20:15:03 +02:00
|
|
|
#ifdef _UNICODE
|
|
|
|
CStr8 ToUTF8() const;
|
|
|
|
#else
|
|
|
|
CStrW FromUTF8() const;
|
|
|
|
#endif
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr(int Number); // Creates CStr from a int
|
|
|
|
CStr(unsigned int Number); // Creates CStr from a uint
|
|
|
|
CStr(long Number); // Creates CStr from a long
|
2004-06-01 18:51:37 +02:00
|
|
|
CStr(unsigned long Number); // Creates CStr from a ulong
|
2004-10-31 21:29:09 +01:00
|
|
|
CStr(float Number); // Creates CStr from a float
|
|
|
|
CStr(double Number); // Creates CStr from a double
|
|
|
|
|
|
|
|
~CStr() {}; // Destructor
|
2003-09-21 23:24:53 +02:00
|
|
|
|
|
|
|
// Conversions
|
2004-10-31 21:29:09 +01:00
|
|
|
int ToInt() const;
|
2004-06-01 18:51:37 +02:00
|
|
|
unsigned int ToUInt() const;
|
2004-10-31 21:29:09 +01:00
|
|
|
long ToLong() const;
|
2004-06-01 18:51:37 +02:00
|
|
|
unsigned long ToULong() const;
|
2004-10-31 21:29:09 +01:00
|
|
|
float ToFloat() const;
|
|
|
|
double ToDouble() const;
|
|
|
|
|
2005-06-01 22:12:45 +02:00
|
|
|
// Returns the length of the string in characters
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t Length() const { return length(); }
|
2003-09-21 23:24:53 +02:00
|
|
|
|
|
|
|
// Retrieves the substring within the string
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr GetSubstring(size_t start, size_t len) const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Search the string for another string. Returns the offset of the first
|
|
|
|
// match, or -1 if no matches are found.
|
2004-06-18 15:22:26 +02:00
|
|
|
long Find(const CStr& Str) const;
|
2005-06-01 22:12:45 +02:00
|
|
|
long Find(const tchar &chr) const;
|
|
|
|
long Find(const int &start, const tchar &chr) const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-12-09 17:54:02 +01:00
|
|
|
// Case-insensitive versions of Find
|
|
|
|
long FindInsensitive(const CStr& Str) const;
|
2005-06-01 22:12:45 +02:00
|
|
|
long FindInsensitive(const tchar &chr) const;
|
|
|
|
long FindInsensitive(const int &start, const tchar &chr) const;
|
2004-12-09 17:54:02 +01:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// You can also do a "ReverseFind" - i.e. search starting from the end
|
2004-06-18 15:22:26 +02:00
|
|
|
long ReverseFind(const CStr& Str) const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
|
|
|
// Lowercase and uppercase
|
2004-05-29 05:53:38 +02:00
|
|
|
CStr LowerCase() const;
|
|
|
|
CStr UpperCase() const;
|
|
|
|
CStr LCase() const;
|
|
|
|
CStr UCase() const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Retrieve the substring of the first n characters
|
2005-01-12 15:31:47 +01:00
|
|
|
CStr Left(size_t len) const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Retrieve the substring of the last n characters
|
2005-01-12 15:31:47 +01:00
|
|
|
CStr Right(size_t len) const;
|
2005-03-18 23:30:23 +01:00
|
|
|
|
|
|
|
// Retrieve the substring following the last occurrence of Str
|
|
|
|
// (or the whole string if it doesn't contain Str)
|
|
|
|
CStr AfterLast(const CStr& Str) const;
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2005-03-18 23:30:23 +01:00
|
|
|
// Retrieve the substring preceding the last occurrence of Str
|
|
|
|
// (or the whole string if it doesn't contain Str)
|
|
|
|
CStr BeforeLast(const CStr& Str) const;
|
|
|
|
|
2005-03-30 07:43:22 +02:00
|
|
|
// Retrieve the substring following the first occurrence of Str
|
|
|
|
// (or the whole string if it doesn't contain Str)
|
|
|
|
CStr AfterFirst(const CStr& Str) const;
|
|
|
|
|
|
|
|
// Retrieve the substring preceding the first occurrence of Str
|
|
|
|
// (or the whole string if it doesn't contain Str)
|
|
|
|
CStr BeforeFirst(const CStr& Str) const;
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Remove all occurrences of some character or substring
|
2004-06-18 15:22:26 +02:00
|
|
|
void Remove(const CStr& Str);
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Replace all occurrences of some substring by another
|
2004-06-18 15:22:26 +02:00
|
|
|
void Replace(const CStr& StrToReplace, const CStr& ReplaceWith);
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-12-28 14:13:27 +01:00
|
|
|
// Convert strings like \\\n into <backslash><newline>
|
|
|
|
CStr UnescapeBackslashes();
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Returns a trimmed string, removes whitespace from the left/right/both
|
|
|
|
CStr Trim(PS_TRIM_MODE Mode) const;
|
|
|
|
|
2005-12-17 03:33:57 +01:00
|
|
|
// Returns a padded string, adding spaces to the left/right/both
|
|
|
|
CStr Pad(PS_TRIM_MODE Mode, size_t Length) const;
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Overloaded operations
|
2003-09-21 23:24:53 +02:00
|
|
|
|
2004-06-18 15:22:26 +02:00
|
|
|
CStr& operator=(int Number);
|
|
|
|
CStr& operator=(long Number);
|
|
|
|
CStr& operator=(unsigned int Number);
|
|
|
|
CStr& operator=(unsigned long Number);
|
|
|
|
CStr& operator=(float Number);
|
|
|
|
CStr& operator=(double Number);
|
|
|
|
|
|
|
|
CStr operator+(const CStr& Str);
|
2005-06-01 22:12:45 +02:00
|
|
|
CStr operator+(const tchar* Str);
|
2004-10-31 21:29:09 +01:00
|
|
|
#ifndef _UNICODE
|
|
|
|
CStr8 operator+(const CStrW& Str);
|
|
|
|
#else
|
|
|
|
CStrW operator+(const CStr8& Str);
|
|
|
|
#endif
|
|
|
|
|
2005-06-01 22:12:45 +02:00
|
|
|
operator const tchar*() const;
|
2004-10-31 21:29:09 +01:00
|
|
|
|
|
|
|
// Do some range checking in debug builds
|
2005-08-09 17:55:44 +02:00
|
|
|
tchar& operator[](size_t n) { debug_assert(n < length()); return this->std::tstring::operator[](n); }
|
|
|
|
tchar& operator[](int n) { debug_assert((size_t)n < length()); return this->std::tstring::operator[](n); }
|
2004-05-22 01:46:16 +02:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Conversion to utf16string
|
2004-08-05 14:15:53 +02:00
|
|
|
inline utf16string utf16() const
|
2004-10-31 21:29:09 +01:00
|
|
|
{ return utf16string(begin(), end()); }
|
2005-01-12 15:31:47 +01:00
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Calculates a hash of the string's contents
|
2004-05-22 01:46:16 +02:00
|
|
|
size_t GetHashCode() const;
|
2004-03-04 21:27:37 +01:00
|
|
|
|
2003-11-30 17:39:22 +01:00
|
|
|
// Serialization functions
|
2005-08-09 23:26:40 +02:00
|
|
|
// (These are not virtual or inherited from ISerializable, to avoid
|
|
|
|
// adding a vtable and making the strings larger than std::string)
|
|
|
|
uint GetSerializedLength() const;
|
|
|
|
u8 *Serialize(u8 *buffer) const;
|
|
|
|
const u8 *Deserialize(const u8 *buffer, const u8 *bufferend);
|
2003-09-21 23:24:53 +02:00
|
|
|
};
|
|
|
|
|
2004-10-31 21:29:09 +01:00
|
|
|
// Hash function (for STL_HASH_MAP, etc)
|
2004-05-22 01:46:16 +02:00
|
|
|
class CStr_hash_compare
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static const size_t bucket_size = 1;
|
|
|
|
static const size_t min_buckets = 16;
|
2004-10-31 21:29:09 +01:00
|
|
|
size_t operator() (const CStr& Key) const
|
2004-05-22 01:46:16 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return Key.GetHashCode();
|
2004-05-22 01:46:16 +02:00
|
|
|
}
|
2004-10-31 21:29:09 +01:00
|
|
|
bool operator() (const CStr& _Key1, const CStr& _Key2) const
|
2004-05-22 01:46:16 +02:00
|
|
|
{
|
2004-10-31 21:29:09 +01:00
|
|
|
return (_Key1 < _Key2);
|
2004-05-22 01:46:16 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-07-10 22:56:15 +02:00
|
|
|
#endif
|