StringUtils.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 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. static const int TEMP_BUFFER_LENGTH = 128;
  29. Vector<String> Split(const String& source, char separator)
  30. {
  31. Vector<String> ret;
  32. unsigned pos = 0;
  33. while (pos < source.Length())
  34. {
  35. unsigned start = pos;
  36. while (start < source.Length())
  37. {
  38. if (source[start] == separator)
  39. break;
  40. start++;
  41. }
  42. if (start == source.Length())
  43. {
  44. ret.Push(source.Substring(pos));
  45. break;
  46. }
  47. unsigned end = start;
  48. while (end < source.Length())
  49. {
  50. if (source[end] != separator)
  51. break;
  52. end++;
  53. }
  54. ret.Push(source.Substring(pos, start - pos));
  55. pos = end;
  56. }
  57. return ret;
  58. }
  59. bool ToBool(const String& source)
  60. {
  61. String temp = source.ToLower();
  62. if (temp.Find("true") != String::NPOS)
  63. return true;
  64. else
  65. return false;
  66. }
  67. int ToInt(const String& source)
  68. {
  69. if (!source.Length())
  70. return 0;
  71. return atoi(source.CString());
  72. }
  73. unsigned ToUInt(const String& source)
  74. {
  75. if (!source.Length())
  76. return 0;
  77. return (unsigned)atoi(source.CString());
  78. }
  79. float ToFloat(const String& source)
  80. {
  81. if (!source.Length())
  82. return 0.0f;
  83. return (float)atof(source.CString());
  84. }
  85. Color ToColor(const String& source)
  86. {
  87. Vector<String> colors = Split(source, ' ');
  88. if (colors.Size() < 3)
  89. return Color();
  90. Color ret(ToFloat(colors[0]), ToFloat(colors[1]), ToFloat(colors[2]));
  91. if (colors.Size() > 3)
  92. ret.a_ = ToFloat(colors[3]);
  93. return ret;
  94. }
  95. IntRect ToIntRect(const String& source)
  96. {
  97. Vector<String> coords = Split(source, ' ');
  98. if (coords.Size() < 4)
  99. return IntRect::ZERO;
  100. else
  101. return IntRect(ToInt(coords[0]), ToInt(coords[1]), ToInt(coords[2]), ToInt(coords[3]));
  102. }
  103. IntVector2 ToIntVector2(const String& source)
  104. {
  105. Vector<String> coords = Split(source, ' ');
  106. if (coords.Size() < 2)
  107. return IntVector2::ZERO;
  108. else
  109. return IntVector2(ToInt(coords[0]), ToInt(coords[1]));
  110. }
  111. Rect ToRect(const String& source)
  112. {
  113. Vector<String> coords = Split(source, ' ');
  114. if (coords.Size() < 4)
  115. return Rect::ZERO;
  116. else
  117. return Rect(ToFloat(coords[0]), ToFloat(coords[1]), ToFloat(coords[2]), ToFloat(coords[3]));
  118. }
  119. Quaternion ToQuaternion(const String& source)
  120. {
  121. Vector<String> coords = Split(source, ' ');
  122. if (coords.Size() < 3)
  123. return Quaternion::IDENTITY;
  124. else if (coords.Size() < 4)
  125. // 3 coords specified: conversion from Euler angles
  126. return Quaternion(ToFloat(coords[0]), ToFloat(coords[1]), ToFloat(coords[2]));
  127. else
  128. // 4 coords specified: full quaternion
  129. return Quaternion(ToFloat(coords[0]), ToFloat(coords[1]), ToFloat(coords[2]), ToFloat(coords[3])).GetNormalized();
  130. }
  131. Vector2 ToVector2(const String& source)
  132. {
  133. Vector<String> coords = Split(source, ' ');
  134. if (coords.Size() < 2)
  135. return Vector2::ZERO;
  136. else
  137. return Vector2(ToFloat(coords[0]), ToFloat(coords[1]));
  138. }
  139. Vector3 ToVector3(const String& source)
  140. {
  141. Vector<String> coords = Split(source, ' ');
  142. if (coords.Size() < 3)
  143. return Vector3::ZERO;
  144. else
  145. return Vector3(ToFloat(coords[0]), ToFloat(coords[1]), ToFloat(coords[2]));
  146. }
  147. Vector4 ToVector4(const String& source, bool allowMissingCoords)
  148. {
  149. Vector<String> coords = Split(source, ' ');
  150. if (!allowMissingCoords)
  151. {
  152. if (coords.Size() < 4)
  153. return Vector4::ZERO;
  154. return Vector4(ToFloat(coords[0]), ToFloat(coords[1]), ToFloat(coords[2]), ToFloat(coords[3]));
  155. }
  156. else
  157. {
  158. unsigned num = coords.Size();
  159. Vector4 ret(Vector4::ZERO);
  160. if (num > 0)
  161. ret.x_ = ToFloat(coords[0]);
  162. if (num > 1)
  163. ret.y_ = ToFloat(coords[1]);
  164. if (num > 2)
  165. ret.z_ = ToFloat(coords[2]);
  166. if (num > 3)
  167. ret.w_ = ToFloat(coords[3]);
  168. return ret;
  169. }
  170. }
  171. String ToString(bool value)
  172. {
  173. if (value)
  174. return "true";
  175. else
  176. return "false";
  177. }
  178. String ToString(float value)
  179. {
  180. char tempBuffer[TEMP_BUFFER_LENGTH];
  181. sprintf(tempBuffer, "%g", value);
  182. return String(tempBuffer);
  183. }
  184. String ToString(int value)
  185. {
  186. char tempBuffer[TEMP_BUFFER_LENGTH];
  187. sprintf(tempBuffer, "%d", value);
  188. return String(tempBuffer);
  189. }
  190. String ToString(unsigned value)
  191. {
  192. char tempBuffer[TEMP_BUFFER_LENGTH];
  193. sprintf(tempBuffer, "%u", value);
  194. return String(tempBuffer);
  195. }
  196. String ToString(const Color& value)
  197. {
  198. char tempBuffer[TEMP_BUFFER_LENGTH];
  199. sprintf(tempBuffer, "%g %g %g %g", value.r_, value.g_, value.b_, value.a_);
  200. return String(tempBuffer);
  201. }
  202. String ToString(const IntRect& value)
  203. {
  204. char tempBuffer[TEMP_BUFFER_LENGTH];
  205. sprintf(tempBuffer, "%d %d %d &d", value.left_, value.top_, value.right_, value.bottom_);
  206. return String(tempBuffer);
  207. }
  208. String ToString(const IntVector2& value)
  209. {
  210. char tempBuffer[TEMP_BUFFER_LENGTH];
  211. sprintf(tempBuffer, "%d %d", value.x_, value.y_);
  212. return String(tempBuffer);
  213. }
  214. String ToString(const Rect& value)
  215. {
  216. char tempBuffer[TEMP_BUFFER_LENGTH];
  217. sprintf(tempBuffer, "%g %g %g %g", value.min_.x_, value.min_.y_, value.max_.x_, value.max_.y_);
  218. return String(tempBuffer);
  219. }
  220. String ToString(const Quaternion& value)
  221. {
  222. char tempBuffer[TEMP_BUFFER_LENGTH];
  223. sprintf(tempBuffer, "%g %g %g %g", value.w_, value.x_, value.y_, value.z_);
  224. return String(tempBuffer);
  225. }
  226. String ToString(const StringHash& value)
  227. {
  228. char tempBuffer[TEMP_BUFFER_LENGTH];
  229. sprintf(tempBuffer, "%08X", value.GetValue());
  230. return String(tempBuffer);
  231. }
  232. String ToString(const ShortStringHash& value)
  233. {
  234. char tempBuffer[TEMP_BUFFER_LENGTH];
  235. sprintf(tempBuffer, "%04X", value.GetValue());
  236. return String(tempBuffer);
  237. }
  238. String ToString(const Vector2& value)
  239. {
  240. char tempBuffer[TEMP_BUFFER_LENGTH];
  241. sprintf(tempBuffer, "%g %g", value.x_, value.y_);
  242. return String(tempBuffer);
  243. }
  244. String ToString(const Vector3& value)
  245. {
  246. char tempBuffer[TEMP_BUFFER_LENGTH];
  247. sprintf(tempBuffer, "%g %g %g", value.x_, value.y_, value.z_);
  248. return String(tempBuffer);
  249. }
  250. String ToString(const Vector4& value)
  251. {
  252. char tempBuffer[TEMP_BUFFER_LENGTH];
  253. sprintf(tempBuffer, "%g %g %g %g", value.x_, value.y_, value.z_, value.w_);
  254. return String(tempBuffer);
  255. }
  256. String ToString(void* value)
  257. {
  258. return ToStringHex((int)value);
  259. }
  260. String ToStringHex(unsigned value)
  261. {
  262. char tempBuffer[TEMP_BUFFER_LENGTH];
  263. sprintf(tempBuffer, "%08x", value);
  264. return String(tempBuffer);
  265. }
  266. unsigned GetStringListIndex(const String& value, const String* strings, unsigned count, unsigned defaultIndex,
  267. bool caseSensitive)
  268. {
  269. if (caseSensitive)
  270. {
  271. for (unsigned i = 0; i < count; ++i)
  272. {
  273. if (value == strings[i])
  274. return i;
  275. }
  276. }
  277. else
  278. {
  279. String valueLower = value.ToLower();
  280. for (unsigned i = 0; i < count; ++i)
  281. {
  282. /// \todo Write an insensitive compare function instead of creating new strings
  283. if (valueLower == strings[i].ToLower())
  284. return i;
  285. }
  286. }
  287. return defaultIndex;
  288. }