BsString.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. //__________________________ Banshee Project - A modern game development toolkit _________________________________//
  2. //_____________________________________ www.banshee-project.com __________________________________________________//
  3. //________________________ Copyright (c) 2014 Marko Pintera. All rights reserved. ________________________________//
  4. #include "BsString.h"
  5. #include "BsColor.h"
  6. #include "BsMath.h"
  7. #include "BsMatrix3.h"
  8. #include "BsMatrix4.h"
  9. #include "BsQuaternion.h"
  10. #include "BsVector2.h"
  11. #include "BsVector3.h"
  12. #include "BsVector4.h"
  13. #include "BsException.h"
  14. namespace BansheeEngine
  15. {
  16. const String StringUtil::BLANK;
  17. const WString StringUtil::WBLANK;
  18. void StringUtil::trim(String& str, bool left, bool right)
  19. {
  20. static const String delims = " \t\r";
  21. trim(str, delims, left, right);
  22. }
  23. void StringUtil::trim(WString& str, bool left, bool right)
  24. {
  25. static const WString delims = L" \t\r";
  26. trim(str, delims, left, right);
  27. }
  28. void StringUtil::trim(String& str, const String& delims, bool left, bool right)
  29. {
  30. if(right)
  31. str.erase(str.find_last_not_of(delims)+1); // trim right
  32. if(left)
  33. str.erase(0, str.find_first_not_of(delims)); // trim left
  34. }
  35. void StringUtil::trim(WString& str, const WString& delims, bool left, bool right)
  36. {
  37. if(right)
  38. str.erase(str.find_last_not_of(delims)+1); // trim right
  39. if(left)
  40. str.erase(0, str.find_first_not_of(delims)); // trim left
  41. }
  42. Vector<String> StringUtil::split(const String& str, const String& delims, unsigned int maxSplits)
  43. {
  44. return splitInternal<char>(str, delims, maxSplits);
  45. }
  46. Vector<WString> StringUtil::split(const WString& str, const WString& delims, unsigned int maxSplits)
  47. {
  48. return splitInternal<wchar_t>(str, delims, maxSplits);
  49. }
  50. Vector<String> StringUtil::tokenise(const String& str, const String& singleDelims, const String& doubleDelims, unsigned int maxSplits)
  51. {
  52. return tokeniseInternal<char>(str, singleDelims, doubleDelims, maxSplits);
  53. }
  54. Vector<WString> StringUtil::tokenise(const WString& str, const WString& singleDelims, const WString& doubleDelims, unsigned int maxSplits)
  55. {
  56. return tokeniseInternal<wchar_t>(str, singleDelims, doubleDelims, maxSplits);
  57. }
  58. void StringUtil::toLowerCase(String& str)
  59. {
  60. std::transform(str.begin(), str.end(), str.begin(), tolower);
  61. }
  62. void StringUtil::toLowerCase(WString& str)
  63. {
  64. std::transform(str.begin(), str.end(), str.begin(), tolower);
  65. }
  66. void StringUtil::toUpperCase(String& str)
  67. {
  68. std::transform(str.begin(), str.end(), str.begin(), toupper);
  69. }
  70. void StringUtil::toUpperCase(WString& str)
  71. {
  72. std::transform(str.begin(), str.end(), str.begin(), toupper);
  73. }
  74. bool StringUtil::startsWith(const String& str, const String& pattern, bool lowerCase)
  75. {
  76. return startsWithInternal<char>(str, pattern, lowerCase);
  77. }
  78. bool StringUtil::startsWith(const WString& str, const WString& pattern, bool lowerCase)
  79. {
  80. return startsWithInternal<wchar_t>(str, pattern, lowerCase);
  81. }
  82. bool StringUtil::endsWith(const String& str, const String& pattern, bool lowerCase)
  83. {
  84. return endsWithInternal<char>(str, pattern, lowerCase);
  85. }
  86. bool StringUtil::endsWith(const WString& str, const WString& pattern, bool lowerCase)
  87. {
  88. return endsWithInternal<wchar_t>(str, pattern, lowerCase);
  89. }
  90. bool StringUtil::match(const String& str, const String& pattern, bool caseSensitive)
  91. {
  92. return matchInternal<char>(str, pattern, caseSensitive);
  93. }
  94. bool StringUtil::match(const WString& str, const WString& pattern, bool caseSensitive)
  95. {
  96. return matchInternal<wchar_t>(str, pattern, caseSensitive);
  97. }
  98. const String StringUtil::replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat)
  99. {
  100. return replaceAllInternal<char>(source, replaceWhat, replaceWithWhat);
  101. }
  102. const WString StringUtil::replaceAll(const WString& source, const WString& replaceWhat, const WString& replaceWithWhat)
  103. {
  104. return replaceAllInternal<wchar_t>(source, replaceWhat, replaceWithWhat);
  105. }
  106. /************************************************************************/
  107. /* VARIOUS TO STRING CONVERSIONS */
  108. /************************************************************************/
  109. WString toWString(const String& source)
  110. {
  111. return WString(source.begin(), source.end());
  112. }
  113. WString toWString(float val, unsigned short precision,
  114. unsigned short width, char fill, std::ios::fmtflags flags)
  115. {
  116. WStringStream stream;
  117. stream.precision(precision);
  118. stream.width(width);
  119. stream.fill(fill);
  120. if (flags)
  121. stream.setf(flags);
  122. stream << val;
  123. return stream.str();
  124. }
  125. WString toWString(double val, unsigned short precision,
  126. unsigned short width, char fill, std::ios::fmtflags flags)
  127. {
  128. WStringStream stream;
  129. stream.precision(precision);
  130. stream.width(width);
  131. stream.fill(fill);
  132. if (flags)
  133. stream.setf(flags);
  134. stream << val;
  135. return stream.str();
  136. }
  137. WString toWString(Radian val, unsigned short precision,
  138. unsigned short width, char fill, std::ios::fmtflags flags)
  139. {
  140. return toWString(val.valueRadians(), precision, width, fill, flags);
  141. }
  142. WString toWString(Degree val, unsigned short precision,
  143. unsigned short width, char fill, std::ios::fmtflags flags)
  144. {
  145. return toWString(val.valueDegrees(), precision, width, fill, flags);
  146. }
  147. WString toWString(int val,
  148. unsigned short width, char fill, std::ios::fmtflags flags)
  149. {
  150. WStringStream stream;
  151. stream.width(width);
  152. stream.fill(fill);
  153. if (flags)
  154. stream.setf(flags);
  155. stream << val;
  156. return stream.str();
  157. }
  158. WString toWString(unsigned int val, unsigned short width, char fill, std::ios::fmtflags flags)
  159. {
  160. WStringStream stream;
  161. stream.width(width);
  162. stream.fill(fill);
  163. if (flags)
  164. stream.setf(flags);
  165. stream << val;
  166. return stream.str();
  167. }
  168. WString toWString(long val,
  169. unsigned short width, char fill, std::ios::fmtflags flags)
  170. {
  171. WStringStream stream;
  172. stream.width(width);
  173. stream.fill(fill);
  174. if (flags)
  175. stream.setf(flags);
  176. stream << val;
  177. return stream.str();
  178. }
  179. WString toWString(unsigned long val, unsigned short width, char fill, std::ios::fmtflags flags)
  180. {
  181. WStringStream stream;
  182. stream.width(width);
  183. stream.fill(fill);
  184. if (flags)
  185. stream.setf(flags);
  186. stream << val;
  187. return stream.str();
  188. }
  189. WString toWString(INT64 val, unsigned short width, char fill, std::ios::fmtflags flags)
  190. {
  191. WStringStream stream;
  192. stream.width(width);
  193. stream.fill(fill);
  194. if (flags)
  195. stream.setf(flags);
  196. stream << val;
  197. return stream.str();
  198. }
  199. WString toWString(UINT64 val, unsigned short width, char fill, std::ios::fmtflags flags)
  200. {
  201. WStringStream stream;
  202. stream.width(width);
  203. stream.fill(fill);
  204. if (flags)
  205. stream.setf(flags);
  206. stream << val;
  207. return stream.str();
  208. }
  209. WString toWString(char val, unsigned short width, char fill, std::ios::fmtflags flags)
  210. {
  211. WStringStream stream;
  212. stream.width(width);
  213. stream.fill(fill);
  214. if (flags)
  215. stream.setf(flags);
  216. stream << val;
  217. return stream.str();
  218. }
  219. WString toWString(wchar_t val, unsigned short width, char fill, std::ios::fmtflags flags)
  220. {
  221. WStringStream stream;
  222. stream.width(width);
  223. stream.fill(fill);
  224. if (flags)
  225. stream.setf(flags);
  226. stream << val;
  227. return stream.str();
  228. }
  229. WString toWString(const Vector2& val)
  230. {
  231. WStringStream stream;
  232. stream << val.x << L" " << val.y;
  233. return stream.str();
  234. }
  235. WString toWString(const Vector3& val)
  236. {
  237. WStringStream stream;
  238. stream << val.x << L" " << val.y << L" " << val.z;
  239. return stream.str();
  240. }
  241. WString toWString(const Vector4& val)
  242. {
  243. WStringStream stream;
  244. stream << val.x << L" " << val.y << L" " << val.z << L" " << val.w;
  245. return stream.str();
  246. }
  247. WString toWString(const Matrix3& val)
  248. {
  249. WStringStream stream;
  250. stream << val[0][0] << L" "
  251. << val[0][1] << L" "
  252. << val[0][2] << L" "
  253. << val[1][0] << L" "
  254. << val[1][1] << L" "
  255. << val[1][2] << L" "
  256. << val[2][0] << L" "
  257. << val[2][1] << L" "
  258. << val[2][2];
  259. return stream.str();
  260. }
  261. WString toWString(bool val, bool yesNo)
  262. {
  263. if (val)
  264. {
  265. if (yesNo)
  266. {
  267. return L"yes";
  268. }
  269. else
  270. {
  271. return L"true";
  272. }
  273. }
  274. else
  275. if (yesNo)
  276. {
  277. return L"no";
  278. }
  279. else
  280. {
  281. return L"false";
  282. }
  283. }
  284. WString toWString(const Matrix4& val)
  285. {
  286. WStringStream stream;
  287. stream << val[0][0] << L" "
  288. << val[0][1] << L" "
  289. << val[0][2] << L" "
  290. << val[0][3] << L" "
  291. << val[1][0] << L" "
  292. << val[1][1] << L" "
  293. << val[1][2] << L" "
  294. << val[1][3] << L" "
  295. << val[2][0] << L" "
  296. << val[2][1] << L" "
  297. << val[2][2] << L" "
  298. << val[2][3] << L" "
  299. << val[3][0] << L" "
  300. << val[3][1] << L" "
  301. << val[3][2] << L" "
  302. << val[3][3];
  303. return stream.str();
  304. }
  305. WString toWString(const Quaternion& val)
  306. {
  307. WStringStream stream;
  308. stream << val.w << L" " << val.x << L" " << val.y << L" " << val.z;
  309. return stream.str();
  310. }
  311. WString toWString(const Color& val)
  312. {
  313. WStringStream stream;
  314. stream << val.r << L" " << val.g << L" " << val.b << L" " << val.a;
  315. return stream.str();
  316. }
  317. WString toWString(const Vector<BansheeEngine::WString>& val)
  318. {
  319. WStringStream stream;
  320. Vector<BansheeEngine::WString>::const_iterator i, iend, ibegin;
  321. ibegin = val.begin();
  322. iend = val.end();
  323. for (i = ibegin; i != iend; ++i)
  324. {
  325. if (i != ibegin)
  326. stream << L" ";
  327. stream << *i;
  328. }
  329. return stream.str();
  330. }
  331. String toString(const WString& source)
  332. {
  333. return String(source.begin(), source.end());
  334. }
  335. String toString(float val, unsigned short precision,
  336. unsigned short width, char fill, std::ios::fmtflags flags)
  337. {
  338. StringStream stream;
  339. stream.precision(precision);
  340. stream.width(width);
  341. stream.fill(fill);
  342. if (flags)
  343. stream.setf(flags);
  344. stream << val;
  345. return stream.str();
  346. }
  347. String toString(double val, unsigned short precision,
  348. unsigned short width, char fill, std::ios::fmtflags flags)
  349. {
  350. StringStream stream;
  351. stream.precision(precision);
  352. stream.width(width);
  353. stream.fill(fill);
  354. if (flags)
  355. stream.setf(flags);
  356. stream << val;
  357. return stream.str();
  358. }
  359. String toString(Radian val, unsigned short precision,
  360. unsigned short width, char fill, std::ios::fmtflags flags)
  361. {
  362. return toString(val.valueRadians(), precision, width, fill, flags);
  363. }
  364. String toString(Degree val, unsigned short precision,
  365. unsigned short width, char fill, std::ios::fmtflags flags)
  366. {
  367. return toString(val.valueDegrees(), precision, width, fill, flags);
  368. }
  369. String toString(int val,
  370. unsigned short width, char fill, std::ios::fmtflags flags)
  371. {
  372. StringStream stream;
  373. stream.width(width);
  374. stream.fill(fill);
  375. if (flags)
  376. stream.setf(flags);
  377. stream << val;
  378. return stream.str();
  379. }
  380. String toString(unsigned int val, unsigned short width, char fill, std::ios::fmtflags flags)
  381. {
  382. StringStream stream;
  383. stream.width(width);
  384. stream.fill(fill);
  385. if (flags)
  386. stream.setf(flags);
  387. stream << val;
  388. return stream.str();
  389. }
  390. String toString(long val,
  391. unsigned short width, char fill, std::ios::fmtflags flags)
  392. {
  393. StringStream stream;
  394. stream.width(width);
  395. stream.fill(fill);
  396. if (flags)
  397. stream.setf(flags);
  398. stream << val;
  399. return stream.str();
  400. }
  401. String toString(unsigned long val, unsigned short width, char fill, std::ios::fmtflags flags)
  402. {
  403. StringStream stream;
  404. stream.width(width);
  405. stream.fill(fill);
  406. if (flags)
  407. stream.setf(flags);
  408. stream << val;
  409. return stream.str();
  410. }
  411. String toString(INT64 val,
  412. unsigned short width, char fill, std::ios::fmtflags flags)
  413. {
  414. StringStream stream;
  415. stream.width(width);
  416. stream.fill(fill);
  417. if (flags)
  418. stream.setf(flags);
  419. stream << val;
  420. return stream.str();
  421. }
  422. String toString(UINT64 val, unsigned short width, char fill, std::ios::fmtflags flags)
  423. {
  424. StringStream stream;
  425. stream.width(width);
  426. stream.fill(fill);
  427. if (flags)
  428. stream.setf(flags);
  429. stream << val;
  430. return stream.str();
  431. }
  432. String toString(const Vector2& val)
  433. {
  434. StringStream stream;
  435. stream << val.x << " " << val.y;
  436. return stream.str();
  437. }
  438. String toString(const Vector3& val)
  439. {
  440. StringStream stream;
  441. stream << val.x << " " << val.y << " " << val.z;
  442. return stream.str();
  443. }
  444. String toString(const Vector4& val)
  445. {
  446. StringStream stream;
  447. stream << val.x << " " << val.y << " " << val.z << " " << val.w;
  448. return stream.str();
  449. }
  450. String toString(const Matrix3& val)
  451. {
  452. StringStream stream;
  453. stream << val[0][0] << " "
  454. << val[0][1] << " "
  455. << val[0][2] << " "
  456. << val[1][0] << " "
  457. << val[1][1] << " "
  458. << val[1][2] << " "
  459. << val[2][0] << " "
  460. << val[2][1] << " "
  461. << val[2][2];
  462. return stream.str();
  463. }
  464. String toString(bool val, bool yesNo)
  465. {
  466. if (val)
  467. {
  468. if (yesNo)
  469. {
  470. return "yes";
  471. }
  472. else
  473. {
  474. return "true";
  475. }
  476. }
  477. else
  478. if (yesNo)
  479. {
  480. return "no";
  481. }
  482. else
  483. {
  484. return "false";
  485. }
  486. }
  487. String toString(const Matrix4& val)
  488. {
  489. StringStream stream;
  490. stream << val[0][0] << " "
  491. << val[0][1] << " "
  492. << val[0][2] << " "
  493. << val[0][3] << " "
  494. << val[1][0] << " "
  495. << val[1][1] << " "
  496. << val[1][2] << " "
  497. << val[1][3] << " "
  498. << val[2][0] << " "
  499. << val[2][1] << " "
  500. << val[2][2] << " "
  501. << val[2][3] << " "
  502. << val[3][0] << " "
  503. << val[3][1] << " "
  504. << val[3][2] << " "
  505. << val[3][3];
  506. return stream.str();
  507. }
  508. String toString(const Quaternion& val)
  509. {
  510. StringStream stream;
  511. stream << val.w << " " << val.x << " " << val.y << " " << val.z;
  512. return stream.str();
  513. }
  514. String toString(const Color& val)
  515. {
  516. StringStream stream;
  517. stream << val.r << " " << val.g << " " << val.b << " " << val.a;
  518. return stream.str();
  519. }
  520. String toString(const Vector<BansheeEngine::String>& val)
  521. {
  522. StringStream stream;
  523. Vector<BansheeEngine::String>::const_iterator i, iend, ibegin;
  524. ibegin = val.begin();
  525. iend = val.end();
  526. for (i = ibegin; i != iend; ++i)
  527. {
  528. if (i != ibegin)
  529. stream << " ";
  530. stream << *i;
  531. }
  532. return stream.str();
  533. }
  534. float parseFloat(const String& val, float defaultValue)
  535. {
  536. // Use istringstream for direct correspondence with toString
  537. StringStream str(val);
  538. float ret = defaultValue;
  539. str >> ret;
  540. return ret;
  541. }
  542. int parseInt(const String& val, int defaultValue)
  543. {
  544. // Use istringstream for direct correspondence with toString
  545. StringStream str(val);
  546. int ret = defaultValue;
  547. str >> ret;
  548. return ret;
  549. }
  550. unsigned int parseUnsignedInt(const String& val, unsigned int defaultValue)
  551. {
  552. // Use istringstream for direct correspondence with toString
  553. StringStream str(val);
  554. unsigned int ret = defaultValue;
  555. str >> ret;
  556. return ret;
  557. }
  558. long parseLong(const String& val, long defaultValue)
  559. {
  560. // Use istringstream for direct correspondence with toString
  561. StringStream str(val);
  562. long ret = defaultValue;
  563. str >> ret;
  564. return ret;
  565. }
  566. unsigned long parseUnsignedLong(const String& val, unsigned long defaultValue)
  567. {
  568. // Use istringstream for direct correspondence with toString
  569. StringStream str(val);
  570. unsigned long ret = defaultValue;
  571. str >> ret;
  572. return ret;
  573. }
  574. bool parseBool(const String& val, bool defaultValue)
  575. {
  576. if ((StringUtil::startsWith(val, "true") || StringUtil::startsWith(val, "yes")
  577. || StringUtil::startsWith(val, "1")))
  578. return true;
  579. else if ((StringUtil::startsWith(val, "false") || StringUtil::startsWith(val, "no")
  580. || StringUtil::startsWith(val, "0")))
  581. return false;
  582. else
  583. return defaultValue;
  584. }
  585. bool isNumber(const String& val)
  586. {
  587. StringStream str(val);
  588. float tst;
  589. str >> tst;
  590. return !str.fail() && str.eof();
  591. }
  592. float parseFloat(const WString& val, float defaultValue)
  593. {
  594. // Use istringstream for direct correspondence with toString
  595. WStringStream str(val);
  596. float ret = defaultValue;
  597. str >> ret;
  598. return ret;
  599. }
  600. int parseInt(const WString& val, int defaultValue)
  601. {
  602. // Use istringstream for direct correspondence with toString
  603. WStringStream str(val);
  604. int ret = defaultValue;
  605. str >> ret;
  606. return ret;
  607. }
  608. unsigned int parseUnsignedInt(const WString& val, unsigned int defaultValue)
  609. {
  610. // Use istringstream for direct correspondence with toString
  611. WStringStream str(val);
  612. unsigned int ret = defaultValue;
  613. str >> ret;
  614. return ret;
  615. }
  616. long parseLong(const WString& val, long defaultValue)
  617. {
  618. // Use istringstream for direct correspondence with toString
  619. WStringStream str(val);
  620. long ret = defaultValue;
  621. str >> ret;
  622. return ret;
  623. }
  624. unsigned long parseUnsignedLong(const WString& val, unsigned long defaultValue)
  625. {
  626. // Use istringstream for direct correspondence with toString
  627. WStringStream str(val);
  628. unsigned long ret = defaultValue;
  629. str >> ret;
  630. return ret;
  631. }
  632. bool parseBool(const WString& val, bool defaultValue)
  633. {
  634. if ((StringUtil::startsWith(val, L"true") || StringUtil::startsWith(val, L"yes")
  635. || StringUtil::startsWith(val, L"1")))
  636. return true;
  637. else if ((StringUtil::startsWith(val, L"false") || StringUtil::startsWith(val, L"no")
  638. || StringUtil::startsWith(val, L"0")))
  639. return false;
  640. else
  641. return defaultValue;
  642. }
  643. bool isNumber(const WString& val)
  644. {
  645. WStringStream str(val);
  646. float tst;
  647. str >> tst;
  648. return !str.fail() && str.eof();
  649. }
  650. void __string_throwDataOverflowException()
  651. {
  652. BS_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
  653. }
  654. }