Str.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  1. //
  2. // Copyright (c) 2008-2013 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "Str.h"
  23. #include "Swap.h"
  24. #include <cstdio>
  25. #include "DebugNew.h"
  26. namespace Urho3D
  27. {
  28. char String::endZero = 0;
  29. const String String::EMPTY;
  30. void PrintArgs(const char *formatString, va_list args);
  31. String::String(const WString& str) :
  32. length_(0),
  33. capacity_(0),
  34. buffer_(&endZero)
  35. {
  36. SetUTF8FromWChar(str.CString());
  37. }
  38. String::String(int value) :
  39. length_(0),
  40. capacity_(0),
  41. buffer_(&endZero)
  42. {
  43. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  44. sprintf(tempBuffer, "%d", value);
  45. *this = tempBuffer;
  46. }
  47. String::String(short value) :
  48. length_(0),
  49. capacity_(0),
  50. buffer_(&endZero)
  51. {
  52. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  53. sprintf(tempBuffer, "%d", value);
  54. *this = tempBuffer;
  55. }
  56. String::String(unsigned value) :
  57. length_(0),
  58. capacity_(0),
  59. buffer_(&endZero)
  60. {
  61. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  62. sprintf(tempBuffer, "%u", value);
  63. *this = tempBuffer;
  64. }
  65. String::String(unsigned short value) :
  66. length_(0),
  67. capacity_(0),
  68. buffer_(&endZero)
  69. {
  70. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  71. sprintf(tempBuffer, "%u", value);
  72. *this = tempBuffer;
  73. }
  74. String::String(float value) :
  75. length_(0),
  76. capacity_(0),
  77. buffer_(&endZero)
  78. {
  79. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  80. sprintf(tempBuffer, "%g", value);
  81. *this = tempBuffer;
  82. }
  83. String::String(double value) :
  84. length_(0),
  85. capacity_(0),
  86. buffer_(&endZero)
  87. {
  88. char tempBuffer[CONVERSION_BUFFER_LENGTH];
  89. sprintf(tempBuffer, "%g", value);
  90. *this = tempBuffer;
  91. }
  92. String::String(bool value) :
  93. length_(0),
  94. capacity_(0),
  95. buffer_(&endZero)
  96. {
  97. if (value)
  98. *this = "true";
  99. else
  100. *this = "false";
  101. }
  102. String::String(char value) :
  103. length_(0),
  104. capacity_(0),
  105. buffer_(&endZero)
  106. {
  107. Resize(1);
  108. buffer_[0] = value;
  109. }
  110. String::String(char value, unsigned length) :
  111. length_(0),
  112. capacity_(0),
  113. buffer_(&endZero)
  114. {
  115. Resize(length);
  116. for (unsigned i = 0; i < length; ++i)
  117. buffer_[i] = value;
  118. }
  119. String& String::operator += (int rhs)
  120. {
  121. return *this += String(rhs);
  122. }
  123. String& String::operator += (short rhs)
  124. {
  125. return *this += String(rhs);
  126. }
  127. String& String::operator += (unsigned rhs)
  128. {
  129. return *this += String(rhs);
  130. }
  131. String& String::operator += (unsigned short rhs)
  132. {
  133. return *this += String(rhs);
  134. }
  135. String& String::operator += (float rhs)
  136. {
  137. return *this += String(rhs);
  138. }
  139. String& String::operator += (bool rhs)
  140. {
  141. return *this += String(rhs);
  142. }
  143. void String::Replace(char replaceThis, char replaceWith)
  144. {
  145. for (unsigned i = 0; i < length_; ++i)
  146. {
  147. if (buffer_[i] == replaceThis)
  148. buffer_[i] = replaceWith;
  149. }
  150. }
  151. void String::Replace(const String& replaceThis, const String& replaceWith)
  152. {
  153. unsigned nextPos = 0;
  154. while (nextPos < length_)
  155. {
  156. unsigned pos = Find(replaceThis, nextPos);
  157. if (pos == NPOS)
  158. break;
  159. Replace(pos, replaceThis.length_, replaceWith);
  160. nextPos = pos + replaceWith.length_;
  161. }
  162. }
  163. void String::Replace(unsigned pos, unsigned length, const String& str)
  164. {
  165. // If substring is illegal, do nothing
  166. if (pos + length > length_)
  167. return;
  168. Replace(pos, length, str.buffer_, str.length_);
  169. }
  170. String::Iterator String::Replace(const String::Iterator& start, const String::Iterator& end, const String& replaceWith)
  171. {
  172. unsigned pos = start - Begin();
  173. if (pos >= length_)
  174. return End();
  175. unsigned length = end - start;
  176. Replace(pos, length, replaceWith);
  177. return Begin() + pos;
  178. }
  179. String String::Replaced(char replaceThis, char replaceWith) const
  180. {
  181. String ret(*this);
  182. ret.Replace(replaceThis, replaceWith);
  183. return ret;
  184. }
  185. String String::Replaced(const String& replaceThis, const String& replaceWith) const
  186. {
  187. String ret(*this);
  188. ret.Replace(replaceThis, replaceWith);
  189. return ret;
  190. }
  191. String& String::Append(const String& str)
  192. {
  193. return *this += str;
  194. }
  195. String& String::Append(const char* str)
  196. {
  197. return *this += str;
  198. }
  199. String& String::Append(char c)
  200. {
  201. return *this += c;
  202. }
  203. String& String::Append(const char* str, unsigned length)
  204. {
  205. if (str)
  206. {
  207. unsigned oldLength = length_;
  208. Resize(oldLength + length);
  209. CopyChars(&buffer_[oldLength], str, length);
  210. }
  211. return *this;
  212. }
  213. void String::Insert(unsigned pos, const String& str)
  214. {
  215. if (pos > length_)
  216. pos = length_;
  217. if (pos == length_)
  218. (*this) += str;
  219. else
  220. Replace(pos, 0, str);
  221. }
  222. void String::Insert(unsigned pos, char c)
  223. {
  224. if (pos > length_)
  225. pos = length_;
  226. if (pos == length_)
  227. (*this) += c;
  228. else
  229. {
  230. unsigned oldLength = length_;
  231. Resize(length_ + 1);
  232. MoveRange(pos + 1, pos, oldLength - pos);
  233. buffer_[pos] = c;
  234. }
  235. }
  236. String::Iterator String::Insert(const String::Iterator& dest, const String& str)
  237. {
  238. unsigned pos = dest - Begin();
  239. if (pos > length_)
  240. pos = length_;
  241. Insert(pos, str);
  242. return Begin() + pos;
  243. }
  244. String::Iterator String::Insert(const String::Iterator& dest, const String::Iterator& start, const String::Iterator& end)
  245. {
  246. unsigned pos = dest - Begin();
  247. if (pos > length_)
  248. pos = length_;
  249. unsigned length = end - start;
  250. Replace(pos, 0, &(*start), length);
  251. return Begin() + pos;
  252. }
  253. String::Iterator String::Insert(const String::Iterator& dest, char c)
  254. {
  255. unsigned pos = dest - Begin();
  256. if (pos > length_)
  257. pos = length_;
  258. Insert(pos, c);
  259. return Begin() + pos;
  260. }
  261. void String::Erase(unsigned pos, unsigned length)
  262. {
  263. Replace(pos, length, String::EMPTY);
  264. }
  265. String::Iterator String::Erase(const String::Iterator& it)
  266. {
  267. unsigned pos = it - Begin();
  268. if (pos >= length_)
  269. return End();
  270. Erase(pos);
  271. return Begin() + pos;
  272. }
  273. String::Iterator String::Erase(const String::Iterator& start, const String::Iterator& end)
  274. {
  275. unsigned pos = start - Begin();
  276. if (pos >= length_)
  277. return End();
  278. unsigned length = end - start;
  279. Erase(pos, length);
  280. return Begin() + pos;
  281. }
  282. void String::Resize(unsigned newLength)
  283. {
  284. if (!capacity_)
  285. {
  286. // Calculate initial capacity
  287. capacity_ = newLength + 1;
  288. if (capacity_ < MIN_CAPACITY)
  289. capacity_ = MIN_CAPACITY;
  290. buffer_ = new char[capacity_];
  291. }
  292. else
  293. {
  294. if (newLength && capacity_ < newLength + 1)
  295. {
  296. // Increase the capacity with half each time it is exceeded
  297. while (capacity_ < newLength + 1)
  298. capacity_ += (capacity_ + 1) >> 1;
  299. char* newBuffer = new char[capacity_];
  300. // Move the existing data to the new buffer, then delete the old buffer
  301. if (length_)
  302. CopyChars(newBuffer, buffer_, length_);
  303. delete[] buffer_;
  304. buffer_ = newBuffer;
  305. }
  306. }
  307. buffer_[newLength] = 0;
  308. length_ = newLength;
  309. }
  310. void String::Reserve(unsigned newCapacity)
  311. {
  312. if (newCapacity < length_ + 1)
  313. newCapacity = length_ + 1;
  314. if (newCapacity == capacity_)
  315. return;
  316. char* newBuffer = new char[newCapacity];
  317. // Move the existing data to the new buffer, then delete the old buffer
  318. CopyChars(newBuffer, buffer_, length_ + 1);
  319. if (capacity_)
  320. delete[] buffer_;
  321. capacity_ = newCapacity;
  322. buffer_ = newBuffer;
  323. }
  324. void String::Compact()
  325. {
  326. if (capacity_)
  327. Reserve(length_ + 1);
  328. }
  329. void String::Clear()
  330. {
  331. Resize(0);
  332. }
  333. void String::Swap(String& str)
  334. {
  335. Urho3D::Swap(length_, str.length_);
  336. Urho3D::Swap(capacity_, str.capacity_);
  337. Urho3D::Swap(buffer_, str.buffer_);
  338. }
  339. String String::Substring(unsigned pos) const
  340. {
  341. if (pos < length_)
  342. {
  343. String ret;
  344. ret.Resize(length_ - pos);
  345. CopyChars(ret.buffer_, buffer_ + pos, ret.length_);
  346. return ret;
  347. }
  348. else
  349. return String();
  350. }
  351. String String::Substring(unsigned pos, unsigned length) const
  352. {
  353. if (pos < length_)
  354. {
  355. String ret;
  356. if (pos + length > length_)
  357. length = length_ - pos;
  358. ret.Resize(length);
  359. CopyChars(ret.buffer_, buffer_ + pos, ret.length_);
  360. return ret;
  361. }
  362. else
  363. return String();
  364. }
  365. String String::Trimmed() const
  366. {
  367. unsigned trimStart = 0;
  368. unsigned trimEnd = length_;
  369. while (trimStart < trimEnd)
  370. {
  371. char c = buffer_[trimStart];
  372. if (c != ' ' && c != 9)
  373. break;
  374. ++trimStart;
  375. }
  376. while (trimEnd > trimStart)
  377. {
  378. char c = buffer_[trimEnd - 1];
  379. if (c != ' ' && c != 9)
  380. break;
  381. --trimEnd;
  382. }
  383. return Substring(trimStart, trimEnd - trimStart);
  384. }
  385. String String::ToLower() const
  386. {
  387. String ret(*this);
  388. for (unsigned i = 0; i < ret.length_; ++i)
  389. ret[i] = tolower(buffer_[i]);
  390. return ret;
  391. }
  392. String String::ToUpper() const
  393. {
  394. String ret(*this);
  395. for (unsigned i = 0; i < ret.length_; ++i)
  396. ret[i] = toupper(buffer_[i]);
  397. return ret;
  398. }
  399. Vector<String> String::Split(char separator) const
  400. {
  401. return Split(CString(), separator);
  402. }
  403. void String::Join(const Vector<String>& subStrings, String glue)
  404. {
  405. *this = Joined(subStrings, glue);
  406. }
  407. unsigned String::Find(char c, unsigned startPos) const
  408. {
  409. for (unsigned i = startPos; i < length_; ++i)
  410. {
  411. if (buffer_[i] == c)
  412. return i;
  413. }
  414. return NPOS;
  415. }
  416. unsigned String::Find(const String& str, unsigned startPos) const
  417. {
  418. if (!str.length_ || str.length_ > length_)
  419. return NPOS;
  420. char first = str.buffer_[0];
  421. for (unsigned i = startPos; i <= length_ - str.length_; ++i)
  422. {
  423. if (buffer_[i] == first)
  424. {
  425. unsigned skip = NPOS;
  426. bool found = true;
  427. for (unsigned j = 1; j < str.length_; ++j)
  428. {
  429. char c = buffer_[i + j];
  430. if (skip == NPOS && c == first)
  431. skip = i + j - 1;
  432. if (c != str.buffer_[j])
  433. {
  434. found = false;
  435. if (skip != NPOS)
  436. i = skip;
  437. break;
  438. }
  439. }
  440. if (found)
  441. return i;
  442. }
  443. }
  444. return NPOS;
  445. }
  446. unsigned String::FindLast(char c, unsigned startPos) const
  447. {
  448. if (startPos >= length_)
  449. startPos = length_ - 1;
  450. for (unsigned i = startPos; i < length_; --i)
  451. {
  452. if (buffer_[i] == c)
  453. return i;
  454. }
  455. return NPOS;
  456. }
  457. unsigned String::FindLast(const String& str, unsigned startPos) const
  458. {
  459. if (!str.length_ || str.length_ > length_)
  460. return NPOS;
  461. if (startPos > length_ - str.length_)
  462. startPos = length_ - str.length_;
  463. char first = str.buffer_[0];
  464. for (unsigned i = startPos; i < length_; --i)
  465. {
  466. if (buffer_[i] == first)
  467. {
  468. bool found = true;
  469. for (unsigned j = 1; j < str.length_; ++j)
  470. {
  471. char c = buffer_[i + j];
  472. if (c != str.buffer_[j])
  473. {
  474. found = false;
  475. break;
  476. }
  477. }
  478. if (found)
  479. return i;
  480. }
  481. }
  482. return NPOS;
  483. }
  484. bool String::StartsWith(const String& str) const
  485. {
  486. return Find(str) == 0;
  487. }
  488. bool String::EndsWith(const String& str) const
  489. {
  490. return FindLast(str) == Length() - str.Length();
  491. }
  492. int String::Compare(const String& str, bool caseSensitive) const
  493. {
  494. return Compare(CString(), str.CString(), caseSensitive);
  495. }
  496. int String::Compare(const char* str, bool caseSensitive) const
  497. {
  498. return Compare(CString(), str, caseSensitive);
  499. }
  500. void String::SetUTF8FromLatin1(const char* str)
  501. {
  502. char temp[7];
  503. Clear();
  504. if (!str)
  505. return;
  506. while (*str)
  507. {
  508. char* dest = temp;
  509. EncodeUTF8(dest, *str++);
  510. *dest = 0;
  511. Append(temp);
  512. }
  513. }
  514. void String::SetUTF8FromWChar(const wchar_t* str)
  515. {
  516. char temp[7];
  517. Clear();
  518. if (!str)
  519. return;
  520. #ifdef WIN32
  521. while (*str)
  522. {
  523. unsigned unicodeChar = DecodeUTF16(str);
  524. char* dest = temp;
  525. EncodeUTF8(dest, unicodeChar);
  526. *dest = 0;
  527. Append(temp);
  528. }
  529. #else
  530. while (*str)
  531. {
  532. char* dest = temp;
  533. EncodeUTF8(dest, *str++);
  534. *dest = 0;
  535. Append(temp);
  536. }
  537. #endif
  538. }
  539. unsigned String::LengthUTF8() const
  540. {
  541. unsigned ret = 0;
  542. const char* src = buffer_;
  543. if (!src)
  544. return ret;
  545. const char* end = buffer_ + length_;
  546. while (src < end)
  547. {
  548. DecodeUTF8(src);
  549. ++ret;
  550. }
  551. return ret;
  552. }
  553. unsigned String::ByteOffsetUTF8(unsigned index) const
  554. {
  555. unsigned byteOffset = 0;
  556. unsigned utfPos = 0;
  557. while (utfPos < index && byteOffset < length_)
  558. {
  559. NextUTF8Char(byteOffset);
  560. ++utfPos;
  561. }
  562. return byteOffset;
  563. }
  564. unsigned String::NextUTF8Char(unsigned& byteOffset) const
  565. {
  566. if (!buffer_)
  567. return 0;
  568. const char* src = buffer_ + byteOffset;
  569. unsigned ret = DecodeUTF8(src);
  570. byteOffset = src - buffer_;
  571. return ret;
  572. }
  573. unsigned String::AtUTF8(unsigned index) const
  574. {
  575. unsigned byteOffset = ByteOffsetUTF8(index);
  576. return NextUTF8Char(byteOffset);
  577. }
  578. void String::ReplaceUTF8(unsigned index, unsigned unicodeChar)
  579. {
  580. unsigned utfPos = 0;
  581. unsigned byteOffset = 0;
  582. while (utfPos < index && byteOffset < length_)
  583. {
  584. NextUTF8Char(byteOffset);
  585. ++utfPos;
  586. }
  587. if (utfPos < index)
  588. return;
  589. unsigned beginCharPos = byteOffset;
  590. NextUTF8Char(byteOffset);
  591. char temp[7];
  592. char* dest = temp;
  593. EncodeUTF8(dest, unicodeChar);
  594. *dest = 0;
  595. Replace(beginCharPos, byteOffset - beginCharPos, temp, dest - temp);
  596. }
  597. String& String::AppendUTF8(unsigned unicodeChar)
  598. {
  599. char temp[7];
  600. char* dest = temp;
  601. EncodeUTF8(dest, unicodeChar);
  602. *dest = 0;
  603. return Append(temp);
  604. }
  605. String String::SubstringUTF8(unsigned pos) const
  606. {
  607. unsigned utf8Length = LengthUTF8();
  608. unsigned byteOffset = ByteOffsetUTF8(pos);
  609. String ret;
  610. while (pos < utf8Length)
  611. {
  612. ret.AppendUTF8(NextUTF8Char(byteOffset));
  613. ++pos;
  614. }
  615. return ret;
  616. }
  617. String String::SubstringUTF8(unsigned pos, unsigned length) const
  618. {
  619. unsigned utf8Length = LengthUTF8();
  620. unsigned byteOffset = ByteOffsetUTF8(pos);
  621. unsigned endPos = pos + length;
  622. String ret;
  623. while (pos < endPos && pos < utf8Length)
  624. {
  625. ret.AppendUTF8(NextUTF8Char(byteOffset));
  626. ++pos;
  627. }
  628. return ret;
  629. }
  630. void String::EncodeUTF8(char*& dest, unsigned unicodeChar)
  631. {
  632. if (unicodeChar < 0x80)
  633. *dest++ = unicodeChar;
  634. else if (unicodeChar < 0x800)
  635. {
  636. *dest++ = 0xc0 | ((unicodeChar >> 6) & 0x1f);
  637. *dest++ = 0x80 | (unicodeChar & 0x3f);
  638. }
  639. else if (unicodeChar < 0x10000)
  640. {
  641. *dest++ = 0xe0 | ((unicodeChar >> 12) & 0xf);
  642. *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
  643. *dest++ = 0x80 | (unicodeChar & 0x3f);
  644. }
  645. else if (unicodeChar < 0x200000)
  646. {
  647. *dest++ = 0xf0 | ((unicodeChar >> 18) & 0x7);
  648. *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
  649. *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
  650. *dest++ = 0x80 | (unicodeChar & 0x3f);
  651. }
  652. else if (unicodeChar < 0x4000000)
  653. {
  654. *dest++ = 0xf8 | ((unicodeChar >> 24) & 0x3);
  655. *dest++ = 0x80 | ((unicodeChar >> 18) & 0x3f);
  656. *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
  657. *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
  658. *dest++ = 0x80 | (unicodeChar & 0x3f);
  659. }
  660. else
  661. {
  662. *dest++ = 0xfc | ((unicodeChar >> 30) & 0x1);
  663. *dest++ = 0x80 | ((unicodeChar >> 24) & 0x3f);
  664. *dest++ = 0x80 | ((unicodeChar >> 18) & 0x3f);
  665. *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
  666. *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
  667. *dest++ = 0x80 | (unicodeChar & 0x3f);
  668. }
  669. }
  670. #define GET_NEXT_CONTINUATION_BYTE(ptr) *ptr; if ((unsigned char)*ptr < 0x80 || (unsigned char)*ptr >= 0xc0) return '?'; else ++ptr;
  671. unsigned String::DecodeUTF8(const char*& src)
  672. {
  673. if (src == 0)
  674. return 0;
  675. unsigned char char1 = *src++;
  676. // Check if we are in the middle of a UTF8 character
  677. if (char1 >= 0x80 && char1 < 0xc0)
  678. {
  679. while ((unsigned char)*src >= 0x80 && (unsigned char)*src < 0xc0)
  680. ++src;
  681. return '?';
  682. }
  683. if (char1 < 0x80)
  684. return char1;
  685. else if (char1 < 0xe0)
  686. {
  687. unsigned char char2 = GET_NEXT_CONTINUATION_BYTE(src);
  688. return (char2 & 0x3f) | ((char1 & 0x1f) << 6);
  689. }
  690. else if (char1 < 0xf0)
  691. {
  692. unsigned char char2 = GET_NEXT_CONTINUATION_BYTE(src);
  693. unsigned char char3 = GET_NEXT_CONTINUATION_BYTE(src);
  694. return (char3 & 0x3f) | ((char2 & 0x3f) << 6) | ((char1 & 0xf) << 12);
  695. }
  696. else if (char1 < 0xf8)
  697. {
  698. unsigned char char2 = GET_NEXT_CONTINUATION_BYTE(src);
  699. unsigned char char3 = GET_NEXT_CONTINUATION_BYTE(src);
  700. unsigned char char4 = GET_NEXT_CONTINUATION_BYTE(src);
  701. return (char4 & 0x3f) | ((char3 & 0x3f) << 6) | ((char2 & 0x3f) << 12) | ((char1 & 0x7) << 18);
  702. }
  703. else if (char1 < 0xfc)
  704. {
  705. unsigned char char2 = GET_NEXT_CONTINUATION_BYTE(src);
  706. unsigned char char3 = GET_NEXT_CONTINUATION_BYTE(src);
  707. unsigned char char4 = GET_NEXT_CONTINUATION_BYTE(src);
  708. unsigned char char5 = GET_NEXT_CONTINUATION_BYTE(src);
  709. return (char5 & 0x3f) | ((char4 & 0x3f) << 6) | ((char3 & 0x3f) << 12) | ((char2 & 0x3f) << 18) | ((char1 & 0x3) << 24);
  710. }
  711. else
  712. {
  713. unsigned char char2 = GET_NEXT_CONTINUATION_BYTE(src);
  714. unsigned char char3 = GET_NEXT_CONTINUATION_BYTE(src);
  715. unsigned char char4 = GET_NEXT_CONTINUATION_BYTE(src);
  716. unsigned char char5 = GET_NEXT_CONTINUATION_BYTE(src);
  717. unsigned char char6 = GET_NEXT_CONTINUATION_BYTE(src);
  718. return (char6 & 0x3f) | ((char5 & 0x3f) << 6) | ((char4 & 0x3f) << 12) | ((char3 & 0x3f) << 18) | ((char2 & 0x3f) << 24) |
  719. ((char1 & 0x1) << 30);
  720. }
  721. }
  722. #ifdef WIN32
  723. void String::EncodeUTF16(wchar_t*& dest, unsigned unicodeChar)
  724. {
  725. if (unicodeChar < 0x10000)
  726. *dest++ = unicodeChar;
  727. else
  728. {
  729. unicodeChar -= 0x10000;
  730. *dest++ = 0xd800 | ((unicodeChar >> 10) & 0x3ff);
  731. *dest++ = 0xdc00 | (unicodeChar & 0x3ff);
  732. }
  733. }
  734. unsigned String::DecodeUTF16(const wchar_t*& src)
  735. {
  736. if (src == 0)
  737. return 0;
  738. unsigned short word1 = *src;
  739. // Check if we are at a low surrogate
  740. word1 = *src++;
  741. if (word1 >= 0xdc00 && word1 < 0xe000)
  742. {
  743. while (*src >= 0xdc00 && *src < 0xe000)
  744. ++src;
  745. return '?';
  746. }
  747. if (word1 < 0xd800 || word1 >= 0xe00)
  748. return word1;
  749. else
  750. {
  751. unsigned short word2 = *src++;
  752. if (word2 < 0xdc00 || word2 >= 0xe000)
  753. {
  754. --src;
  755. return '?';
  756. }
  757. else
  758. return ((word1 & 0x3ff) << 10) | (word2 & 0x3ff) | 0x10000;
  759. }
  760. }
  761. #endif
  762. Vector<String> String::Split(const char* str, char separator)
  763. {
  764. Vector<String> ret;
  765. unsigned pos = 0;
  766. unsigned length = CStringLength(str);
  767. while (pos < length)
  768. {
  769. if (str[pos] != separator)
  770. break;
  771. ++pos;
  772. }
  773. while (pos < length)
  774. {
  775. unsigned start = pos;
  776. while (start < length)
  777. {
  778. if (str[start] == separator)
  779. break;
  780. ++start;
  781. }
  782. if (start == length)
  783. {
  784. ret.Push(String(&str[pos]));
  785. break;
  786. }
  787. unsigned end = start;
  788. while (end < length)
  789. {
  790. if (str[end] != separator)
  791. break;
  792. ++end;
  793. }
  794. ret.Push(String(&str[pos], start - pos));
  795. pos = end;
  796. }
  797. return ret;
  798. }
  799. String String::Joined(const Vector<String>& subStrings, String glue)
  800. {
  801. if (subStrings.Empty())
  802. return String();
  803. String joinedString(subStrings[0]);
  804. for (unsigned i = 1; i < subStrings.Size(); ++i)
  805. joinedString.Append(glue).Append(subStrings[i]);
  806. return joinedString;
  807. }
  808. String& String::AppendWithFormat(const char* formatString, ... )
  809. {
  810. va_list args;
  811. va_start(args, formatString);
  812. AppendWithFormatArgs(formatString, args);
  813. va_end(args);
  814. return *this;
  815. }
  816. String& String::AppendWithFormatArgs(const char* formatString, va_list args)
  817. {
  818. int pos = 0, lastPos = 0;
  819. int length = strlen(formatString);
  820. while (true)
  821. {
  822. // Scan the format string and find %a argument where a is one of d, f, s ...
  823. while (pos < length && formatString[pos] != '%') pos++;
  824. Append(formatString + lastPos, pos - lastPos);
  825. if (pos >= length)
  826. return *this;
  827. char arg = formatString[pos + 1];
  828. pos += 2;
  829. lastPos = pos;
  830. switch (arg)
  831. {
  832. // Integer
  833. case 'd':
  834. case 'i':
  835. {
  836. int arg = va_arg(args, int);
  837. Append(String(arg));
  838. break;
  839. }
  840. // Unsigned
  841. case 'u':
  842. {
  843. unsigned arg = va_arg(args, unsigned);
  844. Append(String(arg));
  845. break;
  846. }
  847. // Real
  848. case 'f':
  849. {
  850. double arg = va_arg(args, double);
  851. Append(String(arg));
  852. break;
  853. }
  854. // Character
  855. case 'c':
  856. {
  857. int arg = va_arg(args, int);
  858. Append(arg);
  859. break;
  860. }
  861. // C string
  862. case 's':
  863. {
  864. char* arg = va_arg(args, char*);
  865. Append(arg);
  866. break;
  867. }
  868. // Hex
  869. case 'x':
  870. {
  871. char buf[CONVERSION_BUFFER_LENGTH];
  872. int arg = va_arg(args, int);
  873. int arglen = ::sprintf(buf, "%x", arg);
  874. Append(buf, arglen);
  875. break;
  876. }
  877. // Pointer
  878. case 'p':
  879. {
  880. char buf[CONVERSION_BUFFER_LENGTH];
  881. int arg = va_arg(args, int);
  882. int arglen = ::sprintf(buf, "%p", reinterpret_cast<void*>(arg));
  883. Append(buf, arglen);
  884. break;
  885. }
  886. case '%':
  887. {
  888. Append("%", 1);
  889. break;
  890. }
  891. }
  892. }
  893. }
  894. int String::Compare(const char* lhs, const char* rhs, bool caseSensitive)
  895. {
  896. if (!lhs || !rhs)
  897. return lhs ? 1 : (rhs ? -1 : 0);
  898. if (caseSensitive)
  899. return strcmp(lhs, rhs);
  900. else
  901. {
  902. for (;;)
  903. {
  904. char l = tolower(*lhs);
  905. char r = tolower(*rhs);
  906. if (!l || !r)
  907. return l ? 1 : (r ? -1 : 0);
  908. if (l < r)
  909. return -1;
  910. if (l > r)
  911. return 1;
  912. ++lhs;
  913. ++rhs;
  914. }
  915. }
  916. }
  917. void String::Replace(unsigned pos, unsigned length, const char* srcStart, unsigned srcLength)
  918. {
  919. int delta = (int)srcLength - (int)length;
  920. if (pos + length < length_)
  921. {
  922. if (delta < 0)
  923. {
  924. MoveRange(pos + srcLength, pos + length, length_ - pos - length);
  925. Resize(length_ + delta);
  926. }
  927. if (delta > 0)
  928. {
  929. Resize(length_ + delta);
  930. MoveRange(pos + srcLength, pos + length, length_ - pos - length - delta);
  931. }
  932. }
  933. else
  934. Resize(length_ + delta);
  935. CopyChars(buffer_ + pos, srcStart, srcLength);
  936. }
  937. WString::WString() :
  938. length_(0),
  939. buffer_(0)
  940. {
  941. }
  942. WString::WString(const String& str) :
  943. length_(0),
  944. buffer_(0)
  945. {
  946. #ifdef WIN32
  947. unsigned neededSize = 0;
  948. wchar_t temp[3];
  949. unsigned byteOffset = 0;
  950. while (byteOffset < str.Length())
  951. {
  952. wchar_t* dest = temp;
  953. String::EncodeUTF16(dest, str.NextUTF8Char(byteOffset));
  954. neededSize += dest - temp;
  955. }
  956. Resize(neededSize);
  957. byteOffset = 0;
  958. wchar_t* dest = buffer_;
  959. while (byteOffset < str.Length())
  960. String::EncodeUTF16(dest, str.NextUTF8Char(byteOffset));
  961. #else
  962. Resize(str.LengthUTF8());
  963. unsigned byteOffset = 0;
  964. wchar_t* dest = buffer_;
  965. while (byteOffset < str.Length())
  966. *dest++ = str.NextUTF8Char(byteOffset);
  967. #endif
  968. }
  969. WString::~WString()
  970. {
  971. delete[] buffer_;
  972. }
  973. void WString::Resize(unsigned newSize)
  974. {
  975. if (!newSize)
  976. {
  977. delete[] buffer_;
  978. buffer_ = 0;
  979. length_ = 0;
  980. }
  981. else
  982. {
  983. wchar_t* newBuffer = new wchar_t[newSize + 1];
  984. if (buffer_)
  985. memcpy(newBuffer, buffer_, length_ * sizeof(wchar_t));
  986. newBuffer[newSize] = 0;
  987. buffer_ = newBuffer;
  988. length_ = newSize;
  989. }
  990. }
  991. }