311 lines
8.8 KiB
C++
311 lines
8.8 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __NSTRING__
|
|
#define __NSTRING__
|
|
|
|
|
|
#include <cstring>
|
|
#include "container/narray.h"
|
|
|
|
namespace GS {
|
|
template <class T> class List;
|
|
template <class T> class Array;
|
|
|
|
/*!
|
|
@short String class.
|
|
Strings are internally stored as UTF-8.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
class String
|
|
{
|
|
Array <char> _p;
|
|
|
|
mutable uint hash;
|
|
int len;
|
|
|
|
void Touch();
|
|
|
|
public:
|
|
|
|
enum CaseSensitivity
|
|
{
|
|
CaseSensitive = 0,
|
|
CaseInsensitive
|
|
};
|
|
|
|
enum EOLConvention
|
|
{
|
|
EOLUnix = 0,
|
|
EOLWindows
|
|
};
|
|
|
|
/*!
|
|
@short Compare string object with a C string
|
|
Optionally accept a hash value for the input string.
|
|
@return True if strings match.
|
|
*/
|
|
bool equals(const char *s, const uint hash = 0) const;
|
|
|
|
bool operator == (const String &) const;
|
|
bool operator != (const String &) const;
|
|
bool operator == (const char *) const;
|
|
bool operator != (const char *) const;
|
|
|
|
/// Format a string.
|
|
static String Format(const char *format, ...);
|
|
|
|
String operator + (const char *) const;
|
|
String operator + (const String &) const;
|
|
|
|
void operator += (const char *);
|
|
void operator += (const String &);
|
|
void operator += (float);
|
|
void operator += (double);
|
|
void operator += (int);
|
|
void operator += (uint);
|
|
void operator += (bool);
|
|
|
|
String &operator = (const String &);
|
|
String &operator = (const char *);
|
|
|
|
void Set(const char *s, const char *e = 0);
|
|
|
|
String &operator << (const String &);
|
|
String &operator << (const char *);
|
|
String &operator << (float);
|
|
String &operator << (double);
|
|
String &operator << (int);
|
|
String &operator << (uint);
|
|
String &operator << (bool);
|
|
|
|
/// String hash value.
|
|
uint Hash() const;
|
|
/// String length.
|
|
uint Len() const;
|
|
/// String size in bytes.
|
|
size_t Size() const;
|
|
|
|
/// Is empty.
|
|
inline bool IsEmpty() const { return (!_p || !len) ? true : false; }
|
|
|
|
/// Normalize the string end of line.
|
|
void NormalizeEOL(EOLConvention = EOLUnix);
|
|
/// Return a normalized version of this string.
|
|
String NormalizedEOL(EOLConvention = EOLUnix) const;
|
|
|
|
/*!
|
|
@name File system tool set.
|
|
@{
|
|
*/
|
|
/// Is absolute path.
|
|
bool IsAbsolutePath() const;
|
|
|
|
String BeautifyFileName(bool allow_spaces = true) const;
|
|
|
|
String CleanFilePath() const;
|
|
|
|
String CutFilePath() const;
|
|
String CutFileName() const;
|
|
String CutFileExtension() const;
|
|
|
|
String GetFilePath() const;
|
|
String GetFileName() const;
|
|
String GetFileNameAndExtension() const;
|
|
String GetFileExtension() const;
|
|
|
|
/// Return this filename with another file extension.
|
|
String GetSwappedExtension(const char *) const;
|
|
|
|
void FileCutPath();
|
|
void FileSwapExtension(const char *);
|
|
void FileCutPathAndExtension();
|
|
void FileCutExtension();
|
|
void FileCutName();
|
|
|
|
/// Get extension.
|
|
static String FileGetExtension(const char *path);
|
|
/// Convert backslash to slash, merge redundant slash.
|
|
bool FileCleanName();
|
|
/// @}
|
|
|
|
/// Return as utf-8 ASCII C string.
|
|
inline operator const char *() const { return _p; }
|
|
/// Return as utf-8 ASCII C string.
|
|
inline const char *c_str() const { return _p; }
|
|
inline char *str() const { return _p; }
|
|
/// Return a pointer to the end of the string.
|
|
inline const char *eos() const { return _p + Len(); }
|
|
/*!
|
|
@name Unicode tool set.
|
|
@{
|
|
*/
|
|
/// Convert an utf-8 character to utf-32, returns the number of consumed bytes.
|
|
static size_t Utf8toUtf32(const uchar *utf8, uint *utf32);
|
|
/// Get utf-8 character size in byte.
|
|
static size_t GetUtf8CharSize(const uchar *utf8);
|
|
|
|
/// Create a string from a UCS-2 buffer.
|
|
static String FromUcs2(const ushort *);
|
|
|
|
/// Return as utf-8
|
|
inline const char *toUtf8() const { return _p; }
|
|
/// Return string as UCS-2 (utf-16 compatible up to code point 0xffff).
|
|
Array <ushort> toUcs2() const;
|
|
/// Return string as utf-32.
|
|
Array <uint> toUtf32() const;
|
|
/// @}
|
|
|
|
/// Remove all occurrences of a given character from the string.
|
|
String TrimChar(char);
|
|
|
|
/// ASCII to float.
|
|
inline float Float(bool support_comma = true) const { return atof(_p, _p + Len(), support_comma); }
|
|
/// ASCII to integer.
|
|
inline int Integer() const { return atoi(_p); }
|
|
/// ASCII header less, 0x or h prefixed hexadecimal to integer.
|
|
inline int Hex() const { return atoh(_p); }
|
|
|
|
/// Split string against a separator string.
|
|
template <class C> uint Split(const char *separator, C &container, const char skip = 0) const
|
|
{
|
|
const char *s = c_str();
|
|
if (!s)
|
|
return 0;
|
|
size_t ls = strlen(separator);
|
|
|
|
for (const char *n = s; s[0]; s = n)
|
|
{
|
|
// Check the skip char.
|
|
if (skip && (n[0] == skip))
|
|
for (++n; n[0] && (n[0] != skip); ++n)
|
|
;
|
|
|
|
// Seek the next separator occurrence.
|
|
while (n[0] && (strncmp(n, separator, ls) != 0))
|
|
++n;
|
|
|
|
// Append sub-string.
|
|
if (skip)
|
|
container.Add(String(s, n).TrimChar(skip));
|
|
else
|
|
container.Add(String(s, n));
|
|
|
|
if (!n[0])
|
|
break;
|
|
|
|
n += ls;
|
|
}
|
|
return container.GetCount();
|
|
}
|
|
/// Get a slice of the string starting at s ending at e.
|
|
String Slice(uint s, uint e) const;
|
|
|
|
bool Compare(const char *, CaseSensitivity = CaseSensitive) const;
|
|
|
|
/// Test if the string starts with another string.
|
|
bool StartsWith(const char *, CaseSensitivity = CaseSensitive) const;
|
|
/// Test if the string ends with another string.
|
|
bool EndsWith(const char *, CaseSensitivity = CaseSensitive) const;
|
|
/// Test if the string contains another string.
|
|
bool Contains(const char *, CaseSensitivity = CaseSensitive) const;
|
|
|
|
String Upper() const;
|
|
String Lower() const;
|
|
|
|
/// Get the n leftmost characters from the string.
|
|
String Left(uint n) const;
|
|
/// Get the n rightmost characters from the string.
|
|
String Right(uint n) const;
|
|
/// Get 'n' characters starting at p from the string.
|
|
String Mid(uint p, int n = -1) const;
|
|
|
|
/// Return the index of a specific character in string, starting at p.
|
|
size_t IndexOf(char c, uint p = 0) const;
|
|
|
|
/// Return the address of a substring in string, starting at p.
|
|
char *FindString(const char *c, uint p = 0, CaseSensitivity = CaseSensitive) const;
|
|
|
|
bool Replace(const char *what, const char *by, CaseSensitivity cs = CaseSensitive);
|
|
bool ReplaceAll(const char *what, const char *by, bool match_whole_word = false);
|
|
bool ReplaceAll(const char **what, const char **by, bool match_whole_word = false);
|
|
|
|
static const char *LocatePattern(const char *s, const char *format, const char **e = 0);
|
|
bool Extract(const char *format, List <String> &arg);
|
|
|
|
typedef String RewriteFunc(const char *pattern, List <String> &arg);
|
|
static String RewritePatternAll(const char *p, const char *pattern, RewriteFunc &rewrite_func);
|
|
|
|
/*!
|
|
@short C string library.
|
|
@{
|
|
*/
|
|
/// Compare two strings, returns -1 if b < a, 0 if a == b, 1 if b > a.
|
|
static int Compare(const String &a, const String &b);
|
|
|
|
/*!
|
|
@short Returns the address where a given character can be found.
|
|
|
|
Returns the address where a given character can be found inside the
|
|
memory block starting at 'from' and ending at 'to'.
|
|
*/
|
|
static char *strfindchar(const char *from, const char c, const char *to = 0);
|
|
|
|
/*!
|
|
@short Compare the shortest C string with the other C string.
|
|
Returns false if matching. (eg: 'fore' and 'foremost' do match).
|
|
*/
|
|
static bool strccmp(const char *, const char *);
|
|
/// Compute string hash value.
|
|
static uint strhash(const char *);
|
|
/// Compute string length.
|
|
static size_t strlen(const char *);
|
|
|
|
/// Remove path.
|
|
static void rmpath(char *);
|
|
/// Remove extension.
|
|
static void rmext(char *);
|
|
/// Remove path and extension.
|
|
static void rmpathext(char *);
|
|
/// Remove filename.
|
|
static void rmname(char *);
|
|
|
|
/// Integer to ASCII.
|
|
static char *itoa(int);
|
|
|
|
/// ASCII to float.
|
|
static float atof(const char *s, const char *e = 0, bool support_comma = true);
|
|
/// ASCII to integer.
|
|
static int atoi(const char *s);
|
|
/// ASCII header-less, 0x or h prefixed hexadecimal to integer.
|
|
static int atoh(const char *s);
|
|
|
|
|
|
/// @}
|
|
|
|
//-------------------------------------------------------------------
|
|
/*!
|
|
@short Reserve space on the string for a number of characters.
|
|
@note An extra byte will be allocated to store the string terminator.
|
|
*/
|
|
bool Allocate(uint size);
|
|
void Clear();
|
|
|
|
String(const char *s) : _p(Alloc::StringBuffer) { Clear(); *this = s; }
|
|
String(const String &b) : _p(Alloc::StringBuffer) { Clear(); *this = b.c_str(); }
|
|
String(const char *s, const char *e) : _p(Alloc::StringBuffer) { Clear(); Set(s, e); }
|
|
String(const char *s, size_t l) : _p(Alloc::StringBuffer) { Clear(); Set(s, s + l); }
|
|
String() : _p(Alloc::StringBuffer) { Clear(); }
|
|
~String() { Clear(); }
|
|
};
|
|
|
|
typedef List <String> StringList;
|
|
|
|
} // GS
|
|
|
|
|
|
#endif // __NSTRING__
|