32 #include <deque> |
32 #include <deque> |
33 #include <string> |
33 #include <string> |
34 #include <stdarg.h> |
34 #include <stdarg.h> |
35 #include "basics.h" |
35 #include "basics.h" |
36 #include "list.h" |
36 #include "list.h" |
|
37 |
37 BEGIN_ZFC_NAMESPACE |
38 BEGIN_ZFC_NAMESPACE |
38 |
39 |
39 class String; |
40 |
40 class StringList; |
|
41 |
|
42 // ------------------------------------------------------------------------------------------------- |
|
43 // |
|
44 class String |
41 class String |
45 { |
42 { |
46 public: |
43 public: |
47 String() {} |
|
48 |
|
49 String (char a) |
|
50 { |
|
51 char buffer[2] = { a, '0' }; |
|
52 m_string = buffer; |
|
53 } |
|
54 |
|
55 String (const char* data) : |
|
56 m_string (data) {} |
|
57 |
|
58 String (const std::string& data) : |
|
59 m_string (data) {} |
|
60 |
|
61 String (const Vector<char>& data) : |
|
62 m_string (data.data(), data.size()) {} |
|
63 |
|
64 typedef std::string::iterator Iterator; |
44 typedef std::string::iterator Iterator; |
65 typedef std::string::const_iterator ConstIterator; |
45 typedef std::string::const_iterator ConstIterator; |
66 |
46 |
67 ConstIterator begin() const { return m_string.cbegin(); } |
47 String(); |
68 int compare (const String &other) const; |
48 String(char a); |
69 int count (char needle) const; |
49 String(const char* data); |
70 const char* chars() const { return m_string.c_str(); } |
50 String(const std::string& data); |
71 ConstIterator end() const { return m_string.end(); } |
51 String(const Vector<char>& data); |
72 int find (const char* c, int a = 0) const; |
52 |
73 int find (char ch, int a = 0) const; |
53 void append(const char* text); |
74 bool is_empty() const { return m_string[0] == '\0'; } |
54 void append(char character); |
75 bool is_numeric() const; |
55 void append(const String& text); |
76 int find_last (const char*c, int a) const; |
56 ConstIterator begin() const; |
77 int length() const { return m_string.length(); } |
57 Iterator begin(); |
78 bool mask_against (const String &pattern) const; |
58 int compare(const String &other) const; |
79 String md5() const; |
59 int count(char character) const; |
80 String mid (int a, int b) const; |
60 const char* chars() const; |
81 String right (int length) const; |
61 void clear(); |
82 StringList split (const String &del) const; |
62 ConstIterator end() const; |
83 StringList split (char del) const; |
63 Iterator end(); |
84 const std::string& std_string() const { return m_string; } |
64 bool endsWith(const String &other) const; |
85 String strip (char unwanted) const; |
65 int find(const char* subString, int startingPosition = 0) const; |
86 String strip (const List<char> &unwanted) const; |
66 int find(char character, int startingPosition = 0) const; |
87 double to_double (bool* ok = nullptr) const; |
67 int indexDifference(int a, int b); |
88 float to_float (bool* ok = nullptr) const; |
68 void insert(int position, char character); |
89 long to_int (bool* ok = nullptr, int base = 10) const; |
69 void insert(int position, const char* string); |
90 String to_lowercase() const; |
70 bool isEmpty() const; |
91 String to_uppercase() const; |
71 bool isNumeric() const; |
92 int word_position (int n) const; |
72 void modifyIndex(int &a) const; |
93 |
73 int findLast(const char* subString, int startingPosition = -1) const; |
94 void append (const char* data) { m_string.append (data); } |
74 int length() const; |
95 void append (char data) { m_string.push_back (data); } |
75 bool maskAgainst(const String &pattern) const; |
96 void append (const String& data) { m_string.append (data.chars()); } |
76 String md5() const; |
97 Iterator begin() { return m_string.begin(); } |
77 String mid(int rangeBegin, int rangeEnd) const; |
98 void clear() { m_string.clear(); } |
78 void normalize(int(*filter)(int) = &isspace); |
99 Iterator end() { return m_string.end(); } |
79 String normalized(int(*filter)(int) = &isspace) const; |
100 bool ends_with (const String &other); |
80 void prepend(String text); |
101 int index_difference (int a, int b) { modify_index (a); modify_index (b); return b - a; } |
81 void remove(int position, int length); |
102 void insert (int pos, char c) { m_string.insert (m_string.begin() + pos, c); } |
82 void removeAt(int position); |
103 void insert (int pos, const char*c) { m_string.insert (pos, c); } |
83 void removeFromEnd(int length); |
104 void modify_index (int &a) { if (a < 0) { a = length() - a; } } |
84 void removeFromStart(int length); |
105 void normalize (int (*filter)(int) = &isspace); |
85 void replace(const char* text, const char* replacement); |
106 String normalized (int (*filter)(int) = &isspace) const; |
86 void replace(int position, int amount, const String &text); |
107 void prepend (String a) { m_string = (a + m_string).std_string(); } |
87 String right(int length) const; |
108 void remove (int pos, int len) { m_string.replace (pos, len, ""); } |
88 void shrinkToFit(); |
109 void remove_at (int pos) { m_string.erase (m_string.begin() + pos); } |
89 class StringList split(const String &delimeter) const; |
110 void remove_from_end (int len) { remove (length() - len, len); } |
90 class StringList split(char delimeter) const; |
111 void remove_from_start (int len) { remove (0, len); } |
91 void __cdecl sprintf(const char* fmtstr, ...); |
112 void replace (const char* a, const char* b); |
92 bool startsWith(const String &other) const; |
113 void replace (int pos, int n, const String &a) { m_string.replace (pos, n, a.chars()); } |
93 const std::string& stdString() const; |
114 void shrink_to_fit() { m_string.shrink_to_fit(); } |
94 void strip(char unwanted); |
115 void __cdecl sprintf (const char* fmtstr, ...); |
95 void strip(const List<char> &unwanted); |
116 void vsprintf (const char* fmtstr, va_list args); |
96 double toDouble(bool* ok = nullptr) const; |
117 bool starts_with (const String &other) const; |
97 float toFloat(bool* ok = nullptr) const; |
118 void trim (int n); |
98 long toInt(bool* ok = nullptr, int base = 10) const; |
119 |
99 String toLowerCase() const; |
120 static String from_number (short int a); |
100 String toUpperCase() const; |
121 static String from_number (int a); |
101 void vsprintf(const char* fmtstr, va_list args); |
122 static String from_number (long int a); |
102 |
123 static String from_number (unsigned short int a); |
103 static String fromNumber(short int a); |
124 static String from_number (unsigned int a); |
104 static String fromNumber(int a); |
125 static String from_number (unsigned long int a); |
105 static String fromNumber(long int a); |
126 static String from_number (double a); |
106 static String fromNumber(unsigned short int a); |
127 |
107 static String fromNumber(unsigned int a); |
128 String operator+ (const String& data) const; |
108 static String fromNumber(unsigned long int a); |
129 String operator+ (const char* data) const; |
109 static String fromNumber(double a); |
130 String operator+ (int num) const { return *this + String::from_number (num); } |
110 |
131 String& operator+= (const String& data) { append (data); return *this; } |
111 String operator+(const String& data) const; |
132 String& operator+= (const char* data) { append (data); return *this; } |
112 String operator+(const char* data) const; |
133 String& operator+= (int num) { return operator+= (String::from_number (num)); } |
113 String operator+(int num) const; |
134 String& operator+= (char data) { append (data); return *this; } |
114 String& operator+=(const String& data); |
135 char& operator[] (int i) { return m_string[i]; } |
115 String& operator+=(const char* data); |
136 char operator[] (int i) const { return m_string[i]; } |
116 String& operator+=(int num); |
137 bool operator== (const String& other) const { return std_string() == other.std_string(); } |
117 String& operator+=(char data); |
138 bool operator== (const char* other) const { return m_string == other; } |
118 char& operator[](int i); |
139 bool operator!= (const String& other) const { return std_string() != other.std_string(); } |
119 char operator[](int i) const; |
140 bool operator!= (const char* other) const { return m_string != other; } |
120 bool operator==(const String& other) const; |
141 bool operator> (const String& other) const { return std_string() > other.std_string(); } |
121 bool operator==(const char* other) const; |
142 bool operator< (const String& other) const { return std_string() < other.std_string(); } |
122 bool operator!=(const String& other) const; |
143 bool operator>= (const String& other) const { return std_string() >= other.std_string(); } |
123 bool operator!=(const char* other) const; |
144 bool operator<= (const String& other) const { return std_string() <= other.std_string(); } |
124 bool operator>(const String& other) const; |
145 operator const char*() const { return chars(); } |
125 bool operator<(const String& other) const; |
146 operator const std::string&() const { return std_string(); } |
126 bool operator>=(const String& other) const; |
|
127 bool operator<=(const String& other) const; |
|
128 operator const char*() const; |
|
129 operator const std::string&() const; |
147 |
130 |
148 private: |
131 private: |
149 std::string m_string; |
132 std::string m_string; |
150 }; |
133 }; |
151 |
134 |
152 // ------------------------------------------------------------------------------------------------- |
135 |
153 // |
|
154 class StringList : public List<String> |
136 class StringList : public List<String> |
155 { |
137 { |
156 public: |
138 public: |
157 typedef List<String> Super; |
139 StringList(); |
158 |
140 StringList(int numvalues); |
159 StringList() {} |
141 StringList(const List<String>& other); |
160 |
142 String join(const String& delim); |
161 StringList (int numvalues) : |
|
162 Super (numvalues) {} |
|
163 |
|
164 StringList (const Super& other) : |
|
165 Super (other) {} |
|
166 |
|
167 String join (const String& delim); |
|
168 }; |
143 }; |
169 |
144 |
170 // ------------------------------------------------------------------------------------------------- |
145 |
171 // |
146 inline bool operator==(const char* a, const String& b); |
172 inline bool operator== (const char* a, const String& b) |
147 inline String operator+(const char* a, const String& b); |
173 { |
148 |
174 return b == a; |
149 // -------------------------------------------------------------------------------------------------------------------- |
175 } |
150 |
176 |
151 /*! |
177 // ------------------------------------------------------------------------------------------------- |
152 * \brief Constructs an empty string. |
178 // |
153 */ |
179 inline String operator+ (const char* a, const String& b) |
154 inline String::String() {} |
180 { |
155 |
181 return String (a) + b; |
156 /*! |
182 } |
157 * \brief Constructs a string from a single character. |
|
158 * \param character Character to create a string out of. |
|
159 */ |
|
160 inline String::String(char character) |
|
161 { |
|
162 char buffer[2] = { character, '\0' }; |
|
163 m_string = buffer; |
|
164 } |
|
165 |
|
166 /*! |
|
167 * \brief Constructs a string from a char-array. |
|
168 * \param string char-array to convert. |
|
169 */ |
|
170 inline String::String(const char* string) : |
|
171 m_string(string) {} |
|
172 |
|
173 /*! |
|
174 * \brief Constructs a string out of a \c std::string . |
|
175 * \param string \c std::string to base the construction on. |
|
176 */ |
|
177 inline String::String(const std::string& string) : |
|
178 m_string(string) {} |
|
179 |
|
180 /*! |
|
181 * \brief Constructs a string out of a vector of characters. The vector does not have to be null-terminated. |
|
182 * \param charVector Vector of characters to construct the string out of. |
|
183 */ |
|
184 inline String::String(const Vector<char>& charVector) : |
|
185 m_string(charVector.data(), charVector.size()) {} |
|
186 |
|
187 /*! |
|
188 * \returns a constant iterator to the beginning of the string. |
|
189 */ |
|
190 inline String::ConstIterator String::begin() const |
|
191 { |
|
192 return m_string.cbegin(); |
|
193 } |
|
194 |
|
195 /*! |
|
196 * \returns the string's contents as a char-array. |
|
197 */ |
|
198 inline const char* String::chars() const |
|
199 { |
|
200 return m_string.c_str(); |
|
201 } |
|
202 |
|
203 /*! |
|
204 * \returns the string's constant end-iterator. |
|
205 */ |
|
206 inline String::ConstIterator String::end() const |
|
207 { |
|
208 return m_string.end(); |
|
209 } |
|
210 |
|
211 /*! |
|
212 * \returns whether or not the string is empty. |
|
213 */ |
|
214 inline bool String::isEmpty() const |
|
215 { |
|
216 return m_string[0] == '\0'; |
|
217 } |
|
218 |
|
219 /*! |
|
220 * \returns the length of the string. |
|
221 */ |
|
222 inline int String::length() const |
|
223 { |
|
224 return m_string.length(); |
|
225 } |
|
226 |
|
227 /*! |
|
228 * \returns the underlying \c std::string . |
|
229 */ |
|
230 inline const std::string& String::stdString() const |
|
231 { |
|
232 return m_string; |
|
233 } |
|
234 |
|
235 /*! |
|
236 * \brief Adds text from a char-array to the end of the string. |
|
237 * \param text Text to append. |
|
238 */ |
|
239 inline void String::append(const char* text) |
|
240 { |
|
241 m_string.append(text); |
|
242 } |
|
243 |
|
244 /*! |
|
245 * \brief Adds text to the end of the string. |
|
246 * \param text Text to append. |
|
247 */ |
|
248 inline void String::append(char character) |
|
249 { |
|
250 m_string.push_back(character); |
|
251 } |
|
252 |
|
253 /*! |
|
254 * \brief Adds text from another string to the end of this string. |
|
255 * \param text Text to append. |
|
256 */ |
|
257 inline void String::append(const String& text) |
|
258 { |
|
259 m_string.append(text.chars()); |
|
260 } |
|
261 |
|
262 /*! |
|
263 * \returns a mutable iterator to the beginning of the string. |
|
264 */ |
|
265 inline String::Iterator String::begin() |
|
266 { |
|
267 return m_string.begin(); |
|
268 } |
|
269 |
|
270 /*! |
|
271 * \brief Clears the string. |
|
272 */ |
|
273 inline void String::clear() |
|
274 { |
|
275 m_string.clear(); |
|
276 } |
|
277 |
|
278 /*! |
|
279 * \returns the string's mutable end-iterator. |
|
280 */ |
|
281 inline String::Iterator String::end() |
|
282 { |
|
283 return m_string.end(); |
|
284 } |
|
285 |
|
286 /*! |
|
287 * \brief Compares two string indices, supporting negatives as offsets from the end of string. |
|
288 * \param a First index to compare |
|
289 * \param b Second index to compare |
|
290 * \returns the difference of two indices. |
|
291 */ |
|
292 inline int String::indexDifference(int a, int b) |
|
293 { |
|
294 modifyIndex(a); |
|
295 modifyIndex(b); |
|
296 return b - a; |
|
297 } |
|
298 |
|
299 /*! |
|
300 * \brief Inserts a character into the string. |
|
301 * \param position Position in the string where to insert the character into. |
|
302 * \param character Character to insert into the string. |
|
303 */ |
|
304 inline void String::insert(int position, char character) |
|
305 { |
|
306 m_string.insert(m_string.begin() + position, character); |
|
307 } |
|
308 |
|
309 /*! |
|
310 * \brief Inserts a substring into the string. |
|
311 * \param position Position in the string where to insert the substring. |
|
312 * \param string Substring to insert. |
|
313 */ |
|
314 inline void String::insert(int position, const char* string) |
|
315 { |
|
316 m_string.insert(position, string); |
|
317 } |
|
318 |
|
319 /*! |
|
320 * \brief Modifies the given index so that if it is negative, it is translated into a positive index starting from the |
|
321 * end of the string. For example, an index of -1 will be modified to point to the last character in the string, |
|
322 * -2 to the second last, etc. |
|
323 * \param index Index to translate. |
|
324 */ |
|
325 inline void String::modifyIndex(int& index) const |
|
326 { |
|
327 if (index < 0) |
|
328 index = length() - index; |
|
329 } |
|
330 |
|
331 /*! |
|
332 * \brief Prepends the given text to the beginning of the string. |
|
333 * \param text Text to prepend. |
|
334 */ |
|
335 inline void String::prepend(String text) |
|
336 { |
|
337 m_string = (text + m_string).stdString(); |
|
338 } |
|
339 |
|
340 /*! |
|
341 * \brief Removes a range of text from the string. |
|
342 * \param position Position where to start removing text. |
|
343 * \param length Amount of characters to remove. |
|
344 */ |
|
345 inline void String::remove(int position, int length) |
|
346 { |
|
347 m_string.replace(position, length, ""); |
|
348 } |
|
349 |
|
350 /*! |
|
351 * \brief Removes a single character from the string. |
|
352 * \param position Position of the character to remove string from. |
|
353 */ |
|
354 inline void String::removeAt(int position) |
|
355 { |
|
356 m_string.erase(m_string.begin() + position); |
|
357 } |
|
358 |
|
359 /*! |
|
360 * \brief Removes a number of characters from the end of the string. |
|
361 * \param length Amount of characters to remove. |
|
362 */ |
|
363 inline void String::removeFromEnd(int length) |
|
364 { |
|
365 remove(this->length() - length, length); |
|
366 } |
|
367 |
|
368 /*! |
|
369 * \brief Removes a number of characters from the beginning of the string. |
|
370 * \param length Amount of characters to remove. |
|
371 */ |
|
372 inline void String::removeFromStart(int length) |
|
373 { |
|
374 remove(0, length); |
|
375 } |
|
376 |
|
377 /*! |
|
378 * \brief Replaces a range of text in the string with another. |
|
379 * \param position Position where to start replacing text. |
|
380 * \param amount Amount of characters to replace. |
|
381 * \param text Replacement string. |
|
382 */ |
|
383 inline void String::replace(int position, int amount, const String& text) |
|
384 { |
|
385 m_string.replace(position, amount, text.chars()); |
|
386 } |
|
387 |
|
388 /*! |
|
389 * \brief Shrinks the string so that it does not allocate more characters than necessary. |
|
390 */ |
|
391 inline void String::shrinkToFit() |
|
392 { |
|
393 m_string.shrink_to_fit(); |
|
394 } |
|
395 |
|
396 /*! |
|
397 * \brief Converts a number into a string, and returns a new string with the number appended to the end of the string. |
|
398 * \param number Number to convert and append. |
|
399 * \returns the resulting string. |
|
400 */ |
|
401 inline String String::operator+(int number) const |
|
402 { |
|
403 return *this + String::fromNumber(number); |
|
404 } |
|
405 |
|
406 /*! |
|
407 * \brief Appends text into the string. |
|
408 * \param text Text to append. |
|
409 * \returns a reference to this string. |
|
410 */ |
|
411 inline String& String::operator+=(const String& text) |
|
412 { |
|
413 append(text); |
|
414 return *this; |
|
415 } |
|
416 |
|
417 /*! |
|
418 * \brief Appends text into the string. |
|
419 * \param text Text to append. |
|
420 * \returns a reference to this string. |
|
421 */ |
|
422 inline String& String::operator+=(const char* text) |
|
423 { |
|
424 append(text); |
|
425 return *this; |
|
426 } |
|
427 |
|
428 /*! |
|
429 * \brief Converts a number into a string, and appends it into this string. |
|
430 * \param number The number to append. |
|
431 * \returns a refence to this string. |
|
432 */ |
|
433 inline String& String::operator+=(int number) |
|
434 { |
|
435 return operator+=(String::fromNumber(number)); |
|
436 } |
|
437 |
|
438 /*! |
|
439 * \brief Appends a character into this string. |
|
440 * \param character The character to append. |
|
441 * \return a reference to this string. |
|
442 */ |
|
443 inline String& String::operator+=(char character) |
|
444 { |
|
445 append(character); |
|
446 return *this; |
|
447 } |
|
448 |
|
449 /*! |
|
450 * \param index Index referring to a character of this string. |
|
451 * \returns an editable reference to the character pointed by the given index. |
|
452 */ |
|
453 inline char& String::operator[](int index) |
|
454 { |
|
455 return m_string[index]; |
|
456 } |
|
457 |
|
458 /*! |
|
459 * \param index Index referring to a character of this string. |
|
460 * \returns an const reference to the character pointed by the given index. |
|
461 */ |
|
462 inline char String::operator[](int index) const |
|
463 { |
|
464 return m_string[index]; |
|
465 } |
|
466 |
|
467 /*! |
|
468 * \param other String to compare with. |
|
469 * \returns whether or not this string is the same as the other string. |
|
470 */ |
|
471 inline bool String::operator==(const String& other) const |
|
472 { |
|
473 return stdString() == other.stdString(); |
|
474 } |
|
475 |
|
476 /*! |
|
477 * \param other String to compare with. |
|
478 * \returns whether or not this string is the same as the other string. |
|
479 */ |
|
480 inline bool String::operator==(const char* other) const |
|
481 { |
|
482 return m_string == other; |
|
483 } |
|
484 |
|
485 /*! |
|
486 * \param other String to compare with. |
|
487 * \returns whether or not this string is different than the other string. |
|
488 */ |
|
489 inline bool String::operator!=(const String& other) const |
|
490 { |
|
491 return stdString() != other.stdString(); |
|
492 } |
|
493 |
|
494 /*! |
|
495 * \param other String to compare with. |
|
496 * \returns whether or not this string is different than the other string. |
|
497 */ |
|
498 inline bool String::operator!=(const char* other) const |
|
499 { |
|
500 return m_string != other; |
|
501 } |
|
502 |
|
503 /*! |
|
504 * \param other String to compare with. |
|
505 * \return whether or not this string is lexicographically greater than the other string. |
|
506 */ |
|
507 inline bool String::operator>(const String& other) const |
|
508 { |
|
509 return stdString() > other.stdString(); |
|
510 } |
|
511 |
|
512 /*! |
|
513 * \param other String to compare with. |
|
514 * \return whether or not this string is lexicographically lesser than the other string. |
|
515 */ |
|
516 inline bool String::operator<(const String& other) const |
|
517 { |
|
518 return stdString() < other.stdString(); |
|
519 } |
|
520 |
|
521 /*! |
|
522 * \param other String to compare with. |
|
523 * \return whether or not this string is lexicographically at least as great as the other string. |
|
524 */ |
|
525 inline bool String::operator>=(const String& other) const |
|
526 { |
|
527 return stdString() >= other.stdString(); |
|
528 } |
|
529 |
|
530 /*! |
|
531 * \param other String to compare with. |
|
532 * \return whether or not this string is lexicographically at most as great as the other string. |
|
533 */ |
|
534 inline bool String::operator<=(const String& other) const |
|
535 { |
|
536 return stdString() <= other.stdString(); |
|
537 } |
|
538 |
|
539 /*! |
|
540 * \returns a char-array representation of this string. |
|
541 */ |
|
542 inline String::operator const char*() const |
|
543 { |
|
544 return chars(); |
|
545 } |
|
546 |
|
547 /*! |
|
548 * \returns the underlying \c std::string of this string. |
|
549 */ |
|
550 inline String::operator const std::string&() const |
|
551 { |
|
552 return stdString(); |
|
553 } |
|
554 |
|
555 /*! |
|
556 * \brief Constructs an empty string list. |
|
557 */ |
|
558 inline StringList::StringList() {} |
|
559 |
|
560 /*! |
|
561 * \brief Constructs a string list containing \c numvalues empty strings. |
|
562 * \param numvalues Amount of empty strings to fill. |
|
563 */ |
|
564 inline StringList::StringList(int numvalues) : |
|
565 List<String>(numvalues) {} |
|
566 |
|
567 /*! |
|
568 * \brief Constructs a string list from another list of strings. |
|
569 * \param other The list of strings to use for construction. |
|
570 */ |
|
571 inline StringList::StringList(const List<String>& other) : |
|
572 List<String>(other) {} |
|
573 |
|
574 /*! |
|
575 * \brief An \c operator== implementation that allows a char-array to be at the left side of a string comparison |
|
576 * with a \c String. |
|
577 * \param one A char-array representation of a string to compare. |
|
578 * \param other A string to compare. |
|
579 * \returns whether or not the two parameters are equal. |
|
580 */ |
|
581 inline bool operator==(const char* one, const String& other) |
|
582 { |
|
583 return other == one; |
|
584 } |
|
585 |
|
586 /*! |
|
587 * \brief An \c operator+ implementation that allows a char-array to be at the left side of a string catenation |
|
588 * with a \c String. |
|
589 * \param one A char-array representation of a string to catenate. |
|
590 * \param other A string to catenate. |
|
591 * \returns the catenated string. |
|
592 */ |
|
593 inline String operator+(const char* one, const String& other) |
|
594 { |
|
595 return String(one) + other; |
|
596 } |
|
597 |
183 |
598 |
184 END_ZFC_NAMESPACE |
599 END_ZFC_NAMESPACE |