/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NSTRING__ #define __NSTRING__ #include #include "container/narray.h" namespace GS { template class List; template class Array; /*! @short String class. Strings are internally stored as UTF-8. @author Emmanuel Julien (ejulien@gsworks.fr) */ class String { Array _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 toUcs2() const; /// Return string as utf-32. Array 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 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 &arg); typedef String RewriteFunc(const char *pattern, List &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 StringList; } // GS #endif // __NSTRING__