StringUtils.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2012 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "StringUtils.h"
  25. #include <cstdio>
  26. #include <ctype.h>
  27. #include "DebugNew.h"
  28. unsigned CountElements(const char* buffer, char separator)
  29. {
  30. if (!buffer)
  31. return 0;
  32. const char* endPos = buffer + String::CStringLength(buffer);
  33. const char* pos = buffer;
  34. unsigned ret = 0;
  35. while (pos < endPos)
  36. {
  37. if (*pos != separator)
  38. break;
  39. ++pos;
  40. }
  41. while (pos < endPos)
  42. {
  43. const char* start = pos;
  44. while (start < endPos)
  45. {
  46. if (*start == separator)
  47. break;
  48. ++start;
  49. }
  50. if (start == endPos)
  51. {
  52. ++ret;
  53. break;
  54. }
  55. const char* end = start;
  56. while (end < endPos)
  57. {
  58. if (*end != separator)
  59. break;
  60. ++end;
  61. }
  62. ++ret;
  63. pos = end;
  64. }
  65. return ret;
  66. }
  67. bool ToBool(const String& source)
  68. {
  69. return ToBool(source.CString());
  70. }
  71. bool ToBool(const char* source)
  72. {
  73. unsigned length = String::CStringLength(source);
  74. for (unsigned i = 0; i < length; ++i)
  75. {
  76. char c = tolower(source[i]);
  77. if (c == 't' || c == 'y' || c == '1')
  78. return true;
  79. else if (c != ' ' && c != '\t')
  80. break;
  81. }
  82. return false;
  83. }
  84. int ToInt(const String& source)
  85. {
  86. return ToInt(source.CString());
  87. }
  88. int ToInt(const char* source)
  89. {
  90. if (!source)
  91. return 0;
  92. return strtol(source, 0, 0);
  93. }
  94. unsigned ToUInt(const String& source)
  95. {
  96. return ToUInt(source.CString());
  97. }
  98. unsigned ToUInt(const char* source)
  99. {
  100. if (!source)
  101. return 0;
  102. return strtoul(source, 0, 0);
  103. }
  104. float ToFloat(const String& source)
  105. {
  106. return ToFloat(source.CString());
  107. }
  108. float ToFloat(const char* source)
  109. {
  110. if (!source)
  111. return 0;
  112. return (float)strtod(source, 0);
  113. }
  114. Color ToColor(const String& source)
  115. {
  116. return ToColor(source.CString());
  117. }
  118. Color ToColor(const char* source)
  119. {
  120. Color ret;
  121. unsigned elements = CountElements(source, ' ');
  122. if (elements < 3)
  123. return ret;
  124. char* ptr = (char*)source;
  125. ret.r_ = (float)strtod(ptr, &ptr);
  126. ret.g_ = (float)strtod(ptr, &ptr);
  127. ret.b_ = (float)strtod(ptr, &ptr);
  128. if (elements > 3)
  129. ret.a_ = (float)strtod(ptr, &ptr);
  130. return ret;
  131. }
  132. IntRect ToIntRect(const String& source)
  133. {
  134. return ToIntRect(source.CString());
  135. }
  136. IntRect ToIntRect(const char* source)
  137. {
  138. IntRect ret(IntRect::ZERO);
  139. unsigned elements = CountElements(source, ' ');
  140. if (elements < 4)
  141. return ret;
  142. char* ptr = (char*)source;
  143. ret.left_ = strtol(ptr, &ptr, 0);
  144. ret.top_ = strtol(ptr, &ptr, 0);
  145. ret.right_ = strtol(ptr, &ptr, 0);
  146. ret.bottom_ = strtol(ptr, &ptr, 0);
  147. return ret;
  148. }
  149. IntVector2 ToIntVector2(const String& source)
  150. {
  151. return ToIntVector2(source.CString());
  152. }
  153. IntVector2 ToIntVector2(const char* source)
  154. {
  155. IntVector2 ret(IntVector2::ZERO);
  156. unsigned elements = CountElements(source, ' ');
  157. if (elements < 2)
  158. return ret;
  159. char* ptr = (char*)source;
  160. ret.x_ = strtol(ptr, &ptr, 0);
  161. ret.y_ = strtol(ptr, &ptr, 0);
  162. return ret;
  163. }
  164. Rect ToRect(const String& source)
  165. {
  166. return ToRect(source.CString());
  167. }
  168. Rect ToRect(const char* source)
  169. {
  170. Rect ret(Rect::ZERO);
  171. unsigned elements = CountElements(source, ' ');
  172. if (elements < 4)
  173. return ret;
  174. char* ptr = (char*)source;
  175. ret.min_.x_ = (float)strtod(ptr, &ptr);
  176. ret.min_.y_ = (float)strtod(ptr, &ptr);
  177. ret.max_.x_ = (float)strtod(ptr, &ptr);
  178. ret.max_.y_ = (float)strtod(ptr, &ptr);
  179. return ret;
  180. }
  181. Quaternion ToQuaternion(const String& source)
  182. {
  183. return ToQuaternion(source.CString());
  184. }
  185. Quaternion ToQuaternion(const char* source)
  186. {
  187. unsigned elements = CountElements(source, ' ');
  188. char* ptr = (char*)source;
  189. if (elements < 3)
  190. return Quaternion::IDENTITY;
  191. else if (elements < 4)
  192. {
  193. // 3 coords specified: conversion from Euler angles
  194. float x, y, z;
  195. x = (float)strtod(ptr, &ptr);
  196. y = (float)strtod(ptr, &ptr);
  197. z = (float)strtod(ptr, &ptr);
  198. return Quaternion(x, y, z);
  199. }
  200. else
  201. {
  202. // 4 coords specified: full quaternion
  203. Quaternion ret;
  204. ret.w_ = (float)strtod(ptr, &ptr);
  205. ret.x_ = (float)strtod(ptr, &ptr);
  206. ret.y_ = (float)strtod(ptr, &ptr);
  207. ret.z_ = (float)strtod(ptr, &ptr);
  208. return ret;
  209. }
  210. }
  211. Vector2 ToVector2(const String& source)
  212. {
  213. return ToVector2(source.CString());
  214. }
  215. Vector2 ToVector2(const char* source)
  216. {
  217. Vector2 ret(Vector2::ZERO);
  218. unsigned elements = CountElements(source, ' ');
  219. if (elements < 2)
  220. return ret;
  221. char* ptr = (char*)source;
  222. ret.x_ = (float)strtod(ptr, &ptr);
  223. ret.y_ = (float)strtod(ptr, &ptr);
  224. return ret;
  225. }
  226. Vector3 ToVector3(const String& source)
  227. {
  228. return ToVector3(source.CString());
  229. }
  230. Vector3 ToVector3(const char* source)
  231. {
  232. Vector3 ret(Vector3::ZERO);
  233. unsigned elements = CountElements(source, ' ');
  234. if (elements < 3)
  235. return ret;
  236. char* ptr = (char*)source;
  237. ret.x_ = (float)strtod(ptr, &ptr);
  238. ret.y_ = (float)strtod(ptr, &ptr);
  239. ret.z_ = (float)strtod(ptr, &ptr);
  240. return ret;
  241. }
  242. Vector4 ToVector4(const String& source, bool allowMissingCoords)
  243. {
  244. return ToVector4(source.CString(), allowMissingCoords);
  245. }
  246. Vector4 ToVector4(const char* source, bool allowMissingCoords)
  247. {
  248. Vector4 ret(Vector4::ZERO);
  249. unsigned elements = CountElements(source, ' ');
  250. char* ptr = (char*)source;
  251. if (!allowMissingCoords)
  252. {
  253. if (elements < 4)
  254. return ret;
  255. ret.x_ = (float)strtod(ptr, &ptr);
  256. ret.y_ = (float)strtod(ptr, &ptr);
  257. ret.z_ = (float)strtod(ptr, &ptr);
  258. ret.w_ = (float)strtod(ptr, &ptr);
  259. return ret;
  260. }
  261. else
  262. {
  263. if (elements > 0)
  264. ret.x_ = (float)strtod(ptr, &ptr);
  265. if (elements > 1)
  266. ret.y_ = (float)strtod(ptr, &ptr);
  267. if (elements > 2)
  268. ret.z_ = (float)strtod(ptr, &ptr);
  269. if (elements > 3)
  270. ret.w_ = (float)strtod(ptr, &ptr);
  271. return ret;
  272. }
  273. }
  274. String ToString(void* value)
  275. {
  276. return ToStringHex((int)value);
  277. }
  278. String ToStringHex(unsigned value)
  279. {
  280. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  281. sprintf(tempBuffer, "%08x", value);
  282. return String(tempBuffer);
  283. }
  284. unsigned GetStringListIndex(const String& value, const String* strings, unsigned defaultIndex, bool caseSensitive)
  285. {
  286. return GetStringListIndex(value.CString(), strings, defaultIndex, caseSensitive);
  287. }
  288. unsigned GetStringListIndex(const char* value, const String* strings, unsigned defaultIndex, bool caseSensitive)
  289. {
  290. unsigned i = 0;
  291. while (!strings[i].Empty())
  292. {
  293. if (!strings[i].Compare(value, caseSensitive))
  294. return i;
  295. ++i;
  296. }
  297. return defaultIndex;
  298. }