00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #if !defined(INCLUDED_STRING_STRING_H)
00028 #define INCLUDED_STRING_STRING_H
00029
00030 #include <string>
00031 #include <cstring>
00032 #include <cctype>
00033 #include <algorithm>
00034 #include <glib.h>
00035
00036 #include "memory/allocator.h"
00037 #include "generic/arrayrange.h"
00038
00041 inline bool string_empty (const std::string& string)
00042 {
00043 return string.empty();
00044 }
00045
00050 inline int string_compare (const std::string& string, const std::string& other)
00051 {
00052 return std::strcmp(string.c_str(), other.c_str());
00053 }
00054
00057 inline bool string_equal (const std::string& string, const std::string& other)
00058 {
00059 return string == other;
00060 }
00061
00064 inline bool string_equal_n (const char* string, const char* other, std::size_t n)
00065 {
00066 return std::strncmp(string, other, n) == 0;
00067 }
00068
00071 inline bool string_less (const char* string, const char* other)
00072 {
00073 return string_compare(string, other) < 0;
00074 }
00075
00080 inline int string_compare_nocase (const std::string& string, const std::string& other)
00081 {
00082 return g_ascii_strcasecmp(string.c_str(), other.c_str());
00083 }
00084
00090 inline int string_compare_nocase_n (const char* string, const char* other, std::size_t n)
00091 {
00092 return g_ascii_strncasecmp(string, other, n);
00093 }
00094
00098 inline bool string_equal_nocase (const std::string& string, const std::string& other)
00099 {
00100 return string_compare_nocase(string, other) == 0;
00101 }
00102
00106 inline bool string_equal_nocase_n (const char* string, const char* other, std::size_t n)
00107 {
00108 return string_compare_nocase_n(string, other, n) == 0;
00109 }
00110
00114 inline bool string_less_nocase (const char* string, const char* other)
00115 {
00116 return string_compare_nocase(string, other) < 0;
00117 }
00118
00121 inline std::size_t string_length (const std::string& string)
00122 {
00123 return string.length();
00124 }
00125
00129 inline char* string_copy (char* string, const char* other)
00130 {
00131 return std::strcpy(string, other);
00132 }
00133
00136 template<typename Allocator>
00137 inline char* string_new (std::size_t length, Allocator& allocator)
00138 {
00139 return allocator.allocate(length + 1);
00140 }
00141
00143 template<typename Allocator>
00144 inline void string_release (char* buffer, std::size_t length, Allocator& allocator)
00145 {
00146 allocator.deallocate(buffer, length + 1);
00147 }
00148
00151 template<typename Allocator>
00152 inline char* string_clone (const char* other, Allocator& allocator)
00153 {
00154 char* copied = string_new(string_length(other), allocator);
00155 std::strcpy(copied, other);
00156 return copied;
00157 }
00158
00161 template<typename Allocator>
00162 inline char* string_clone_range (StringRange range, Allocator& allocator)
00163 {
00164 std::size_t length = range.last - range.first;
00165 char* copied = strncpy(string_new(length, allocator), range.first, length);
00166 copied[length] = '\0';
00167 return copied;
00168 }
00169
00172 inline char* string_new (std::size_t length)
00173 {
00174 DefaultAllocator<char> allocator;
00175 return string_new(length, allocator);
00176 }
00177
00179 inline void string_release (char* string, std::size_t length)
00180 {
00181 DefaultAllocator<char> allocator;
00182 string_release(string, length, allocator);
00183 }
00184
00187 inline char* string_clone (const char* other)
00188 {
00189 DefaultAllocator<char> allocator;
00190 return string_clone(other, allocator);
00191 }
00192
00195 inline char* string_clone_range (StringRange range)
00196 {
00197 DefaultAllocator<char> allocator;
00198 return string_clone_range(range, allocator);
00199 }
00200
00201 typedef char* char_pointer;
00203 inline void string_swap (char_pointer& string, char_pointer& other)
00204 {
00205 std::swap(string, other);
00206 }
00207
00210 inline char* string_to_lowercase (char* string)
00211 {
00212 for (char* p = string; *p != '\0'; ++p) {
00213 *p = (char) std::tolower(*p);
00214 }
00215 return string;
00216 }
00217
00219 inline char* string_contains_nocase (char* haystack, char* needle)
00220 {
00221 return std::strstr(string_to_lowercase(haystack), string_to_lowercase(needle));
00222 }
00223
00225 class StringTokeniser
00226 {
00227 bool istoken (char c) const
00228 {
00229 if (strchr(m_delimiters, c) != 0) {
00230 return false;
00231 }
00232 return true;
00233 }
00234 const char* advance ()
00235 {
00236 const char* token = m_pos;
00237 bool intoken = true;
00238 while (!string_empty(m_pos)) {
00239 if (!istoken(*m_pos)) {
00240 *m_pos = '\0';
00241 intoken = false;
00242 } else if (!intoken) {
00243 return token;
00244 }
00245 ++m_pos;
00246 }
00247 return token;
00248 }
00249 std::size_t m_length;
00250 char* m_string;
00251 char* m_pos;
00252 const char* m_delimiters;
00253 public:
00254 StringTokeniser (const char* string, const char* delimiters = " \n\r\t\v") :
00255 m_length(string_length(string)), m_string(string_copy(string_new(m_length), string)), m_pos(m_string),
00256 m_delimiters(delimiters)
00257 {
00258 while (!string_empty(m_pos) && !istoken(*m_pos)) {
00259 ++m_pos;
00260 }
00261 }
00262 ~StringTokeniser ()
00263 {
00264 string_release(m_string, m_length);
00265 }
00267 const char* getToken ()
00268 {
00269 return advance();
00270 }
00271 };
00272
00273 struct RawStringEqual
00274 {
00275 bool operator() (const std::string& x, const std::string& y) const
00276 {
00277 return x.compare(y) == 0;
00278 }
00279 };
00280
00281 struct RawStringLess
00282 {
00283 bool operator() (const std::string& x, const std::string& y) const
00284 {
00285 return x.compare(y) < 0;
00286 }
00287 };
00288
00289 struct RawStringLessNoCase
00290 {
00291 bool operator() (const std::string& x, const std::string& y) const
00292 {
00293 return string_less_nocase(x.c_str(), y.c_str());
00294 }
00295 };
00296
00297 #include <sstream>
00298 #include <string>
00299 #include <algorithm>
00300 #include <cctype>
00301
00302 namespace string
00303 {
00304 template<class T>
00305 inline std::string toString (const T& t)
00306 {
00307 std::stringstream ss;
00308 ss << t;
00309 return ss.str();
00310 }
00311
00312 inline bool contains (const std::string& source, const std::string& contains)
00313 {
00314 return source.rfind(contains) != std::string::npos;
00315 }
00316
00317 inline int toInt (const std::string& str)
00318 {
00319 return atoi(str.c_str());
00320 }
00321
00322 inline float toFloat (const std::string& str)
00323 {
00324 return atof(str.c_str());
00325 }
00326
00327 inline std::string toLower (const std::string& str)
00328 {
00329 std::string convert = str;
00330 std::transform(convert.begin(), convert.end(), convert.begin(), (int(*) (int)) std::tolower);
00331 return convert;
00332 }
00333
00334 inline std::string toUpper (const std::string& str)
00335 {
00336 std::string convert = str;
00337 std::transform(convert.begin(), convert.end(), convert.begin(), (int(*) (int)) std::toupper);
00338 return convert;
00339 }
00340
00348 inline std::string replaceAll (const std::string& str, const std::string& searchStr, const std::string& replaceStr)
00349 {
00350 if (str.empty())
00351 return str;
00352 std::string sNew = str;
00353 std::string::size_type loc;
00354 const std::string::size_type replaceLength = replaceStr.length();
00355 const std::string::size_type searchLength = searchStr.length();
00356 std::string::size_type lastPosition = 0;
00357 while (std::string::npos != (loc = sNew.find(searchStr, lastPosition))) {
00358 sNew.replace(loc, searchLength, replaceStr);
00359 lastPosition = loc + replaceLength;
00360 }
00361 return sNew;
00362 }
00363 }
00364
00365 #endif