SuperTuxKart
Loading...
Searching...
No Matches
string_utils.hpp
1//
2// SuperTuxKart - a fun racing game with go-kart
3// Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>,
4// Copyright (C) 2004-2015 Ingo Ruhnke <grumbel@gmx.de>
5// Copyright (C) 2006-2015 SuperTuxKart-Team
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 3
10// of the License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21#ifndef HEADER_STRING_UTILS_HPP
22#define HEADER_STRING_UTILS_HPP
23
24#include "utils/types.hpp"
25#include <limits>
26#include <string>
27#include <vector>
28#include <sstream>
29#include <irrString.h>
30#include <IGUIFont.h>
31#include <irrTypes.h>
32
33namespace StringUtils
34{
35 void unitTesting();
36 int versionToInt(const std::string &s);
37
38 bool hasSuffix(const std::string& lhs, const std::string &rhs);
39 bool startsWith(const std::string& str, const std::string& prefix);
40
42 std::string getBasename(const std::string& filename);
43
45 std::string getPath(const std::string& filename);
46
47 std::string removeExtension(const std::string& filename);
48 std::string getExtension(const std::string& filename);
49
50 std::string ticksTimeToString(int time);
51 std::string timeToString(float time, unsigned int precision = 3,
52 bool display_minutes_if_zero = true, bool display_hours = false);
53 irr::core::stringw loadingDots(float interval = 0.5f, int max_dots = 3);
54 irr::core::stringw loadingDots(const irr::core::stringw& s);
55 std::string toUpperCase(const std::string&);
56 std::string toLowerCase(const std::string&);
57 std::vector<std::string> split(const std::string& s, char c,
58 bool keepSplitChar=false);
59 std::vector<std::u32string> split(const std::u32string& s, char32_t c,
60 bool keepSplitChar=false);
61 std::vector<irr::core::stringw> split(const irr::core::stringw& s,
62 char c, bool keepSplitChar=false);
63 std::vector<uint32_t> splitToUInt(const std::string& s, char c,
64 bool keepSplitChar=false);
65 std::vector<std::string> splitPath(const std::string& path);
66 std::string replace(const std::string& other, const std::string& from, const std::string& to);
67
68 irr::core::stringw xmlDecode(const std::string& input);
69
70 std::string xmlEncode(const irr::core::stringw &output);
71
72 // ------------------------------------------------------------------------
73 template <class T>
74 std::string toString(const T& any)
75 {
76 std::ostringstream oss;
77 oss << any;
78 return oss.str();
79 } // toString template
80
81 // ------------------------------------------------------------------------
82 template <>
83 inline std::string toString(const double& any)
84 {
85 std::ostringstream oss;
86 oss.precision(std::numeric_limits<double>::max_digits10);
87 oss << any;
88 return oss.str();
89 } // toString template
90
91 // ------------------------------------------------------------------------
93 inline std::string toString(const bool& b)
94 {
95 return (b ? "true" : "false");
96 } // toString(bool)
97
98 // ------------------------------------------------------------------------
99 template <class T>
100 irr::core::stringw toWString (const T& any)
101 {
102 std::ostringstream oss;
103 oss << any ;
104 return oss.str().c_str();
105 } // toWString
106
107 // ------------------------------------------------------------------------
111 template <class T>
112 bool fromString(const std::string& rep, T& x)
113 {
114 // Don't modify x" if the conversion fails by using a temp
115 T temp;
116 std::istringstream iss(rep);
117 iss >> temp;
118
119 if (iss.fail())
120 {
121 return false;
122 }
123 else
124 {
125 x = temp;
126 return true;
127 }
128 } // fromString
129
130 // ------------------------------------------------------------------------
152 std::string insertValues(const std::string &s,
153 std::vector<std::string>& all_vals);
154
155 // ------------------------------------------------------------------------
157 irr::core::stringw insertValues(const irr::core::stringw &s,
158 std::vector<irr::core::stringw>& all_vals);
159
160 // ------------------------------------------------------------------------
163 {
168 template<typename T, typename...Args>
169 static void FillS(std::vector<std::string> &all_vals, T&& v, Args &&...args)
170 {
171 std::ostringstream oss;
172 oss << v;
173 all_vals.push_back(oss.str());
174 FillS(all_vals, std::forward<Args>(args)...);
175 }
176
177 static void FillS(std::vector<std::string>&) {}
178
180 template<typename T, typename...Args>
181 static void FillW(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
182 {
183 all_vals.push_back(irr::core::stringw(std::forward<T>(v)));
184 FillW(all_vals, std::forward<Args>(args)...);
185 }
186
187 static void FillW(std::vector<irr::core::stringw>&) {}
188 };
189
190 template <typename...Args>
191 std::string insertValues(const std::string &s, Args ...args)
192 {
193 std::vector<std::string> all_vals;
194 all_vals.reserve(sizeof...(args));
195 FillStringVector::FillS(all_vals, std::forward<Args>(args)...);
196 return insertValues(s, all_vals);
197 }
198
199 template <typename...Args>
200 std::string insertValues(const char *s, Args ...args)
201 {
202 return insertValues(std::string(s), std::forward<Args>(args)...);
203 }
204
206 template <typename...Args>
207 irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
208 {
209 std::vector<irr::core::stringw> all_vals;
210 all_vals.reserve(sizeof...(args));
211 FillStringVector::FillW(all_vals, std::forward<Args>(args)...);
212 return insertValues(s, all_vals);
213 }
214
215 template <typename...Args>
216 irr::core::stringw insertValues(const wchar_t *s, Args ...args)
217 {
218 return insertValues(irr::core::stringw(s), std::forward<Args>(args)...);
219 }
220
221 // ------------------------------------------------------------------------
222 template<typename T>
223 bool parseString(const char* input, T* output)
224 {
225 std::istringstream conv(input);
226 conv >> *output;
227
228 // check reading worked correctly and everything was read
229 if (conv.fail() || !conv.eof())
230 {
231 return false;
232 }
233 return true;
234 } // parseString
235
236 // ------------------------------------------------------------------------
237 template<typename T>
238 bool parseString(const std::string& input, T* output)
239 {
240 return parseString(input.c_str(), output);
241 } // parseString
242
243 // ------------------------------------------------------------------------
246 inline irr::core::stringw getCountryFlag(const std::string& country_code)
247 {
248 irr::core::stringw result;
249 if (country_code.empty() || country_code.size() != 2)
250 return result;
251 uint32_t flag[2] =
252 {
253 (uint32_t)(country_code[0]) + 127397,
254 (uint32_t)(country_code[1]) + 127397
255 };
256 if (sizeof(wchar_t) == 4)
257 {
258 result.reserve(2);
259 result.append((wchar_t)flag[0]);
260 result.append((wchar_t)flag[1]);
261 }
262 else if (sizeof(wchar_t) == 2)
263 {
264 flag[0] -= 0x10000;
265 flag[1] -= 0x10000;
266 result.reserve(4);
267 //make a surrogate pair
268 result.append(static_cast<wchar_t>((flag[0] >> 10) + 0xd800));
269 result.append(static_cast<wchar_t>((flag[0] & 0x3ff) + 0xdc00));
270 result.append(static_cast<wchar_t>((flag[1] >> 10) + 0xd800));
271 result.append(static_cast<wchar_t>((flag[1] & 0x3ff) + 0xdc00));
272 }
273 return result;
274 } // getCountryFlag
275
276 // ------------------------------------------------------------------------
277 irr::core::stringw utf8ToWide(const char* input);
278 irr::core::stringw utf8ToWide(const std::string &input);
279 std::u32string utf8ToUtf32(const std::string &input);
280 std::string wideToUtf8(const wchar_t* input);
281 std::string wideToUtf8(const irr::core::stringw& input);
282 std::string utf32ToUtf8(const std::u32string& input);
283 std::string findAndReplace(const std::string& source, const std::string& find, const std::string& replace);
284 std::string removeWhitespaces(const std::string& input);
285 irr::core::stringw getReadableFileSize(uint64_t n);
286 irr::core::stringw utf32ToWide(const std::u32string& input);
287 std::u32string wideToUtf32(const irr::core::stringw& input);
288
289 std::string getUserAgentString();
296 std::string getHostNameFromURL(const std::string& url);
297 // ------------------------------------------------------------------------
298 std::pair<std::string, std::string> extractVersionOS(
299 const std::string& user_agent);
300 // ------------------------------------------------------------------------
301 /* Get line from istream with taking into account for its line ending. */
302 inline std::istream& safeGetline(std::istream& is, std::string& t)
303 {
304 t.clear();
305
306 // The characters in the stream are read one-by-one using a std::streambuf.
307 // That is faster than reading them one-by-one using the std::istream.
308 // Code that uses streambuf this way must be guarded by a sentry object.
309 // The sentry object performs various tasks,
310 // such as thread synchronization and updating the stream state.
311 std::istream::sentry se(is, true);
312 std::streambuf* sb = is.rdbuf();
313
314 for(;;)
315 {
316 int c = sb->sbumpc();
317 switch (c)
318 {
319 case '\n':
320 return is;
321 case '\r':
322 if(sb->sgetc() == '\n')
323 sb->sbumpc();
324 return is;
325 case std::streambuf::traits_type::eof():
326 // Also handle the case when the last line has no line ending
327 if (t.empty())
328 is.setstate(std::ios::eofbit);
329 return is;
330 default:
331 t += (char)c;
332 }
333 }
334 }
335
336} // namespace StringUtils
337
338#endif
std::string insertValues(std::string *format_string, std::string *arg1)
Replaces placeholders with values.
Definition: script_utils.cpp:60
Intermediate struct to fill a vector using variadic templates.
Definition: string_utils.hpp:163
static void FillS(std::vector< std::string > &all_vals, T &&v, Args &&...args)
FillS takes a vector as the first argument and a variadic list of arguments.
Definition: string_utils.hpp:169
static void FillW(std::vector< irr::core::stringw > &all_vals, T &&v, Args &&...args)
This functions does the same as FillS but for wide strings.
Definition: string_utils.hpp:181
Declares the general types that are used by the network.