WString.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /*
  2. WString.cpp - String library for Wiring & Arduino
  3. ...mostly rewritten by Paul Stoffregen...
  4. Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
  5. Copyright 2011, Paul Stoffregen, paul@pjrc.com
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "WString.h"
  19. /*********************************************/
  20. /* Constructors */
  21. /*********************************************/
  22. String::String(const char *cstr)
  23. {
  24. init();
  25. if (cstr) copy(cstr, strlen(cstr));
  26. }
  27. String::String(const String &value)
  28. {
  29. init();
  30. *this = value;
  31. }
  32. String::String(const __FlashStringHelper *pstr)
  33. {
  34. init();
  35. *this = pstr;
  36. }
  37. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  38. String::String(String &&rval)
  39. {
  40. init();
  41. move(rval);
  42. }
  43. String::String(StringSumHelper &&rval)
  44. {
  45. init();
  46. move(rval);
  47. }
  48. #endif
  49. String::String(char c)
  50. {
  51. init();
  52. char buf[2];
  53. buf[0] = c;
  54. buf[1] = 0;
  55. *this = buf;
  56. }
  57. String::String(unsigned char value, unsigned char base)
  58. {
  59. init();
  60. char buf[1 + 8 * sizeof(unsigned char)];
  61. utoa(value, buf, base);
  62. *this = buf;
  63. }
  64. String::String(int value, unsigned char base)
  65. {
  66. init();
  67. char buf[2 + 8 * sizeof(int)];
  68. itoa(value, buf, base);
  69. *this = buf;
  70. }
  71. String::String(unsigned int value, unsigned char base)
  72. {
  73. init();
  74. char buf[1 + 8 * sizeof(unsigned int)];
  75. utoa(value, buf, base);
  76. *this = buf;
  77. }
  78. String::String(long value, unsigned char base)
  79. {
  80. init();
  81. char buf[2 + 8 * sizeof(long)];
  82. ltoa(value, buf, base);
  83. *this = buf;
  84. }
  85. String::String(unsigned long value, unsigned char base)
  86. {
  87. init();
  88. char buf[1 + 8 * sizeof(unsigned long)];
  89. ultoa(value, buf, base);
  90. *this = buf;
  91. }
  92. String::String(float value, unsigned char decimalPlaces)
  93. {
  94. init();
  95. char buf[33];
  96. *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
  97. }
  98. String::String(double value, unsigned char decimalPlaces)
  99. {
  100. init();
  101. char buf[33];
  102. *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
  103. }
  104. String::~String()
  105. {
  106. free(buffer);
  107. }
  108. /*********************************************/
  109. /* Memory Management */
  110. /*********************************************/
  111. inline void String::init(void)
  112. {
  113. buffer = NULL;
  114. capacity = 0;
  115. len = 0;
  116. }
  117. void String::invalidate(void)
  118. {
  119. if (buffer) free(buffer);
  120. buffer = NULL;
  121. capacity = len = 0;
  122. }
  123. unsigned char String::reserve(unsigned int size)
  124. {
  125. if (buffer && capacity >= size) return 1;
  126. if (changeBuffer(size)) {
  127. if (len == 0) buffer[0] = 0;
  128. return 1;
  129. }
  130. return 0;
  131. }
  132. unsigned char String::changeBuffer(unsigned int maxStrLen)
  133. {
  134. char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
  135. if (newbuffer) {
  136. buffer = newbuffer;
  137. capacity = maxStrLen;
  138. return 1;
  139. }
  140. return 0;
  141. }
  142. /*********************************************/
  143. /* Copy and Move */
  144. /*********************************************/
  145. String & String::copy(const char *cstr, unsigned int length)
  146. {
  147. if (!reserve(length)) {
  148. invalidate();
  149. return *this;
  150. }
  151. len = length;
  152. strcpy(buffer, cstr);
  153. return *this;
  154. }
  155. String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
  156. {
  157. if (!reserve(length)) {
  158. invalidate();
  159. return *this;
  160. }
  161. len = length;
  162. strcpy_P(buffer, (PGM_P)pstr);
  163. return *this;
  164. }
  165. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  166. void String::move(String &rhs)
  167. {
  168. if (buffer) {
  169. if (capacity >= rhs.len) {
  170. strcpy(buffer, rhs.buffer);
  171. len = rhs.len;
  172. rhs.len = 0;
  173. return;
  174. } else {
  175. free(buffer);
  176. }
  177. }
  178. buffer = rhs.buffer;
  179. capacity = rhs.capacity;
  180. len = rhs.len;
  181. rhs.buffer = NULL;
  182. rhs.capacity = 0;
  183. rhs.len = 0;
  184. }
  185. #endif
  186. String & String::operator = (const String &rhs)
  187. {
  188. if (this == &rhs) return *this;
  189. if (rhs.buffer) copy(rhs.buffer, rhs.len);
  190. else invalidate();
  191. return *this;
  192. }
  193. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  194. String & String::operator = (String &&rval)
  195. {
  196. if (this != &rval) move(rval);
  197. return *this;
  198. }
  199. String & String::operator = (StringSumHelper &&rval)
  200. {
  201. if (this != &rval) move(rval);
  202. return *this;
  203. }
  204. #endif
  205. String & String::operator = (const char *cstr)
  206. {
  207. if (cstr) copy(cstr, strlen(cstr));
  208. else invalidate();
  209. return *this;
  210. }
  211. String & String::operator = (const __FlashStringHelper *pstr)
  212. {
  213. if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
  214. else invalidate();
  215. return *this;
  216. }
  217. /*********************************************/
  218. /* concat */
  219. /*********************************************/
  220. unsigned char String::concat(const String &s)
  221. {
  222. return concat(s.buffer, s.len);
  223. }
  224. unsigned char String::concat(const char *cstr, unsigned int length)
  225. {
  226. unsigned int newlen = len + length;
  227. if (!cstr) return 0;
  228. if (length == 0) return 1;
  229. if (!reserve(newlen)) return 0;
  230. strcpy(buffer + len, cstr);
  231. len = newlen;
  232. return 1;
  233. }
  234. unsigned char String::concat(const char *cstr)
  235. {
  236. if (!cstr) return 0;
  237. return concat(cstr, strlen(cstr));
  238. }
  239. unsigned char String::concat(char c)
  240. {
  241. char buf[2];
  242. buf[0] = c;
  243. buf[1] = 0;
  244. return concat(buf, 1);
  245. }
  246. unsigned char String::concat(unsigned char num)
  247. {
  248. char buf[1 + 3 * sizeof(unsigned char)];
  249. itoa(num, buf, 10);
  250. return concat(buf, strlen(buf));
  251. }
  252. unsigned char String::concat(int num)
  253. {
  254. char buf[2 + 3 * sizeof(int)];
  255. itoa(num, buf, 10);
  256. return concat(buf, strlen(buf));
  257. }
  258. unsigned char String::concat(unsigned int num)
  259. {
  260. char buf[1 + 3 * sizeof(unsigned int)];
  261. utoa(num, buf, 10);
  262. return concat(buf, strlen(buf));
  263. }
  264. unsigned char String::concat(long num)
  265. {
  266. char buf[2 + 3 * sizeof(long)];
  267. ltoa(num, buf, 10);
  268. return concat(buf, strlen(buf));
  269. }
  270. unsigned char String::concat(unsigned long num)
  271. {
  272. char buf[1 + 3 * sizeof(unsigned long)];
  273. ultoa(num, buf, 10);
  274. return concat(buf, strlen(buf));
  275. }
  276. unsigned char String::concat(float num)
  277. {
  278. char buf[20];
  279. char* string = dtostrf(num, 4, 2, buf);
  280. return concat(string, strlen(string));
  281. }
  282. unsigned char String::concat(double num)
  283. {
  284. char buf[20];
  285. char* string = dtostrf(num, 4, 2, buf);
  286. return concat(string, strlen(string));
  287. }
  288. unsigned char String::concat(const __FlashStringHelper * str)
  289. {
  290. if (!str) return 0;
  291. int length = strlen_P((const char *) str);
  292. if (length == 0) return 1;
  293. unsigned int newlen = len + length;
  294. if (!reserve(newlen)) return 0;
  295. strcpy_P(buffer + len, (const char *) str);
  296. len = newlen;
  297. return 1;
  298. }
  299. /*********************************************/
  300. /* Concatenate */
  301. /*********************************************/
  302. StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
  303. {
  304. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  305. if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
  306. return a;
  307. }
  308. StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
  309. {
  310. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  311. if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
  312. return a;
  313. }
  314. StringSumHelper & operator + (const StringSumHelper &lhs, char c)
  315. {
  316. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  317. if (!a.concat(c)) a.invalidate();
  318. return a;
  319. }
  320. StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
  321. {
  322. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  323. if (!a.concat(num)) a.invalidate();
  324. return a;
  325. }
  326. StringSumHelper & operator + (const StringSumHelper &lhs, int num)
  327. {
  328. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  329. if (!a.concat(num)) a.invalidate();
  330. return a;
  331. }
  332. StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
  333. {
  334. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  335. if (!a.concat(num)) a.invalidate();
  336. return a;
  337. }
  338. StringSumHelper & operator + (const StringSumHelper &lhs, long num)
  339. {
  340. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  341. if (!a.concat(num)) a.invalidate();
  342. return a;
  343. }
  344. StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
  345. {
  346. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  347. if (!a.concat(num)) a.invalidate();
  348. return a;
  349. }
  350. StringSumHelper & operator + (const StringSumHelper &lhs, float num)
  351. {
  352. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  353. if (!a.concat(num)) a.invalidate();
  354. return a;
  355. }
  356. StringSumHelper & operator + (const StringSumHelper &lhs, double num)
  357. {
  358. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  359. if (!a.concat(num)) a.invalidate();
  360. return a;
  361. }
  362. StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
  363. {
  364. StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
  365. if (!a.concat(rhs)) a.invalidate();
  366. return a;
  367. }
  368. /*********************************************/
  369. /* Comparison */
  370. /*********************************************/
  371. int String::compareTo(const String &s) const
  372. {
  373. if (!buffer || !s.buffer) {
  374. if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
  375. if (buffer && len > 0) return *(unsigned char *)buffer;
  376. return 0;
  377. }
  378. return strcmp(buffer, s.buffer);
  379. }
  380. unsigned char String::equals(const String &s2) const
  381. {
  382. return (len == s2.len && compareTo(s2) == 0);
  383. }
  384. unsigned char String::equals(const char *cstr) const
  385. {
  386. if (len == 0) return (cstr == NULL || *cstr == 0);
  387. if (cstr == NULL) return buffer[0] == 0;
  388. return strcmp(buffer, cstr) == 0;
  389. }
  390. unsigned char String::operator<(const String &rhs) const
  391. {
  392. return compareTo(rhs) < 0;
  393. }
  394. unsigned char String::operator>(const String &rhs) const
  395. {
  396. return compareTo(rhs) > 0;
  397. }
  398. unsigned char String::operator<=(const String &rhs) const
  399. {
  400. return compareTo(rhs) <= 0;
  401. }
  402. unsigned char String::operator>=(const String &rhs) const
  403. {
  404. return compareTo(rhs) >= 0;
  405. }
  406. unsigned char String::equalsIgnoreCase( const String &s2 ) const
  407. {
  408. if (this == &s2) return 1;
  409. if (len != s2.len) return 0;
  410. if (len == 0) return 1;
  411. const char *p1 = buffer;
  412. const char *p2 = s2.buffer;
  413. while (*p1) {
  414. if (tolower(*p1++) != tolower(*p2++)) return 0;
  415. }
  416. return 1;
  417. }
  418. unsigned char String::startsWith( const String &s2 ) const
  419. {
  420. if (len < s2.len) return 0;
  421. return startsWith(s2, 0);
  422. }
  423. unsigned char String::startsWith( const String &s2, unsigned int offset ) const
  424. {
  425. if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
  426. return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
  427. }
  428. unsigned char String::endsWith( const String &s2 ) const
  429. {
  430. if ( len < s2.len || !buffer || !s2.buffer) return 0;
  431. return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
  432. }
  433. /*********************************************/
  434. /* Character Access */
  435. /*********************************************/
  436. char String::charAt(unsigned int loc) const
  437. {
  438. return operator[](loc);
  439. }
  440. void String::setCharAt(unsigned int loc, char c)
  441. {
  442. if (loc < len) buffer[loc] = c;
  443. }
  444. char & String::operator[](unsigned int index)
  445. {
  446. static char dummy_writable_char;
  447. if (index >= len || !buffer) {
  448. dummy_writable_char = 0;
  449. return dummy_writable_char;
  450. }
  451. return buffer[index];
  452. }
  453. char String::operator[]( unsigned int index ) const
  454. {
  455. if (index >= len || !buffer) return 0;
  456. return buffer[index];
  457. }
  458. void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
  459. {
  460. if (!bufsize || !buf) return;
  461. if (index >= len) {
  462. buf[0] = 0;
  463. return;
  464. }
  465. unsigned int n = bufsize - 1;
  466. if (n > len - index) n = len - index;
  467. strncpy((char *)buf, buffer + index, n);
  468. buf[n] = 0;
  469. }
  470. /*********************************************/
  471. /* Search */
  472. /*********************************************/
  473. int String::indexOf(char c) const
  474. {
  475. return indexOf(c, 0);
  476. }
  477. int String::indexOf( char ch, unsigned int fromIndex ) const
  478. {
  479. if (fromIndex >= len) return -1;
  480. const char* temp = strchr(buffer + fromIndex, ch);
  481. if (temp == NULL) return -1;
  482. return temp - buffer;
  483. }
  484. int String::indexOf(const String &s2) const
  485. {
  486. return indexOf(s2, 0);
  487. }
  488. int String::indexOf(const String &s2, unsigned int fromIndex) const
  489. {
  490. if (fromIndex >= len) return -1;
  491. const char *found = strstr(buffer + fromIndex, s2.buffer);
  492. if (found == NULL) return -1;
  493. return found - buffer;
  494. }
  495. int String::lastIndexOf( char theChar ) const
  496. {
  497. return lastIndexOf(theChar, len - 1);
  498. }
  499. int String::lastIndexOf(char ch, unsigned int fromIndex) const
  500. {
  501. if (fromIndex >= len) return -1;
  502. char tempchar = buffer[fromIndex + 1];
  503. buffer[fromIndex + 1] = '\0';
  504. char* temp = strrchr( buffer, ch );
  505. buffer[fromIndex + 1] = tempchar;
  506. if (temp == NULL) return -1;
  507. return temp - buffer;
  508. }
  509. int String::lastIndexOf(const String &s2) const
  510. {
  511. return lastIndexOf(s2, len - s2.len);
  512. }
  513. int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
  514. {
  515. if (s2.len == 0 || len == 0 || s2.len > len) return -1;
  516. if (fromIndex >= len) fromIndex = len - 1;
  517. int found = -1;
  518. for (char *p = buffer; p <= buffer + fromIndex; p++) {
  519. p = strstr(p, s2.buffer);
  520. if (!p) break;
  521. if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
  522. }
  523. return found;
  524. }
  525. String String::substring(unsigned int left, unsigned int right) const
  526. {
  527. if (left > right) {
  528. unsigned int temp = right;
  529. right = left;
  530. left = temp;
  531. }
  532. String out;
  533. if (left >= len) return out;
  534. if (right > len) right = len;
  535. char temp = buffer[right]; // save the replaced character
  536. buffer[right] = '\0';
  537. out = buffer + left; // pointer arithmetic
  538. buffer[right] = temp; //restore character
  539. return out;
  540. }
  541. /*********************************************/
  542. /* Modification */
  543. /*********************************************/
  544. void String::replace(char find, char replace)
  545. {
  546. if (!buffer) return;
  547. for (char *p = buffer; *p; p++) {
  548. if (*p == find) *p = replace;
  549. }
  550. }
  551. void String::replace(const String& find, const String& replace)
  552. {
  553. if (len == 0 || find.len == 0) return;
  554. int diff = replace.len - find.len;
  555. char *readFrom = buffer;
  556. char *foundAt;
  557. if (diff == 0) {
  558. while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
  559. memcpy(foundAt, replace.buffer, replace.len);
  560. readFrom = foundAt + replace.len;
  561. }
  562. } else if (diff < 0) {
  563. char *writeTo = buffer;
  564. while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
  565. unsigned int n = foundAt - readFrom;
  566. memcpy(writeTo, readFrom, n);
  567. writeTo += n;
  568. memcpy(writeTo, replace.buffer, replace.len);
  569. writeTo += replace.len;
  570. readFrom = foundAt + find.len;
  571. len += diff;
  572. }
  573. strcpy(writeTo, readFrom);
  574. } else {
  575. unsigned int size = len; // compute size needed for result
  576. while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
  577. readFrom = foundAt + find.len;
  578. size += diff;
  579. }
  580. if (size == len) return;
  581. if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
  582. int index = len - 1;
  583. while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
  584. readFrom = buffer + index + find.len;
  585. memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
  586. len += diff;
  587. buffer[len] = 0;
  588. memcpy(buffer + index, replace.buffer, replace.len);
  589. index--;
  590. }
  591. }
  592. }
  593. void String::remove(unsigned int index){
  594. // Pass the biggest integer as the count. The remove method
  595. // below will take care of truncating it at the end of the
  596. // string.
  597. remove(index, (unsigned int)-1);
  598. }
  599. void String::remove(unsigned int index, unsigned int count){
  600. if (index >= len) { return; }
  601. if (count <= 0) { return; }
  602. if (count > len - index) { count = len - index; }
  603. char *writeTo = buffer + index;
  604. len = len - count;
  605. strncpy(writeTo, buffer + index + count,len - index);
  606. buffer[len] = 0;
  607. }
  608. void String::toLowerCase(void)
  609. {
  610. if (!buffer) return;
  611. for (char *p = buffer; *p; p++) {
  612. *p = tolower(*p);
  613. }
  614. }
  615. void String::toUpperCase(void)
  616. {
  617. if (!buffer) return;
  618. for (char *p = buffer; *p; p++) {
  619. *p = toupper(*p);
  620. }
  621. }
  622. void String::trim(void)
  623. {
  624. if (!buffer || len == 0) return;
  625. char *begin = buffer;
  626. while (isspace(*begin)) begin++;
  627. char *end = buffer + len - 1;
  628. while (isspace(*end) && end >= begin) end--;
  629. len = end + 1 - begin;
  630. if (begin > buffer) memcpy(buffer, begin, len);
  631. buffer[len] = 0;
  632. }
  633. /*********************************************/
  634. /* Parsing / Conversion */
  635. /*********************************************/
  636. long String::toInt(void) const
  637. {
  638. if (buffer) return atol(buffer);
  639. return 0;
  640. }
  641. float String::toFloat(void) const
  642. {
  643. if (buffer) return float(atof(buffer));
  644. return 0;
  645. }