PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WString.cpp 15KB

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