3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #ifndef UTIL_STRING_HEADER
21 #define UTIL_STRING_HEADER
23 #include "irrlichttypes_bloated.h"
31 #define STRINGIFY(x) #x
32 #define TOSTRING(x) STRINGIFY(x)
39 std::wstring narrow_to_wide(const std::string& mbs);
40 std::string wide_to_narrow(const std::wstring& wcs);
41 std::string translatePassword(std::string playername, std::wstring password);
42 std::string urlencode(std::string str);
43 std::string urldecode(std::string str);
44 u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask);
45 std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask);
46 size_t mystrlcpy(char *dst, const char *src, size_t size);
47 char *mystrtok_r(char *s, const char *sep, char **lasts);
48 u64 read_seed(const char *str);
49 bool parseColorString(const std::string &value, video::SColor &color, bool quiet);
53 * Returns a copy of s with spaces inserted at the right hand side to ensure
54 * that the string is len characters in length. If s is <= len then the
55 * returned string will be identical to s.
57 static inline std::string padStringRight(std::string s, size_t len)
60 s.insert(s.end(), len - s.size(), ' ');
67 * Returns a version of the string s with the first occurrence of a string
68 * contained within ends[] removed from the end of the string.
71 * @param ends A NULL- or ""- terminated array of strings to remove from s in
72 * the copy produced. Note that once one of these strings is removed
73 * that no further postfixes contained within this array are removed.
75 * @return If no end could be removed then "" is returned
77 static inline std::string removeStringEnd(const std::string &s, const char *ends[])
79 const char **p = ends;
81 for (; *p && (*p)[0] != '\0'; p++) {
83 if(s.size() < end.size())
85 if(s.substr(s.size()-end.size(), end.size()) == end)
86 return s.substr(0, s.size() - end.size());
94 * Check two wide strings for equivalence. If case_insensitive is true
95 * then the case of the strings are ignored (default is false).
99 * @param case_insensitive
100 * @return true if the strings match
102 inline bool str_equal(const std::wstring &s1, const std::wstring &s2,
103 bool case_insensitive = false)
105 if (case_insensitive) {
106 if (s1.size() != s2.size())
109 for (size_t i = 0; i < s1.size(); ++i)
110 if(tolower(s1[i]) != tolower(s2[i]))
121 * Check whether str begins with the string prefix. If the argument
122 * case_insensitive == true then the check is case insensitve (default
123 * is false; i.e. case is significant).
127 * @param case_insensitive
128 * @return true if the str begins with prefix
130 inline bool str_starts_with(const std::wstring &str, const std::wstring &prefix,
131 bool case_insensitive = false)
133 if (str.size() < prefix.size())
136 if (case_insensitive) {
137 for (size_t i = 0; i < prefix.size(); ++i)
138 if (tolower(str[i]) != tolower(prefix[i]))
141 for (size_t i = 0; i < prefix.size(); ++i)
142 if (str[i] != prefix[i])
151 * Splits a string of wide characters into its component parts separated by
152 * the character delimiter.
154 * @return a std::vector<std::wstring> of the component parts
156 inline std::vector<std::wstring> str_split(const std::wstring &str,
159 std::vector<std::wstring> parts;
160 std::wstringstream sstr(str);
163 while (std::getline(sstr, part, delimiter))
164 parts.push_back(part);
171 * Splits a string into its component parts separated by the character
174 * @return a std::vector<std::string> of the component parts
177 inline std::vector<std::string> str_split(const std::string &str, char delimiter) {
179 std::vector<std::string> parts;
180 std::stringstream sstr(str);
183 while (std::getline(sstr, part, delimiter))
184 parts.push_back(part);
191 * Return a copy of s converted to all lowercase characters
194 inline std::string lowercase(const std::string &s)
198 s2.reserve(s.size());
200 for (size_t i = 0; i < s.size(); i++)
208 * Returns a copy of s with leading and trailing whitespace removed.
211 inline std::string trim(const std::string &s)
215 while (std::isspace(s[front]))
218 size_t back = s.size();
219 while (back > front && std::isspace(s[back-1]))
222 return s.substr(front, back - front);
227 * Returns true if s should be regarded as (bool) true. Leading and trailing
228 * whitespace are ignored; case is ignored. Values that will return
229 * true are "y", "n", "true" and any number that != 0.
232 inline bool is_yes(const std::string &s)
234 std::string s2 = lowercase(trim(s));
236 return s2 == "y" || s2 == "yes" || s2 == "true" || atoi(s2.c_str()) != 0;
241 * Converts the string s to a signed 32-bit integer. The converted value is
242 * constrained so that min <= value <= max.
244 * @see atoi(3) for limitations
247 * @param min Range minimum
248 * @param max Range maximum
249 * @return The value converted to a signed 32-bit integer and constrained
250 * within the range defined by min and max (inclusive)
252 inline s32 mystoi(const std::string &s, s32 min, s32 max)
254 s32 i = atoi(s.c_str());
266 * Returns a 64-bit value reprensented by the string s (decimal).
268 inline s64 stoi64(const std::string &s)
270 std::stringstream tmp(s);
276 // MSVC2010 includes it's own versions of these
277 //#if !defined(_MSC_VER) || _MSC_VER < 1600
281 * Returns a 32-bit value reprensented by the string s (decimal).
283 * @see atoi(3) for further limitations
285 inline s32 mystoi(const std::string &s)
287 return atoi(s.c_str());
292 * Returns a 32-bit value reprensented by the wide string s (decimal).
294 * @see atoi(3) for further limitations
296 inline s32 mystoi(const std::wstring &s)
298 return atoi(wide_to_narrow(s).c_str());
303 * Returns a float reprensented by the string s (decimal).
307 inline float mystof(const std::string &s)
309 // This crap causes a segfault in certain cases on MinGW
311 std::istringstream ss(s);
314 // This works in that case
315 return atof(s.c_str());
325 * Returns a string representing the decimal value of the 32-bit value i
327 inline std::string itos(s32 i)
329 std::ostringstream o;
336 * Returns a string representing the decimal value of i of the 64-bit value i
338 inline std::string i64tos(s64 i) {
339 std::ostringstream o;
346 * Returns a string representing the real number (decimal) float value i
348 inline std::string ftos(float f)
350 std::ostringstream o;
357 * Replace all occurrences of pattern in str with replacement
359 * @param str String to replace pattern with replacement within
360 * @param pattern The pattern to replace
361 * @param replacement What to replace the pattern with
363 inline void str_replace(std::string &str, std::string const &pattern,
364 std::string const &replacement)
366 std::string::size_type start = str.find(pattern, 0);
367 while (start != str.npos) {
368 str.replace(start, pattern.size(), replacement);
369 start = str.find(pattern, start+replacement.size());
375 * Replace all occurrances of the character from in str with to.
377 * @param str The string to (potentially) modify
378 * @param from The character in str to replace
379 * @param to The replacement character
381 inline void str_replace_char(std::string &str, char from, char to)
383 for (size_t i = 0; i < str.size(); i++)
390 * Check that a string only contains whitelisted characters. This is the
391 * opposite of string_allowed_blacklist().
393 * @param s The string to be checked.
394 * @param allowed_chars A string containing permitted characters.
395 * @return true if the string is allowed, otherwise false.
397 * @see string_allowed_blacklist()
399 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
401 for (size_t i = 0; i < s.size(); i++)
402 if (allowed_chars.find(s[i]) == std::string::npos)
410 * Check that a string contains no blacklisted characters. This is the
411 * opposite of string_allowed().
413 * @param s The string to be checked.
414 * @param blacklisted_chars A string containing prohibited characters.
415 * @return true if the string is allowed, otherwise false.
417 * @see string_allowed()
419 inline bool string_allowed_blacklist(const std::string &s,
420 const std::string &blacklisted_chars)
422 for (size_t i = 0; i < s.size(); i++)
423 if (blacklisted_chars.find(s[i]) != std::string::npos)
431 * Create a string based on 'from' where a newline is forcefully inserted every
432 * 'rowlen' characters.
434 * @note This function does not honour word wraps and blindy inserts a newline
435 * every rowlen characters whether it breaks a word or not. It is
436 * intended to be used, for example, showing paths in the GUI
438 * @param from The string to be wrapped into rows.
439 * @param rowlen The row length (in characters).
440 * @return A new string with the wrapping applied.
442 inline std::string wrap_rows(const std::string &from, u32 rowlen)
446 for (size_t i = 0; i < from.size(); i++) {
447 if(i != 0 && i % rowlen == 0)
457 * Removes all \\ from a string that had been escaped (FormSpec strings)
460 inline std::string unescape_string(std::string &s)
464 for (size_t i = 0; i < s.length(); i++) {
475 * Checks that all characters in tocheck are a decimal digits
478 * @return true if tockcheck is not empty and all characters in tocheck are
479 * decimal digits, otherwise false
481 inline bool is_number(const std::string &tocheck)
483 for (size_t i = 0; i < tocheck.size(); i++)
484 if (!std::isdigit(tocheck[i]))
487 return !tocheck.empty();
492 * Returns a C-string, either "true" or "false", corresponding to v
494 * @return If v == true, then "true" is returned, otherwise "false"
496 inline const char *bool_to_cstr(bool v)
498 return v ? "true" : "false";