/src/ogre/OgreMain/src/OgreStringConverter.cpp
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | |
30 | | // A quick define to overcome different names for the same function |
31 | | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT |
32 | | # define strtod_l _strtod_l |
33 | | # define strtoul_l _strtoul_l |
34 | | # define strtol_l _strtol_l |
35 | | # define strtoull_l _strtoull_l |
36 | | # define strtoll_l _strtoll_l |
37 | | #endif |
38 | | |
39 | | #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN || \ |
40 | | (OGRE_PLATFORM == OGRE_PLATFORM_LINUX && OGRE_NO_LOCALE_STRCONVERT == 1) |
41 | | # define strtod_l(ptr, end, l) strtod(ptr, end) |
42 | | # define strtoul_l(ptr, end, base, l) strtoul(ptr, end, base) |
43 | | # define strtol_l(ptr, end, base, l) strtol(ptr, end, base) |
44 | | # define strtoull_l(ptr, end, base, l) strtoull(ptr, end, base) |
45 | | # define strtoll_l(ptr, end, base, l) strtoll(ptr, end, base) |
46 | | #endif |
47 | | |
48 | | #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && !defined(__MINGW32__) |
49 | | # define LC_NUMERIC_MASK LC_NUMERIC |
50 | | # define newlocale(cat, loc, base) _create_locale(cat, loc) |
51 | | #endif |
52 | | |
53 | | #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN || defined(__MINGW32__) |
54 | | # define newlocale(cat, loc, base) 0 |
55 | | #endif |
56 | | |
57 | | #ifdef __MINGW32__ |
58 | | #define _strtoull_l _strtoul_l |
59 | | #define _strtoll_l _strtol_l |
60 | | #endif |
61 | | |
62 | | namespace Ogre { |
63 | | locale_t StringConverter::_numLocale = newlocale(LC_NUMERIC_MASK, OGRE_DEFAULT_LOCALE, NULL); |
64 | | |
65 | | template<typename T> |
66 | | String StringConverter::_toString(T val, uint16 width, char fill, std::ios::fmtflags flags) |
67 | 0 | { |
68 | 0 | StringStream stream; |
69 | 0 | stream.width(width); |
70 | 0 | stream.fill(fill); |
71 | 0 | if (flags & std::ios::basefield) { |
72 | 0 | stream.setf(flags, std::ios::basefield); |
73 | 0 | stream.setf((flags & ~std::ios::basefield) | std::ios::showbase); |
74 | 0 | } |
75 | 0 | else if (flags) |
76 | 0 | stream.setf(flags); |
77 | |
|
78 | 0 | stream << val; |
79 | |
|
80 | 0 | return stream.str(); |
81 | 0 | } Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Ogre::StringConverter::_toString<int>(int, unsigned short, char, unsigned int) Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Ogre::StringConverter::_toString<unsigned int>(unsigned int, unsigned short, char, unsigned int) Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Ogre::StringConverter::_toString<unsigned long>(unsigned long, unsigned short, char, unsigned int) Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Ogre::StringConverter::_toString<unsigned long long>(unsigned long long, unsigned short, char, unsigned int) Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Ogre::StringConverter::_toString<long>(long, unsigned short, char, unsigned int) |
82 | | |
83 | | //----------------------------------------------------------------------- |
84 | | String StringConverter::toString(float val, unsigned short precision, |
85 | | unsigned short width, char fill, std::ios::fmtflags flags) |
86 | 0 | { |
87 | 0 | StringStream stream; |
88 | 0 | stream.precision(precision); |
89 | 0 | stream.width(width); |
90 | 0 | stream.fill(fill); |
91 | 0 | if (flags) |
92 | 0 | stream.setf(flags); |
93 | 0 | stream << val; |
94 | 0 | return stream.str(); |
95 | 0 | } |
96 | | |
97 | | //----------------------------------------------------------------------- |
98 | | String StringConverter::toString(double val, unsigned short precision, |
99 | | unsigned short width, char fill, std::ios::fmtflags flags) |
100 | 0 | { |
101 | 0 | StringStream stream; |
102 | 0 | stream.precision(precision); |
103 | 0 | stream.width(width); |
104 | 0 | stream.fill(fill); |
105 | 0 | if (flags) |
106 | 0 | stream.setf(flags); |
107 | 0 | stream << val; |
108 | 0 | return stream.str(); |
109 | 0 | } |
110 | | |
111 | | //----------------------------------------------------------------------- |
112 | | String StringConverter::toString(int32 val, |
113 | | unsigned short width, char fill, std::ios::fmtflags flags) |
114 | 0 | { |
115 | 0 | return _toString(val, width, fill, flags); |
116 | 0 | } |
117 | | //----------------------------------------------------------------------- |
118 | | String StringConverter::toString(uint32 val, |
119 | | unsigned short width, char fill, std::ios::fmtflags flags) |
120 | 0 | { |
121 | 0 | return _toString(val, width, fill, flags); |
122 | 0 | } |
123 | | //----------------------------------------------------------------------- |
124 | | String StringConverter::toString(unsigned long val, |
125 | | unsigned short width, char fill, std::ios::fmtflags flags) |
126 | 0 | { |
127 | 0 | return _toString(val, width, fill, flags); |
128 | 0 | } |
129 | | //----------------------------------------------------------------------- |
130 | | String StringConverter::toString(unsigned long long val, |
131 | | unsigned short width, char fill, std::ios::fmtflags flags) |
132 | 0 | { |
133 | 0 | return _toString(val, width, fill, flags); |
134 | 0 | } |
135 | | //----------------------------------------------------------------------- |
136 | | String StringConverter::toString(long val, |
137 | | unsigned short width, char fill, std::ios::fmtflags flags) |
138 | 0 | { |
139 | 0 | return _toString(val, width, fill, flags); |
140 | 0 | } |
141 | | //----------------------------------------------------------------------- |
142 | | String StringConverter::toString(const Vector2& val) |
143 | 0 | { |
144 | 0 | StringStream stream; |
145 | 0 | stream << val.x << " " << val.y; |
146 | 0 | return stream.str(); |
147 | 0 | } |
148 | | //----------------------------------------------------------------------- |
149 | | String StringConverter::toString(const Vector3& val) |
150 | 0 | { |
151 | 0 | StringStream stream; |
152 | 0 | stream << val.x << " " << val.y << " " << val.z; |
153 | 0 | return stream.str(); |
154 | 0 | } |
155 | | //----------------------------------------------------------------------- |
156 | | String StringConverter::toString(const Vector4& val) |
157 | 0 | { |
158 | 0 | StringStream stream; |
159 | 0 | stream << val.x << " " << val.y << " " << val.z << " " << val.w; |
160 | 0 | return stream.str(); |
161 | 0 | } |
162 | | //----------------------------------------------------------------------- |
163 | | String StringConverter::toString(const Matrix3& val) |
164 | 0 | { |
165 | 0 | StringStream stream; |
166 | 0 | stream << val[0][0] << " " |
167 | 0 | << val[0][1] << " " |
168 | 0 | << val[0][2] << " " |
169 | 0 | << val[1][0] << " " |
170 | 0 | << val[1][1] << " " |
171 | 0 | << val[1][2] << " " |
172 | 0 | << val[2][0] << " " |
173 | 0 | << val[2][1] << " " |
174 | 0 | << val[2][2]; |
175 | 0 | return stream.str(); |
176 | 0 | } |
177 | | //----------------------------------------------------------------------- |
178 | | String StringConverter::toString(bool val, bool yesNo) |
179 | 0 | { |
180 | 0 | if (val) |
181 | 0 | { |
182 | 0 | if (yesNo) |
183 | 0 | { |
184 | 0 | return "yes"; |
185 | 0 | } |
186 | 0 | else |
187 | 0 | { |
188 | 0 | return "true"; |
189 | 0 | } |
190 | 0 | } |
191 | 0 | else |
192 | 0 | if (yesNo) |
193 | 0 | { |
194 | 0 | return "no"; |
195 | 0 | } |
196 | 0 | else |
197 | 0 | { |
198 | 0 | return "false"; |
199 | 0 | } |
200 | 0 | } |
201 | | //----------------------------------------------------------------------- |
202 | | String StringConverter::toString(const Matrix4& val) |
203 | 0 | { |
204 | 0 | StringStream stream; |
205 | 0 | stream << val[0][0] << " " |
206 | 0 | << val[0][1] << " " |
207 | 0 | << val[0][2] << " " |
208 | 0 | << val[0][3] << " " |
209 | 0 | << val[1][0] << " " |
210 | 0 | << val[1][1] << " " |
211 | 0 | << val[1][2] << " " |
212 | 0 | << val[1][3] << " " |
213 | 0 | << val[2][0] << " " |
214 | 0 | << val[2][1] << " " |
215 | 0 | << val[2][2] << " " |
216 | 0 | << val[2][3] << " " |
217 | 0 | << val[3][0] << " " |
218 | 0 | << val[3][1] << " " |
219 | 0 | << val[3][2] << " " |
220 | 0 | << val[3][3]; |
221 | 0 | return stream.str(); |
222 | 0 | } |
223 | | //----------------------------------------------------------------------- |
224 | | String StringConverter::toString(const Quaternion& val) |
225 | 0 | { |
226 | 0 | StringStream stream; |
227 | 0 | stream << val.w << " " << val.x << " " << val.y << " " << val.z; |
228 | 0 | return stream.str(); |
229 | 0 | } |
230 | | //----------------------------------------------------------------------- |
231 | | String StringConverter::toString(const ColourValue& val) |
232 | 0 | { |
233 | 0 | StringStream stream; |
234 | 0 | stream << val.r << " " << val.g << " " << val.b << " " << val.a; |
235 | 0 | return stream.str(); |
236 | 0 | } |
237 | | //----------------------------------------------------------------------- |
238 | | String StringConverter::toString(const StringVector& val) |
239 | 7.26k | { |
240 | 7.26k | StringStream stream; |
241 | 7.26k | StringVector::const_iterator i, iend, ibegin; |
242 | 7.26k | ibegin = val.begin(); |
243 | 7.26k | iend = val.end(); |
244 | 17.9k | for (i = ibegin; i != iend; ++i) |
245 | 10.6k | { |
246 | 10.6k | if (i != ibegin) |
247 | 3.41k | stream << " "; |
248 | | |
249 | 10.6k | stream << *i; |
250 | 10.6k | } |
251 | 7.26k | return stream.str(); |
252 | 7.26k | } |
253 | | |
254 | | //----------------------------------------------------------------------- |
255 | | template <typename T> static bool assignValid(bool valid, const T& val, T& ret) |
256 | 36.9k | { |
257 | 36.9k | if (valid) |
258 | 32.0k | ret = val; |
259 | 36.9k | return valid; |
260 | 36.9k | } OgreStringConverter.cpp:bool Ogre::assignValid<float>(bool, float const&, float&) Line | Count | Source | 256 | 26.3k | { | 257 | 26.3k | if (valid) | 258 | 25.6k | ret = val; | 259 | 26.3k | return valid; | 260 | 26.3k | } |
Unexecuted instantiation: OgreStringConverter.cpp:bool Ogre::assignValid<double>(bool, double const&, double&) OgreStringConverter.cpp:bool Ogre::assignValid<int>(bool, int const&, int&) Line | Count | Source | 256 | 876 | { | 257 | 876 | if (valid) | 258 | 576 | ret = val; | 259 | 876 | return valid; | 260 | 876 | } |
Unexecuted instantiation: OgreStringConverter.cpp:bool Ogre::assignValid<long>(bool, long const&, long&) Unexecuted instantiation: OgreStringConverter.cpp:bool Ogre::assignValid<unsigned long>(bool, unsigned long const&, unsigned long&) Unexecuted instantiation: OgreStringConverter.cpp:bool Ogre::assignValid<unsigned long long>(bool, unsigned long long const&, unsigned long long&) OgreStringConverter.cpp:bool Ogre::assignValid<unsigned int>(bool, unsigned int const&, unsigned int&) Line | Count | Source | 256 | 9.77k | { | 257 | 9.77k | if (valid) | 258 | 5.84k | ret = val; | 259 | 9.77k | return valid; | 260 | 9.77k | } |
|
261 | | |
262 | | bool StringConverter::parse(const String& val, float& ret) |
263 | 26.3k | { |
264 | 26.3k | char* end; |
265 | 26.3k | auto tmp = (float)strtod_l(val.c_str(), &end, _numLocale); |
266 | 26.3k | return assignValid(val.c_str() != end, tmp, ret); |
267 | 26.3k | } |
268 | | bool StringConverter::parse(const String& val, double& ret) |
269 | 0 | { |
270 | 0 | char* end; |
271 | 0 | auto tmp = strtod_l(val.c_str(), &end, _numLocale); |
272 | 0 | return assignValid(val.c_str() != end, tmp, ret); |
273 | 0 | } |
274 | | //----------------------------------------------------------------------- |
275 | | bool StringConverter::parse(const String& val, int32& ret) |
276 | 876 | { |
277 | 876 | char* end; |
278 | 876 | auto tmp = (int32)strtol_l(val.c_str(), &end, 0, _numLocale); |
279 | 876 | return assignValid(val.c_str() != end, tmp, ret); |
280 | 876 | } |
281 | | //----------------------------------------------------------------------- |
282 | | bool StringConverter::parse(const String& val, int64& ret) |
283 | 0 | { |
284 | 0 | char* end; |
285 | 0 | int64 tmp = strtoll_l(val.c_str(), &end, 0, _numLocale); |
286 | 0 | return assignValid(val.c_str() != end, tmp, ret); |
287 | 0 | } |
288 | | //----------------------------------------------------------------------- |
289 | | bool StringConverter::parse(const String& val, unsigned long& ret) |
290 | 0 | { |
291 | 0 | char* end; |
292 | 0 | unsigned long tmp = strtoull_l(val.c_str(), &end, 0, _numLocale); |
293 | 0 | return assignValid(val.c_str() != end, tmp, ret); |
294 | 0 | } |
295 | | bool StringConverter::parse(const String& val, unsigned long long& ret) |
296 | 0 | { |
297 | 0 | char* end; |
298 | 0 | unsigned long long tmp = strtoull_l(val.c_str(), &end, 0, _numLocale); |
299 | 0 | return assignValid(val.c_str() != end, tmp, ret); |
300 | 0 | } |
301 | | //----------------------------------------------------------------------- |
302 | | bool StringConverter::parse(const String& val, uint32& ret) |
303 | 9.77k | { |
304 | 9.77k | char* end; |
305 | 9.77k | auto tmp = (uint32)strtoul_l(val.c_str(), &end, 0, _numLocale); |
306 | 9.77k | return assignValid(val.c_str() != end, tmp, ret); |
307 | 9.77k | } |
308 | | bool StringConverter::parse(const String& val, bool& ret) |
309 | 0 | { |
310 | | //FIXME Returns both parsed value and error in same value - ambiguous. |
311 | | // Suggested alternatives: implement exception handling or make either |
312 | | // error or parsed value a parameter. |
313 | 0 | if ((StringUtil::startsWith(val, "true") || StringUtil::startsWith(val, "yes") |
314 | 0 | || StringUtil::startsWith(val, "1") || StringUtil::startsWith(val, "on"))) |
315 | 0 | ret = true; |
316 | 0 | else if ((StringUtil::startsWith(val, "false") || StringUtil::startsWith(val, "no") |
317 | 0 | || StringUtil::startsWith(val, "0") || StringUtil::startsWith(val, "off"))) |
318 | 0 | ret = false; |
319 | 0 | else |
320 | 0 | return false; |
321 | | |
322 | 0 | return true; |
323 | 0 | } |
324 | | |
325 | | static bool parseReals(const String& val, Real* dst, size_t n) |
326 | 0 | { |
327 | | // Split on space |
328 | 0 | std::vector<String> vec = StringUtil::split(val); |
329 | 0 | if(vec.size() != n) |
330 | 0 | return false; |
331 | | |
332 | 0 | bool ret = true; |
333 | 0 | for(size_t i = 0; i < n; i++) |
334 | 0 | ret &= StringConverter::parse(vec[i], dst[i]); |
335 | 0 | return ret; |
336 | 0 | } |
337 | | |
338 | | //----------------------------------------------------------------------- |
339 | | bool StringConverter::parse(const String& val, Vector2& ret) |
340 | 0 | { |
341 | 0 | return parseReals(val, ret.ptr(), 2); |
342 | 0 | } |
343 | | //----------------------------------------------------------------------- |
344 | | bool StringConverter::parse(const String& val, Vector3& ret) |
345 | 0 | { |
346 | 0 | return parseReals(val, ret.ptr(), 3); |
347 | 0 | } |
348 | | //----------------------------------------------------------------------- |
349 | | bool StringConverter::parse(const String& val, Vector4& ret) |
350 | 0 | { |
351 | 0 | return parseReals(val, ret.ptr(), 4); |
352 | 0 | } |
353 | | //----------------------------------------------------------------------- |
354 | | bool StringConverter::parse(const String& val, Matrix3& ret) |
355 | 0 | { |
356 | 0 | return parseReals(val, &ret[0][0], 9); |
357 | 0 | } |
358 | | //----------------------------------------------------------------------- |
359 | | bool StringConverter::parse(const String& val, Matrix4& ret) |
360 | 0 | { |
361 | 0 | return parseReals(val, &ret[0][0], 16); |
362 | 0 | } |
363 | | //----------------------------------------------------------------------- |
364 | | bool StringConverter::parse(const String& val, Quaternion& ret) |
365 | 0 | { |
366 | 0 | return parseReals(val, ret.ptr(), 4); |
367 | 0 | } |
368 | | //----------------------------------------------------------------------- |
369 | | bool StringConverter::parse(const String& val, ColourValue& ret) |
370 | 0 | { |
371 | | // Split on space |
372 | 0 | std::vector<String> vec = StringUtil::split(val); |
373 | |
|
374 | 0 | if (vec.size() == 4) |
375 | 0 | { |
376 | 0 | return parse(vec[0], ret.r) && parse(vec[1], ret.g) && parse(vec[2], ret.b) && |
377 | 0 | parse(vec[3], ret.a); |
378 | 0 | } |
379 | 0 | else if (vec.size() == 3) |
380 | 0 | { |
381 | 0 | ret.a = 1.0f; |
382 | 0 | return parse(vec[0], ret.r) && parse(vec[1], ret.g) && parse(vec[2], ret.b); |
383 | 0 | } |
384 | 0 | else |
385 | 0 | { |
386 | 0 | return false; |
387 | 0 | } |
388 | 0 | } |
389 | | //----------------------------------------------------------------------- |
390 | | bool StringConverter::isNumber(const String& val) |
391 | 0 | { |
392 | 0 | char* end; |
393 | 0 | strtod(val.c_str(), &end); |
394 | 0 | return end == (val.c_str() + val.size()); |
395 | 0 | } |
396 | | } |
397 | | |
398 | | |