Str.cpp 26 KB

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