BsString.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. /** @addtogroup String
  5. * @{
  6. */
  7. namespace BansheeEngine
  8. {
  9. /** Basic string that uses Banshee memory allocators. */
  10. template <typename T>
  11. using BasicString = std::basic_string < T, std::char_traits<T>, StdAlloc<T> > ;
  12. /** Basic string stream that uses Banshee memory allocators. */
  13. template <typename T>
  14. using BasicStringStream = std::basic_stringstream < T, std::char_traits<T>, StdAlloc<T> > ;
  15. /** Wide string used primarily for handling Unicode text. */
  16. typedef BasicString<wchar_t> WString;
  17. /** Narrow string used primarily for handling ASCII text. */
  18. typedef BasicString<char> String;
  19. /** Wide string stream used for primarily for constructing strings consisting of Unicode text. */
  20. typedef BasicStringStream<wchar_t> WStringStream;
  21. /** Wide string stream used for primarily for constructing strings consisting of ASCII text. */
  22. typedef BasicStringStream<char> StringStream;
  23. }
  24. #include "BsStringFormat.h"
  25. namespace BansheeEngine
  26. {
  27. /** Utility class for manipulating Strings. */
  28. class BS_UTILITY_EXPORT StringUtil
  29. {
  30. public:
  31. /** Removes any whitespace characters from beginning or end of the string. */
  32. static void trim(String& str, bool left = true, bool right = true);
  33. /** @copydoc StringUtil::trim(String&, bool, bool) */
  34. static void trim(WString& str, bool left = true, bool right = true);
  35. /** Removes specified characters from beginning or end of the string. */
  36. static void trim(String& str, const String& delims, bool left = true, bool right = true);
  37. /** @copydoc StringUtil::trim(String&, const String&, bool, bool) */
  38. static void trim(WString& str, const WString& delims, bool left = true, bool right = true);
  39. /**
  40. * Returns a vector of strings containing all the substrings delimited by the provided delimiter characters.
  41. *
  42. * @param[in] str The string to split.
  43. * @param[in] delims (optional) Delimiter characters to split the string by. They will not
  44. * be included in resulting substrings.
  45. * @param[in] maxSplits (optional) The maximum number of splits to perform (0 for unlimited splits). If this
  46. * parameters is > 0, the splitting process will stop after this many splits, left to right.
  47. */
  48. static Vector<String> split(const String& str, const String& delims = "\t\n ", unsigned int maxSplits = 0);
  49. /** @copydoc StringUtil::split(const String&, const String&, unsigned int) */
  50. static Vector<WString> split(const WString& str, const WString& delims = L"\t\n ", unsigned int maxSplits = 0);
  51. /**
  52. * Returns a vector of strings containing all the substrings delimited by the provided delimiter characters, or the
  53. * double delimiters used for including normal delimiter characters in the tokenized string.
  54. *
  55. * @param[in] str The string to split.
  56. * @param[in] delims (optional) Delimiter characters to split the string by. They will not
  57. * be included in resulting substrings.
  58. * @params[in] doubleDelims (optional) Delimiter character you may use to surround other normal delimiters,
  59. * in order to include them in the tokensized string.
  60. * @param[in] maxSplits (optional) The maximum number of splits to perform (0 for unlimited splits).
  61. * If this parameters is > 0, the splitting process will stop after this many splits,
  62. * left to right.
  63. */
  64. static Vector<String> tokenise(const String& str, const String& delims = "\t\n ", const String& doubleDelims = "\"", unsigned int maxSplits = 0);
  65. /** @copydoc StringUtil::tokenise(const String&, const String&, const String&, unsigned int) */
  66. static Vector<WString> tokenise(const WString& str, const WString& delims = L"\t\n ", const WString& doubleDelims = L"\"", unsigned int maxSplits = 0);
  67. /** Converts all the characters in the string to lower case. */
  68. static void toLowerCase(String& str);
  69. /** Converts all the characters in the string to lower case. */
  70. static void toLowerCase(WString& str);
  71. /** Converts all the characters in the string to upper case. */
  72. static void toUpperCase(String& str);
  73. /** Converts all the characters in the string to upper case. */
  74. static void toUpperCase(WString& str);
  75. /**
  76. * Returns whether the string begins with the pattern passed in.
  77. *
  78. * @param[in] str String to compare.
  79. * @param[in] pattern Pattern to compare with.
  80. * @param[in] lowerCase (optional) If true, the start of the string will be lower cased before comparison, and
  81. * the pattern should also be in lower case.
  82. */
  83. static bool startsWith(const String& str, const String& pattern, bool lowerCase = true);
  84. /** @copydoc startsWidth(const String&, const String&, bool) */
  85. static bool startsWith(const WString& str, const WString& pattern, bool lowerCase = true);
  86. /**
  87. * Returns whether the string end with the pattern passed in.
  88. *
  89. * @param[in] str String to compare.
  90. * @param[in] pattern Pattern to compare with.
  91. * @param[in] lowerCase (optional) If true, the start of the string will be lower cased before comparison, and
  92. * the pattern should also be in lower case.
  93. */
  94. static bool endsWith(const String& str, const String& pattern, bool lowerCase = true);
  95. /** @copydoc endsWith(const String&, const String&, bool) */
  96. static bool endsWith(const WString& str, const WString& pattern, bool lowerCase = true);
  97. /**
  98. * Returns true if the string matches the provided pattern. Pattern may use a "*" wildcard for matching any
  99. * characters.
  100. *
  101. * @param[in] str The string to test.
  102. * @param[in] pattern Patterns to look for.
  103. * @param[in] caseSensitive (optional) Should the match be case sensitive or not.
  104. */
  105. static bool match(const String& str, const String& pattern, bool caseSensitive = true);
  106. /** @copydoc match(const String&, const String&, bool) */
  107. static bool match(const WString& str, const WString& pattern, bool caseSensitive = true);
  108. /**
  109. * Replace all instances of a substring with a another substring.
  110. *
  111. * @param[in] source String to search.
  112. * @param[in] replaceWhat Substring to find and replace
  113. * @param[in] replaceWithWhat Substring to replace with (the new sub-string)
  114. *
  115. * @return An updated string with the substrings replaced.
  116. */
  117. static const String replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat);
  118. /** @copydoc replaceAll(const String&, const String&, const String&) */
  119. static const WString replaceAll(const WString& source, const WString& replaceWhat, const WString& replaceWithWhat);
  120. /**
  121. * Compares two strings. Returns 0 if the two compare equal, <0 if the value of the left string is lower than of
  122. * the right string, or >0 if the value of the left string is higher than the right string.
  123. *
  124. * @param[in] lhs Left string to compare.
  125. * @param[in] rhs Right string to compare.
  126. * @param[in] caseSensitive If true the comparison will consider uppercase and lowercase characters different.
  127. */
  128. template <class T>
  129. static int compare(const BasicString<T>& lhs, const BasicString<T>& rhs, bool caseSensitive = true)
  130. {
  131. if (caseSensitive)
  132. return (int)lhs.compare(rhs);
  133. int size = (int)std::min(lhs.size(), rhs.size());
  134. for (int i = 0; i < size; i++)
  135. {
  136. if (toupper(lhs[i]) < toupper(rhs[i])) return -1;
  137. if (toupper(lhs[i]) > toupper(rhs[i])) return 1;
  138. }
  139. return (lhs.size() < rhs.size() ? -1 : (lhs.size() == rhs.size() ? 0 : 1));
  140. }
  141. /** @copydoc StringFormat::format */
  142. template<class T, class... Args>
  143. static BasicString<T> format(const BasicString<T>& source, Args&& ...args)
  144. {
  145. return StringFormat::format(source.c_str(), std::forward<Args>(args)...);
  146. }
  147. /** @copydoc StringFormat::format */
  148. template<class T, class... Args>
  149. static BasicString<T> format(const T* source, Args&& ...args)
  150. {
  151. return StringFormat::format(source, std::forward<Args>(args)...);
  152. }
  153. /** Constant blank string, useful for returning by ref where local does not exist. */
  154. static const String BLANK;
  155. /** Constant blank wide string, useful for returning by ref where local does not exist. */
  156. static const WString WBLANK;
  157. private:
  158. template <class T>
  159. static Vector<BasicString<T>> splitInternal(const BasicString<T>& str, const BasicString<T>& delims, unsigned int maxSplits)
  160. {
  161. Vector<BasicString<T>> ret;
  162. // Pre-allocate some space for performance
  163. ret.reserve(maxSplits ? maxSplits+1 : 10); // 10 is guessed capacity for most case
  164. unsigned int numSplits = 0;
  165. // Use STL methods
  166. size_t start, pos;
  167. start = 0;
  168. do
  169. {
  170. pos = str.find_first_of(delims, start);
  171. if (pos == start)
  172. {
  173. // Do nothing
  174. start = pos + 1;
  175. }
  176. else if (pos == BasicString<T>::npos || (maxSplits && numSplits == maxSplits))
  177. {
  178. // Copy the rest of the string
  179. ret.push_back(str.substr(start));
  180. break;
  181. }
  182. else
  183. {
  184. // Copy up to delimiter
  185. ret.push_back(str.substr(start, pos - start));
  186. start = pos + 1;
  187. }
  188. // parse up to next real data
  189. start = str.find_first_not_of(delims, start);
  190. ++numSplits;
  191. } while (pos != BasicString<T>::npos);
  192. return ret;
  193. }
  194. template <class T>
  195. static Vector<BasicString<T>> tokeniseInternal(const BasicString<T>& str, const BasicString<T>& singleDelims,
  196. const BasicString<T>& doubleDelims, unsigned int maxSplits)
  197. {
  198. Vector<BasicString<T>> ret;
  199. // Pre-allocate some space for performance
  200. ret.reserve(maxSplits ? maxSplits + 1 : 10); // 10 is guessed capacity for most case
  201. unsigned int numSplits = 0;
  202. BasicString<T> delims = singleDelims + doubleDelims;
  203. // Use STL methods
  204. size_t start, pos;
  205. T curDoubleDelim = 0;
  206. start = 0;
  207. do
  208. {
  209. if (curDoubleDelim != 0)
  210. {
  211. pos = str.find(curDoubleDelim, start);
  212. }
  213. else
  214. {
  215. pos = str.find_first_of(delims, start);
  216. }
  217. if (pos == start)
  218. {
  219. T curDelim = str.at(pos);
  220. if (doubleDelims.find_first_of(curDelim) != BasicString<T>::npos)
  221. {
  222. curDoubleDelim = curDelim;
  223. }
  224. // Do nothing
  225. start = pos + 1;
  226. }
  227. else if (pos == BasicString<T>::npos || (maxSplits && numSplits == maxSplits))
  228. {
  229. if (curDoubleDelim != 0)
  230. {
  231. //Missing closer. Warn or throw exception?
  232. }
  233. // Copy the rest of the string
  234. ret.push_back( str.substr(start) );
  235. break;
  236. }
  237. else
  238. {
  239. if (curDoubleDelim != 0)
  240. {
  241. curDoubleDelim = 0;
  242. }
  243. // Copy up to delimiter
  244. ret.push_back( str.substr(start, pos - start) );
  245. start = pos + 1;
  246. }
  247. if (curDoubleDelim == 0)
  248. {
  249. // parse up to next real data
  250. start = str.find_first_not_of(singleDelims, start);
  251. }
  252. ++numSplits;
  253. } while (pos != BasicString<T>::npos);
  254. return ret;
  255. }
  256. template <class T>
  257. static bool startsWithInternal(const BasicString<T>& str, const BasicString<T>& pattern, bool lowerCase)
  258. {
  259. size_t thisLen = str.length();
  260. size_t patternLen = pattern.length();
  261. if (thisLen < patternLen || patternLen == 0)
  262. return false;
  263. BasicString<T> startOfThis = str.substr(0, patternLen);
  264. if (lowerCase)
  265. StringUtil::toLowerCase(startOfThis);
  266. return (startOfThis == pattern);
  267. }
  268. template <class T>
  269. static bool endsWithInternal(const BasicString<T>& str, const BasicString<T>& pattern, bool lowerCase)
  270. {
  271. size_t thisLen = str.length();
  272. size_t patternLen = pattern.length();
  273. if (thisLen < patternLen || patternLen == 0)
  274. return false;
  275. BasicString<T> endOfThis = str.substr(thisLen - patternLen, patternLen);
  276. if (lowerCase)
  277. StringUtil::toLowerCase(endOfThis);
  278. return (endOfThis == pattern);
  279. }
  280. template <class T>
  281. static bool matchInternal(const BasicString<T>& str, const BasicString<T>& pattern, bool caseSensitive)
  282. {
  283. BasicString<T> tmpStr = str;
  284. BasicString<T> tmpPattern = pattern;
  285. if (!caseSensitive)
  286. {
  287. StringUtil::toLowerCase(tmpStr);
  288. StringUtil::toLowerCase(tmpPattern);
  289. }
  290. BasicString<T>::const_iterator strIt = tmpStr.begin();
  291. BasicString<T>::const_iterator patIt = tmpPattern.begin();
  292. BasicString<T>::const_iterator lastWildCardIt = tmpPattern.end();
  293. while (strIt != tmpStr.end() && patIt != tmpPattern.end())
  294. {
  295. if (*patIt == '*')
  296. {
  297. lastWildCardIt = patIt;
  298. // Skip over looking for next character
  299. ++patIt;
  300. if (patIt == tmpPattern.end())
  301. {
  302. // Skip right to the end since * matches the entire rest of the string
  303. strIt = tmpStr.end();
  304. }
  305. else
  306. {
  307. // scan until we find next pattern character
  308. while(strIt != tmpStr.end() && *strIt != *patIt)
  309. ++strIt;
  310. }
  311. }
  312. else
  313. {
  314. if (*patIt != *strIt)
  315. {
  316. if (lastWildCardIt != tmpPattern.end())
  317. {
  318. // The last wildcard can match this incorrect sequence
  319. // rewind pattern to wildcard and keep searching
  320. patIt = lastWildCardIt;
  321. lastWildCardIt = tmpPattern.end();
  322. }
  323. else
  324. {
  325. // no wildwards left
  326. return false;
  327. }
  328. }
  329. else
  330. {
  331. ++patIt;
  332. ++strIt;
  333. }
  334. }
  335. }
  336. // If we reached the end of both the pattern and the string, we succeeded
  337. if (patIt == tmpPattern.end() && strIt == tmpStr.end())
  338. return true;
  339. else
  340. return false;
  341. }
  342. template <class T>
  343. static BasicString<T> replaceAllInternal(const BasicString<T>& source,
  344. const BasicString<T>& replaceWhat, const BasicString<T>& replaceWithWhat)
  345. {
  346. BasicString<T> result = source;
  347. BasicString<T>::size_type pos = 0;
  348. while(1)
  349. {
  350. pos = result.find(replaceWhat,pos);
  351. if (pos == BasicString<T>::npos) break;
  352. result.replace(pos,replaceWhat.size(), replaceWithWhat);
  353. pos += replaceWithWhat.size();
  354. }
  355. return result;
  356. }
  357. };
  358. /** Converts a narrow string to a wide string. */
  359. BS_UTILITY_EXPORT WString toWString(const String& source);
  360. /** Converts a narrow string to a wide string. */
  361. BS_UTILITY_EXPORT WString toWString(const char* source);
  362. /** Converts a float to a string. */
  363. BS_UTILITY_EXPORT WString toWString(float val, unsigned short precision = 6,
  364. unsigned short width = 0, char fill = ' ',
  365. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  366. /** Converts a double to a string. */
  367. BS_UTILITY_EXPORT WString toWString(double val, unsigned short precision = 6,
  368. unsigned short width = 0, char fill = ' ',
  369. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  370. /** Converts a Radian to a string. */
  371. BS_UTILITY_EXPORT WString toWString(Radian val, unsigned short precision = 6,
  372. unsigned short width = 0, char fill = ' ',
  373. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  374. /** Converts a Degree to a string. */
  375. BS_UTILITY_EXPORT WString toWString(Degree val, unsigned short precision = 6,
  376. unsigned short width = 0, char fill = ' ',
  377. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  378. /** Converts an int to a string. */
  379. BS_UTILITY_EXPORT WString toWString(int val, unsigned short width = 0,
  380. char fill = ' ',
  381. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  382. /** Converts an unsigned int to a string. */
  383. BS_UTILITY_EXPORT WString toWString(unsigned int val,
  384. unsigned short width = 0, char fill = ' ',
  385. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  386. /** Converts an 64bit integer to a string. */
  387. BS_UTILITY_EXPORT WString toWString(INT64 val,
  388. unsigned short width = 0, char fill = ' ',
  389. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  390. /** Converts an 64bit unsigned to a string. */
  391. BS_UTILITY_EXPORT WString toWString(UINT64 val,
  392. unsigned short width = 0, char fill = ' ',
  393. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  394. /** Converts an narrow char unsigned to a string. */
  395. BS_UTILITY_EXPORT WString toWString(char val,
  396. unsigned short width = 0, char fill = ' ',
  397. std::ios::fmtflags flags = std::ios::fmtflags(0));
  398. /** Converts an wide bit char unsigned to a string. */
  399. BS_UTILITY_EXPORT WString toWString(wchar_t val,
  400. unsigned short width = 0, char fill = ' ',
  401. std::ios::fmtflags flags = std::ios::fmtflags(0));
  402. /**
  403. * Converts a boolean to a string.
  404. *
  405. * @param[in] val Value to convert.
  406. * @param[in] yesNo (optional) If set to true, result is "yes" or "no" instead of "true" or "false".
  407. */
  408. BS_UTILITY_EXPORT WString toWString(bool val, bool yesNo = false);
  409. /**
  410. * Converts a 2 dimensional vector to a string.
  411. *
  412. * @note Format is "x y".
  413. */
  414. BS_UTILITY_EXPORT WString toWString(const Vector2& val);
  415. /**
  416. * Converts a 2 dimensional integer vector to a string.
  417. *
  418. * @note Format is "x y".
  419. */
  420. BS_UTILITY_EXPORT WString toWString(const Vector2I& val);
  421. /**
  422. * Converts a 3 dimensional vector to a string.
  423. *
  424. * @note Format is "x y z".
  425. */
  426. BS_UTILITY_EXPORT WString toWString(const Vector3& val);
  427. /**
  428. * Converts a 4 dimensional vector to a string.
  429. *
  430. * @note Format is "x y z w".
  431. */
  432. BS_UTILITY_EXPORT WString toWString(const Vector4& val);
  433. /**
  434. * Converts a 3x3 matrix to a string.
  435. *
  436. * @note Format is "00 01 02 10 11 12 20 21 22".
  437. */
  438. BS_UTILITY_EXPORT WString toWString(const Matrix3& val);
  439. /**
  440. * Converts a 4x4 matrix to a string.
  441. *
  442. * @note Format is "00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33".
  443. */
  444. BS_UTILITY_EXPORT WString toWString(const Matrix4& val);
  445. /**
  446. * Converts a Quaternion to a string.
  447. *
  448. * @note Format is "w x y z".
  449. */
  450. BS_UTILITY_EXPORT WString toWString(const Quaternion& val);
  451. /**
  452. * Converts a color to a string.
  453. *
  454. * @note Format is "r g b a".
  455. */
  456. BS_UTILITY_EXPORT WString toWString(const Color& val);
  457. /** Converts a vector of strings into a single string where the substrings are delimited by spaces. */
  458. BS_UTILITY_EXPORT WString toWString(const Vector<BansheeEngine::WString>& val);
  459. /** Converts a wide string to a narrow string. */
  460. BS_UTILITY_EXPORT String toString(const WString& source);
  461. /** Converts a wide string to a narrow string. */
  462. BS_UTILITY_EXPORT String toString(const wchar_t* source);
  463. /** Converts a float to a string. */
  464. BS_UTILITY_EXPORT String toString(float val, unsigned short precision = 6,
  465. unsigned short width = 0, char fill = ' ',
  466. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  467. /** Converts a double to a string. */
  468. BS_UTILITY_EXPORT String toString(double val, unsigned short precision = 6,
  469. unsigned short width = 0, char fill = ' ',
  470. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  471. /** Converts a Radian to a string. */
  472. BS_UTILITY_EXPORT String toString(Radian val, unsigned short precision = 6,
  473. unsigned short width = 0, char fill = ' ',
  474. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  475. /** Converts a Degree to a string. */
  476. BS_UTILITY_EXPORT String toString(Degree val, unsigned short precision = 6,
  477. unsigned short width = 0, char fill = ' ',
  478. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  479. /** Converts an int to a string. */
  480. BS_UTILITY_EXPORT String toString(int val, unsigned short width = 0,
  481. char fill = ' ',
  482. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  483. /** Converts an unsigned int to a string. */
  484. BS_UTILITY_EXPORT String toString(unsigned int val,
  485. unsigned short width = 0, char fill = ' ',
  486. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  487. /** Converts a 64bit int to a string. */
  488. BS_UTILITY_EXPORT String toString(INT64 val,
  489. unsigned short width = 0, char fill = ' ',
  490. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  491. /** Converts an 64bit unsigned int to a string. */
  492. BS_UTILITY_EXPORT String toString(UINT64 val,
  493. unsigned short width = 0, char fill = ' ',
  494. std::ios::fmtflags flags = std::ios::fmtflags(0) );
  495. /**
  496. * Converts a boolean to a string.
  497. *
  498. * @param[in] val true to value.
  499. * @param[in] yesNo (optional) If set to true, result is "yes" or "no" instead of "true" or "false".
  500. */
  501. BS_UTILITY_EXPORT String toString(bool val, bool yesNo = false);
  502. /**
  503. * Converts a 2 dimensional vector to a string.
  504. *
  505. * @note Format is "x y".
  506. */
  507. BS_UTILITY_EXPORT String toString(const Vector2& val);
  508. /**
  509. * Converts a 2 dimensional integer vector to a string.
  510. *
  511. * @note Format is "x y".
  512. */
  513. BS_UTILITY_EXPORT String toString(const Vector2I& val);
  514. /**
  515. * Converts a 3 dimensional vector to a string.
  516. *
  517. * @note Format is "x y z".
  518. */
  519. BS_UTILITY_EXPORT String toString(const Vector3& val);
  520. /**
  521. * Converts a 4 dimensional vector to a string.
  522. *
  523. * @note Format is "x y z w".
  524. */
  525. BS_UTILITY_EXPORT String toString(const Vector4& val);
  526. /**
  527. * Converts a 3x3 matrix to a string.
  528. *
  529. * @note Format is "00 01 02 10 11 12 20 21 22".
  530. */
  531. BS_UTILITY_EXPORT String toString(const Matrix3& val);
  532. /**
  533. * Converts a 4x4 matrix to a string.
  534. *
  535. * @note Format is "00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33".
  536. */
  537. BS_UTILITY_EXPORT String toString(const Matrix4& val);
  538. /**
  539. * Converts a Quaternion to a string.
  540. *
  541. * @note Format is "w x y z".
  542. */
  543. BS_UTILITY_EXPORT String toString(const Quaternion& val);
  544. /**
  545. * Converts a color to a string.
  546. *
  547. * @note Format is "r g b a".
  548. */
  549. BS_UTILITY_EXPORT String toString(const Color& val);
  550. /**
  551. * Converts a vector of strings into a single string where the substrings are delimited by spaces.
  552. */
  553. BS_UTILITY_EXPORT String toString(const Vector<BansheeEngine::String>& val);
  554. /**
  555. * Converts a String to a float.
  556. *
  557. * @note 0.0f if the value could not be parsed, otherwise the numeric version of the string.
  558. */
  559. BS_UTILITY_EXPORT float parseFloat(const String& val, float defaultValue = 0);
  560. /**
  561. * Converts a String to a whole number.
  562. *
  563. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  564. */
  565. BS_UTILITY_EXPORT INT32 parseINT32(const String& val, INT32 defaultValue = 0);
  566. /**
  567. * Converts a String to a whole number.
  568. *
  569. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  570. */
  571. BS_UTILITY_EXPORT UINT32 parseUINT32(const String& val, UINT32 defaultValue = 0);
  572. /**
  573. * Converts a String to a whole number.
  574. *
  575. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  576. */
  577. BS_UTILITY_EXPORT INT64 parseINT64(const String& val, INT64 defaultValue = 0);
  578. /**
  579. * Converts a String to a whole number.
  580. *
  581. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  582. */
  583. BS_UTILITY_EXPORT UINT64 parseUINT64(const String& val, UINT64 defaultValue = 0);
  584. /**
  585. * Converts a String to a boolean.
  586. *
  587. * @note Returns true if case-insensitive match of the start of the string matches "true", "yes" or "1",
  588. * false otherwise.
  589. */
  590. BS_UTILITY_EXPORT bool parseBool(const String& val, bool defaultValue = 0);
  591. /** Checks the String is a valid number value. */
  592. BS_UTILITY_EXPORT bool isNumber(const String& val);
  593. /**
  594. * Converts a WString to a float.
  595. *
  596. * @note 0.0f if the value could not be parsed, otherwise the numeric version of the string.
  597. */
  598. BS_UTILITY_EXPORT float parseFloat(const WString& val, float defaultValue = 0);
  599. /**
  600. * Converts a WString to a whole number.
  601. *
  602. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  603. */
  604. BS_UTILITY_EXPORT INT32 parseINT32(const WString& val, INT32 defaultValue = 0);
  605. /**
  606. * Converts a WString to a whole number.
  607. *
  608. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  609. */
  610. BS_UTILITY_EXPORT UINT32 parseUINT32(const WString& val, UINT32 defaultValue = 0);
  611. /**
  612. * Converts a WString to a whole number.
  613. *
  614. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  615. */
  616. BS_UTILITY_EXPORT INT64 parseINT64(const WString& val, INT64 defaultValue = 0);
  617. /**
  618. * Converts a WString to a whole number.
  619. *
  620. * @note 0 if the value could not be parsed, otherwise the numeric version of the string.
  621. */
  622. BS_UTILITY_EXPORT UINT64 parseUINT64(const WString& val, UINT64 defaultValue = 0);
  623. /**
  624. * Converts a WString to a boolean.
  625. *
  626. * @note Returns true if case-insensitive match of the start of the string
  627. * matches "true", "yes" or "1", false otherwise.
  628. */
  629. BS_UTILITY_EXPORT bool parseBool(const WString& val, bool defaultValue = 0);
  630. /**
  631. * Checks the WString is a valid number value.
  632. */
  633. BS_UTILITY_EXPORT bool isNumber(const WString& val);
  634. /** @cond INTERNAL */
  635. /** Helper method that throws an exception regarding a data overflow. */
  636. void BS_UTILITY_EXPORT __string_throwDataOverflowException();
  637. /** @endcond */
  638. /** @cond SPECIALIZATIONS */
  639. /**
  640. * RTTIPlainType specialization for String that allows strings be serialized as value types.
  641. *
  642. * @see RTTIPlainType
  643. */
  644. template<> struct RTTIPlainType<String>
  645. {
  646. enum { id = 20 }; enum { hasDynamicSize = 1 };
  647. static void toMemory(const String& data, char* memory)
  648. {
  649. UINT32 size = getDynamicSize(data);
  650. memcpy(memory, &size, sizeof(UINT32));
  651. memory += sizeof(UINT32);
  652. size -= sizeof(UINT32);
  653. memcpy(memory, data.data(), size);
  654. }
  655. static UINT32 fromMemory(String& data, char* memory)
  656. {
  657. UINT32 size;
  658. memcpy(&size, memory, sizeof(UINT32));
  659. memory += sizeof(UINT32);
  660. UINT32 stringSize = size - sizeof(UINT32);
  661. char* buffer = (char*)bs_alloc(stringSize + 1);
  662. memcpy(buffer, memory, stringSize);
  663. buffer[stringSize] = '\0';
  664. data = String(buffer);
  665. bs_free(buffer);
  666. return size;
  667. }
  668. static UINT32 getDynamicSize(const String& data)
  669. {
  670. UINT64 dataSize = data.size() * sizeof(String::value_type) + sizeof(UINT32);
  671. #if BS_DEBUG_MODE
  672. if(dataSize > std::numeric_limits<UINT32>::max())
  673. {
  674. __string_throwDataOverflowException();
  675. }
  676. #endif
  677. return (UINT32)dataSize;
  678. }
  679. };
  680. /**
  681. * RTTIPlainType specialization for WString that allows strings be serialized as value types.
  682. *
  683. * @see RTTIPlainType
  684. */
  685. template<> struct RTTIPlainType<WString>
  686. {
  687. enum { id = TID_WString }; enum { hasDynamicSize = 1 };
  688. static void toMemory(const WString& data, char* memory)
  689. {
  690. UINT32 size = getDynamicSize(data);
  691. memcpy(memory, &size, sizeof(UINT32));
  692. memory += sizeof(UINT32);
  693. size -= sizeof(UINT32);
  694. memcpy(memory, data.data(), size);
  695. }
  696. static UINT32 fromMemory(WString& data, char* memory)
  697. {
  698. UINT32 size;
  699. memcpy(&size, memory, sizeof(UINT32));
  700. memory += sizeof(UINT32);
  701. UINT32 stringSize = size - sizeof(UINT32);
  702. WString::value_type* buffer = (WString::value_type*)bs_alloc(stringSize + sizeof(WString::value_type));
  703. memcpy(buffer, memory, stringSize);
  704. UINT32 numChars = stringSize / sizeof(WString::value_type);
  705. buffer[numChars] = L'\0';
  706. data = WString(buffer);
  707. bs_free(buffer);
  708. return size;
  709. }
  710. static UINT32 getDynamicSize(const WString& data)
  711. {
  712. UINT64 dataSize = data.size() * sizeof(WString::value_type) + sizeof(UINT32);
  713. #if BS_DEBUG_MODE
  714. if(dataSize > std::numeric_limits<UINT32>::max())
  715. {
  716. __string_throwDataOverflowException();
  717. }
  718. #endif
  719. return (UINT32)dataSize;
  720. }
  721. };
  722. /** @endcond */
  723. }
  724. /** @cond STDLIB */
  725. /** Hash value generator for String. */
  726. template<>
  727. struct std::hash<BansheeEngine::String>
  728. {
  729. size_t operator()(const BansheeEngine::String& string) const
  730. {
  731. size_t hash = 0;
  732. for(size_t i = 0; i < string.size(); i++)
  733. hash = 65599 * hash + string[i];
  734. return hash ^ (hash >> 16);
  735. }
  736. };
  737. /** Hash value generator for WString. */
  738. template<>
  739. struct std::hash<BansheeEngine::WString>
  740. {
  741. size_t operator()(const BansheeEngine::WString& string) const
  742. {
  743. size_t hash = 0;
  744. for(size_t i = 0; i < string.size(); i++)
  745. hash = 65599 * hash + string[i];
  746. return hash ^ (hash >> 16);
  747. }
  748. };
  749. /** @endcond */
  750. /** @} */