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
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 /*********************************************/
26 /*********************************************/
28 String::String(const char *cstr)
31 if (cstr) copy(cstr, strlen(cstr));
34 String::String(const String &value)
40 String::String(const __FlashStringHelper *pstr)
46 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
47 String::String(String &&rval)
52 String::String(StringSumHelper &&rval)
59 String::String(char c)
68 String::String(unsigned char value, unsigned char base)
71 char buf[1 + 8 * sizeof(unsigned char)];
72 utoa(value, buf, base);
76 String::String(int value, unsigned char base)
79 char buf[2 + 8 * sizeof(int)];
80 itoa(value, buf, base);
84 String::String(unsigned int value, unsigned char base)
87 char buf[1 + 8 * sizeof(unsigned int)];
88 utoa(value, buf, base);
92 String::String(long value, unsigned char base)
95 char buf[2 + 8 * sizeof(long)];
96 ltoa(value, buf, base);
100 String::String(unsigned long value, unsigned char base)
103 char buf[1 + 8 * sizeof(unsigned long)];
104 ultoa(value, buf, base);
108 String::String(float value, unsigned char decimalPlaces)
112 *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
115 String::String(double value, unsigned char decimalPlaces)
119 *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
124 if (buffer) free(buffer);
127 /*********************************************/
128 /* Memory Management */
129 /*********************************************/
131 inline void String::init(void)
138 void String::invalidate(void)
140 if (buffer) free(buffer);
145 unsigned char String::reserve(unsigned int size)
147 if (buffer && capacity >= size) return 1;
148 if (changeBuffer(size)) {
149 if (len == 0) buffer[0] = 0;
155 unsigned char String::changeBuffer(unsigned int maxStrLen)
157 char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
160 capacity = maxStrLen;
166 /*********************************************/
168 /*********************************************/
170 String & String::copy(const char *cstr, unsigned int length)
172 if (!reserve(length)) {
177 strcpy(buffer, cstr);
181 String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
183 if (!reserve(length)) {
188 strcpy_P(buffer, (PGM_P)pstr);
192 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
193 void String::move(String &rhs)
196 if (rhs && capacity >= rhs.len) {
197 strcpy(buffer, rhs.buffer);
206 capacity = rhs.capacity;
214 String & String::operator = (const String &rhs)
216 if (this == &rhs) return *this;
218 if (rhs.buffer) copy(rhs.buffer, rhs.len);
224 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
225 String & String::operator = (String &&rval)
227 if (this != &rval) move(rval);
231 String & String::operator = (StringSumHelper &&rval)
233 if (this != &rval) move(rval);
238 String & String::operator = (const char *cstr)
240 if (cstr) copy(cstr, strlen(cstr));
246 String & String::operator = (const __FlashStringHelper *pstr)
248 if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
254 /*********************************************/
256 /*********************************************/
258 unsigned char String::concat(const String &s)
260 return concat(s.buffer, s.len);
263 unsigned char String::concat(const char *cstr, unsigned int length)
265 unsigned int newlen = len + length;
267 if (length == 0) return 1;
268 if (!reserve(newlen)) return 0;
269 strcpy(buffer + len, cstr);
274 unsigned char String::concat(const char *cstr)
277 return concat(cstr, strlen(cstr));
280 unsigned char String::concat(char c)
285 return concat(buf, 1);
288 unsigned char String::concat(unsigned char num)
290 char buf[1 + 3 * sizeof(unsigned char)];
292 return concat(buf, strlen(buf));
295 unsigned char String::concat(int num)
297 char buf[2 + 3 * sizeof(int)];
299 return concat(buf, strlen(buf));
302 unsigned char String::concat(unsigned int num)
304 char buf[1 + 3 * sizeof(unsigned int)];
306 return concat(buf, strlen(buf));
309 unsigned char String::concat(long num)
311 char buf[2 + 3 * sizeof(long)];
313 return concat(buf, strlen(buf));
316 unsigned char String::concat(unsigned long num)
318 char buf[1 + 3 * sizeof(unsigned long)];
320 return concat(buf, strlen(buf));
323 unsigned char String::concat(float num)
326 char* string = dtostrf(num, 4, 2, buf);
327 return concat(string, strlen(string));
330 unsigned char String::concat(double num)
333 char* string = dtostrf(num, 4, 2, buf);
334 return concat(string, strlen(string));
337 unsigned char String::concat(const __FlashStringHelper * str)
340 int length = strlen_P((const char *) str);
341 if (length == 0) return 1;
342 unsigned int newlen = len + length;
343 if (!reserve(newlen)) return 0;
344 strcpy_P(buffer + len, (const char *) str);
349 /*********************************************/
351 /*********************************************/
353 StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
355 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
356 if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
360 StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
362 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
363 if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
367 StringSumHelper & operator + (const StringSumHelper &lhs, char c)
369 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
370 if (!a.concat(c)) a.invalidate();
374 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
376 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
377 if (!a.concat(num)) a.invalidate();
381 StringSumHelper & operator + (const StringSumHelper &lhs, int num)
383 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
384 if (!a.concat(num)) a.invalidate();
388 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
390 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
391 if (!a.concat(num)) a.invalidate();
395 StringSumHelper & operator + (const StringSumHelper &lhs, long num)
397 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
398 if (!a.concat(num)) a.invalidate();
402 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
404 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
405 if (!a.concat(num)) a.invalidate();
409 StringSumHelper & operator + (const StringSumHelper &lhs, float num)
411 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
412 if (!a.concat(num)) a.invalidate();
416 StringSumHelper & operator + (const StringSumHelper &lhs, double num)
418 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
419 if (!a.concat(num)) a.invalidate();
423 StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
425 StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
426 if (!a.concat(rhs)) a.invalidate();
430 /*********************************************/
432 /*********************************************/
434 int String::compareTo(const String &s) const
436 if (!buffer || !s.buffer) {
437 if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
438 if (buffer && len > 0) return *(unsigned char *)buffer;
441 return strcmp(buffer, s.buffer);
444 unsigned char String::equals(const String &s2) const
446 return (len == s2.len && compareTo(s2) == 0);
449 unsigned char String::equals(const char *cstr) const
451 if (len == 0) return (cstr == NULL || *cstr == 0);
452 if (cstr == NULL) return buffer[0] == 0;
453 return strcmp(buffer, cstr) == 0;
456 unsigned char String::operator<(const String &rhs) const
458 return compareTo(rhs) < 0;
461 unsigned char String::operator>(const String &rhs) const
463 return compareTo(rhs) > 0;
466 unsigned char String::operator<=(const String &rhs) const
468 return compareTo(rhs) <= 0;
471 unsigned char String::operator>=(const String &rhs) const
473 return compareTo(rhs) >= 0;
476 unsigned char String::equalsIgnoreCase( const String &s2 ) const
478 if (this == &s2) return 1;
479 if (len != s2.len) return 0;
480 if (len == 0) return 1;
481 const char *p1 = buffer;
482 const char *p2 = s2.buffer;
484 if (tolower(*p1++) != tolower(*p2++)) return 0;
489 unsigned char String::startsWith( const String &s2 ) const
491 if (len < s2.len) return 0;
492 return startsWith(s2, 0);
495 unsigned char String::startsWith( const String &s2, unsigned int offset ) const
497 if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
498 return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
501 unsigned char String::endsWith( const String &s2 ) const
503 if ( len < s2.len || !buffer || !s2.buffer) return 0;
504 return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
507 /*********************************************/
508 /* Character Access */
509 /*********************************************/
511 char String::charAt(unsigned int loc) const
513 return operator[](loc);
516 void String::setCharAt(unsigned int loc, char c)
518 if (loc < len) buffer[loc] = c;
521 char & String::operator[](unsigned int index)
523 static char dummy_writable_char;
524 if (index >= len || !buffer) {
525 dummy_writable_char = 0;
526 return dummy_writable_char;
528 return buffer[index];
531 char String::operator[]( unsigned int index ) const
533 if (index >= len || !buffer) return 0;
534 return buffer[index];
537 void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
539 if (!bufsize || !buf) return;
544 unsigned int n = bufsize - 1;
545 if (n > len - index) n = len - index;
546 strncpy((char *)buf, buffer + index, n);
550 /*********************************************/
552 /*********************************************/
554 int String::indexOf(char c) const
556 return indexOf(c, 0);
559 int String::indexOf( char ch, unsigned int fromIndex ) const
561 if (fromIndex >= len) return -1;
562 const char* temp = strchr(buffer + fromIndex, ch);
563 if (temp == NULL) return -1;
564 return temp - buffer;
567 int String::indexOf(const String &s2) const
569 return indexOf(s2, 0);
572 int String::indexOf(const String &s2, unsigned int fromIndex) const
574 if (fromIndex >= len) return -1;
575 const char *found = strstr(buffer + fromIndex, s2.buffer);
576 if (found == NULL) return -1;
577 return found - buffer;
580 int String::lastIndexOf( char theChar ) const
582 return lastIndexOf(theChar, len - 1);
585 int String::lastIndexOf(char ch, unsigned int fromIndex) const
587 if (fromIndex >= len) return -1;
588 char tempchar = buffer[fromIndex + 1];
589 buffer[fromIndex + 1] = '\0';
590 char* temp = strrchr( buffer, ch );
591 buffer[fromIndex + 1] = tempchar;
592 if (temp == NULL) return -1;
593 return temp - buffer;
596 int String::lastIndexOf(const String &s2) const
598 return lastIndexOf(s2, len - s2.len);
601 int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
603 if (s2.len == 0 || len == 0 || s2.len > len) return -1;
604 if (fromIndex >= len) fromIndex = len - 1;
606 for (char *p = buffer; p <= buffer + fromIndex; p++) {
607 p = strstr(p, s2.buffer);
609 if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
614 String String::substring(unsigned int left, unsigned int right) const
617 unsigned int temp = right;
622 if (left >= len) return out;
623 if (right > len) right = len;
624 char temp = buffer[right]; // save the replaced character
625 buffer[right] = '\0';
626 out = buffer + left; // pointer arithmetic
627 buffer[right] = temp; //restore character
631 /*********************************************/
633 /*********************************************/
635 void String::replace(char find, char replace)
638 for (char *p = buffer; *p; p++) {
639 if (*p == find) *p = replace;
643 void String::replace(const String& find, const String& replace)
645 if (len == 0 || find.len == 0) return;
646 int diff = replace.len - find.len;
647 char *readFrom = buffer;
650 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
651 memcpy(foundAt, replace.buffer, replace.len);
652 readFrom = foundAt + replace.len;
654 } else if (diff < 0) {
655 char *writeTo = buffer;
656 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
657 unsigned int n = foundAt - readFrom;
658 memcpy(writeTo, readFrom, n);
660 memcpy(writeTo, replace.buffer, replace.len);
661 writeTo += replace.len;
662 readFrom = foundAt + find.len;
665 strcpy(writeTo, readFrom);
667 unsigned int size = len; // compute size needed for result
668 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
669 readFrom = foundAt + find.len;
672 if (size == len) return;
673 if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
675 while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
676 readFrom = buffer + index + find.len;
677 memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
680 memcpy(buffer + index, replace.buffer, replace.len);
686 void String::remove(unsigned int index){
687 // Pass the biggest integer as the count. The remove method
688 // below will take care of truncating it at the end of the
690 remove(index, (unsigned int)-1);
693 void String::remove(unsigned int index, unsigned int count){
694 if (index >= len) { return; }
695 if (count <= 0) { return; }
696 if (count > len - index) { count = len - index; }
697 char *writeTo = buffer + index;
699 strncpy(writeTo, buffer + index + count,len - index);
703 void String::toLowerCase(void)
706 for (char *p = buffer; *p; p++) {
711 void String::toUpperCase(void)
714 for (char *p = buffer; *p; p++) {
719 void String::trim(void)
721 if (!buffer || len == 0) return;
722 char *begin = buffer;
723 while (isspace(*begin)) begin++;
724 char *end = buffer + len - 1;
725 while (isspace(*end) && end >= begin) end--;
726 len = end + 1 - begin;
727 if (begin > buffer) memcpy(buffer, begin, len);
731 /*********************************************/
732 /* Parsing / Conversion */
733 /*********************************************/
735 long String::toInt(void) const
737 if (buffer) return atol(buffer);
741 float String::toFloat(void) const
743 return float(toDouble());
746 double String::toDouble(void) const
748 if (buffer) return atof(buffer);