From 0676263db5147e87f7e0f3afb9340fca9f02b443 Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Fri, 22 Apr 2016 08:08:01 +0200 Subject: [PATCH 1/6] a lot of new functionality void trim(void); void trim(char remove); void trimStart(void); void trimStart(char remove); void trimEnd(void); void trimEnd(char remove); void padLeft(unsigned int newlength); void padLeft(unsigned int newlength, char add); void padRight(unsigned int newlength); void padRight(unsigned int newlength, char add); void cropLeft(unsigned int count); void cropRight(unsigned int count); void keepLeft(unsigned int count); void keepRight(unsigned int count); also: // modification // notice: void function (...) operates on the object and returns void // String functionC (...) operates on a copy of the object and returns the copy (C=Copy) // String* functionS (...) operates on the object and returns a pointer to the object (S=Self) void replace (char find, char replace); String replaceC(char find, char replace); String* replaceS(char find, char replace); void replace (const --- .../arduino/avr/cores/arduino/WString.cpp | 520 ++++++++++++++++-- hardware/arduino/avr/cores/arduino/WString.h | 74 ++- 2 files changed, 554 insertions(+), 40 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/WString.cpp b/hardware/arduino/avr/cores/arduino/WString.cpp index cd3e0e876d0..e840064768a 100644 --- a/hardware/arduino/avr/cores/arduino/WString.cpp +++ b/hardware/arduino/avr/cores/arduino/WString.cpp @@ -214,10 +214,10 @@ void String::move(String &rhs) String & String::operator = (const String &rhs) { if (this == &rhs) return *this; - + if (rhs.buffer) copy(rhs.buffer, rhs.len); else invalidate(); - + return *this; } @@ -239,7 +239,7 @@ String & String::operator = (const char *cstr) { if (cstr) copy(cstr, strlen(cstr)); else invalidate(); - + return *this; } @@ -482,7 +482,7 @@ unsigned char String::equalsIgnoreCase( const String &s2 ) const const char *p2 = s2.buffer; while (*p1) { if (tolower(*p1++) != tolower(*p2++)) return 0; - } + } return 1; } @@ -513,7 +513,7 @@ char String::charAt(unsigned int loc) const return operator[](loc); } -void String::setCharAt(unsigned int loc, char c) +void String::setCharAt(unsigned int loc, char c) { if (loc < len) buffer[loc] = c; } @@ -622,7 +622,7 @@ String String::substring(unsigned int left, unsigned int right) const if (left >= len) return out; if (right > len) right = len; char temp = buffer[right]; // save the replaced character - buffer[right] = '\0'; + buffer[right] = '\0'; out = buffer + left; // pointer arithmetic buffer[right] = temp; //restore character return out; @@ -632,26 +632,51 @@ String String::substring(unsigned int left, unsigned int right) const /* Modification */ /*********************************************/ -void String::replace(char find, char replace) +//---------------------------------------- +// replace (char, char) +//---------------------------------------- +void String::replace (char find, char replacement) { if (!buffer) return; for (char *p = buffer; *p; p++) { - if (*p == find) *p = replace; + if (*p == find) *p = replacement; } } -void String::replace(const String& find, const String& replace) +//---------------------------------------- +String String::replaceC (char find, char replacement) +{ + String str (*this); + str.replace (find, replacement); + return str; +} + +//---------------------------------------- +String* String::replaceS (char find, char replacement) +{ + replace (find, replacement); + return this; +} + +//---------------------------------------- +// replace (const String&, const String&) +//---------------------------------------- +void String::replace (const String& find, const String& replace) { if (len == 0 || find.len == 0) return; int diff = replace.len - find.len; char *readFrom = buffer; char *foundAt; - if (diff == 0) { + + if (diff == 0) + { while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { memcpy(foundAt, replace.buffer, replace.len); readFrom = foundAt + replace.len; } - } else if (diff < 0) { + } + else if (diff < 0) + { char *writeTo = buffer; while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { unsigned int n = foundAt - readFrom; @@ -663,7 +688,9 @@ void String::replace(const String& find, const String& replace) len += diff; } strcpy(writeTo, readFrom); - } else { + } + else + { unsigned int size = len; // compute size needed for result while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { readFrom = foundAt + find.len; @@ -683,24 +710,80 @@ void String::replace(const String& find, const String& replace) } } -void String::remove(unsigned int index){ +//---------------------------------------- +String String::replaceC (const String& find, const String& replacement) +{ + String str (*this); + str.replace (find, replacement); + return str; +} + +//---------------------------------------- +String* String::replaceS (const String& find, const String& replacement) +{ + replace (find, replacement); + return this; +} + +//---------------------------------------- +// remove (unsigned int) +//---------------------------------------- +void String::remove (unsigned int index) +{ // Pass the biggest integer as the count. The remove method // below will take care of truncating it at the end of the // string. - remove(index, (unsigned int)-1); + remove (index, (unsigned int)-1); } -void String::remove(unsigned int index, unsigned int count){ - if (index >= len) { return; } - if (count <= 0) { return; } - if (count > len - index) { count = len - index; } +//---------------------------------------- +String String::removeC (unsigned int index) +{ + String str (*this); + str.remove (index); + return str; +} + +//---------------------------------------- +String* String::removeS (unsigned int index) +{ + remove (index); + return this; +} + +//---------------------------------------- +// remove (unsigned int, unsigned int) +//---------------------------------------- +void String::remove (unsigned int index, unsigned int count) +{ + if (index >= len) return; + if (count <= 0) return; + if (count > len - index) count = len - index; char *writeTo = buffer + index; len = len - count; - strncpy(writeTo, buffer + index + count,len - index); + strncpy(writeTo, buffer + index + count, len - index); buffer[len] = 0; } -void String::toLowerCase(void) +//---------------------------------------- +String String::removeC (unsigned int index, unsigned int count) +{ + String str (*this); + str.remove (index, count); + return str; +} + +//---------------------------------------- +String* String::removeS (unsigned int index, unsigned int count) +{ + remove (index, count); + return this; +} + +//---------------------------------------- +// toLowerCase () +//---------------------------------------- +void String::toLowerCase (void) { if (!buffer) return; for (char *p = buffer; *p; p++) { @@ -708,7 +791,25 @@ void String::toLowerCase(void) } } -void String::toUpperCase(void) +//---------------------------------------- +String String::toLowerCaseC (void) +{ + String str (*this); + str.toLowerCase (); + return str; +} + +//---------------------------------------- +String* String::toLowerCaseS (void) +{ + toLowerCase (); + return this; +} + +//---------------------------------------- +// toUpperCase () +//---------------------------------------- +void String::toUpperCase (void) { if (!buffer) return; for (char *p = buffer; *p; p++) { @@ -716,16 +817,373 @@ void String::toUpperCase(void) } } -void String::trim(void) +//---------------------------------------- +String String::toUpperCaseC (void) { - if (!buffer || len == 0) return; - char *begin = buffer; - while (isspace(*begin)) begin++; - char *end = buffer + len - 1; - while (isspace(*end) && end >= begin) end--; - len = end + 1 - begin; - if (begin > buffer) memcpy(buffer, begin, len); - buffer[len] = 0; + String str (*this); + str.toUpperCase (); + return str; +} + +//---------------------------------------- +String* String::toUpperCaseS (void) +{ + toUpperCase (); + return this; +} + +//---------------------------------------- +// trim () +//---------------------------------------- +void String::trim (void) +{ + trim (0x20); +} + +//---------------------------------------- +String String::trimC (void) +{ + String str (*this); + str.trim(); + return str; +} + +//---------------------------------------- +String* String::trimS (void) +{ + trim (); + return this; +} + +//---------------------------------------- +// trim (char) +//---------------------------------------- +void String::trim (char remove) +{ + trimStart (remove); + trimEnd (remove); +} + +//---------------------------------------- +String String::trimC (char remove) +{ + String str (*this); + str.trim (remove); + return str; +} + +//---------------------------------------- +String* String::trimS (char remove) +{ + trim (remove); + return this; +} + +//---------------------------------------- +// trimStart () +//---------------------------------------- +void String::trimStart (void) +{ + trimStart (0x20); +} + +//---------------------------------------- +String String::trimStartC (void) +{ + String str (*this); + str.trimStart (); + return str; +} + +//---------------------------------------- +String* String::trimStartS (void) +{ + trimStart (); + return this; +} + +//---------------------------------------- +// trimStart (char) +//---------------------------------------- +void String::trimStart (char remove) +{ + if (!buffer || len == 0 || remove == 0) return; + char *begin = buffer; + while ((*begin) == remove) begin++; + len = buffer + len - begin; + if (begin > buffer) memmove (buffer, begin, len); + buffer[len] = 0; +} + +//---------------------------------------- +String String::trimStartC (char remove) +{ + String str (*this); + str.trimStart (remove); + return str; +} + +//---------------------------------------- +String* String::trimStartS (char remove) +{ + trimStart (remove); + return this; +} + +//---------------------------------------- +// trimEnd () +//---------------------------------------- +void String::trimEnd (void) +{ + trimEnd(0x20); +} + +//---------------------------------------- +String String::trimEndC (void) +{ + String str (*this); + str.trimEnd (); + return str; +} + +//---------------------------------------- +String* String::trimEndS (void) +{ + trimEnd(); + return this; +} + +//---------------------------------------- +// trimEnd (char) +//---------------------------------------- +void String::trimEnd (char remove) +{ + if (!buffer || len == 0 || remove == 0) return; + char *end = buffer + len - 1; + while ((*end) == remove && end >= buffer) end--; + len = end + 1 - buffer; + buffer[len] = 0; +} + +//---------------------------------------- +String String::trimEndC (char remove) +{ + String str (*this); + str.trimEnd (remove); + return str; +} + +//---------------------------------------- +String* String::trimEndS (char remove) +{ + trimEnd(remove); + return this; +} + +//---------------------------------------- +// padLeft (unsigned int) +//---------------------------------------- +void String::padLeft (unsigned int newlength) +{ + padLeft(newlength, 0x20); +} + +//---------------------------------------- +String String::padLeftC (unsigned int newlength) +{ + String str (*this); + str.padLeft (newlength); + return str; +} + +//---------------------------------------- +String* String::padLeftS (unsigned int newlength) +{ + padLeft (newlength); + return this; +} + +//---------------------------------------- +// padLeft (unsigned int, char) +//---------------------------------------- +void String::padLeft (unsigned int newlength, char add) +{ + if (newlength < len) newlength = len; + if (!reserve(newlength)) return; + unsigned int lenAdd = newlength - len; + char *begin = buffer + lenAdd; + memmove (begin, buffer, len); + memset (buffer, add, lenAdd); + len = newlength; + buffer[len] = 0; +} + +//---------------------------------------- +String String::padLeftC (unsigned int newlength, char add) +{ + String str (*this); + str.padLeft (newlength, add); + return str; +} + +//---------------------------------------- +String* String::padLeftS (unsigned int newlength, char add) +{ + padLeft (newlength, add); + return this; +} + +//---------------------------------------- +// padRight (unsigned int) +//---------------------------------------- +void String::padRight (unsigned int newlength) +{ + padRight (newlength, 0x20); +} + +//---------------------------------------- +String String::padRightC (unsigned int newlength) +{ + String str (*this); + str.padRight (newlength); + return str; +} + +//---------------------------------------- +String* String::padRightS (unsigned int newlength) +{ + padRight (newlength); + return this; +} + +//---------------------------------------- +// padRight (unsigned int, char) +//---------------------------------------- +void String::padRight (unsigned int newlength, char add) +{ + if (newlength < len) newlength = len; + if (!reserve(newlength)) return; + unsigned int lenAdd = newlength - len; + char *begin = buffer + len; + memset (begin, add, lenAdd); + len = newlength; + buffer[len] = 0; +} + +//---------------------------------------- +String String::padRightC (unsigned int newlength, char add) +{ + String str (*this); + str.padRight (newlength, add); + return str; +} + +//---------------------------------------- +String* String::padRightS (unsigned int newlength, char add) +{ + padRight (newlength, add); + return this; +} + +//---------------------------------------- +// cropLeft (unsigned int) +//---------------------------------------- +void String::cropLeft (unsigned int count) +{ + unsigned int lenKeep = len - count; + keepRight (lenKeep); +} + +//---------------------------------------- +String String::cropLeftC (unsigned int count) +{ + String str (*this); + str.cropLeft (count); + return str; +} + +//---------------------------------------- +String* String::cropLeftS (unsigned int count) +{ + cropLeft (count); + return this; +} + +//---------------------------------------- +// cropRight (unsigned int) +//---------------------------------------- +void String::cropRight (unsigned int count) +{ + unsigned int lenKeep = len - count; + keepLeft (lenKeep); +} + +//---------------------------------------- +String String::cropRightC (unsigned int count) +{ + String str (*this); + str.cropRight (count); + return str; +} + +//---------------------------------------- +String* String::cropRightS (unsigned int count) +{ + cropRight (count); + return this; +} + +//---------------------------------------- +// keepLeft (unsigned int) +//---------------------------------------- +void String::keepLeft (unsigned int count) +{ + if (!buffer || len == 0) return; + if (count <= len) len = count; + buffer[len] = 0; +} + +//---------------------------------------- +String String::keepLeftC (unsigned int count) +{ + String str (*this); + str.keepLeft (count); + return str; +} + +//---------------------------------------- +String* String::keepLeftS (unsigned int count) +{ + keepLeft (count); + return this; +} + +//---------------------------------------- +// keepRight (unsigned int) +//---------------------------------------- +void String::keepRight (unsigned int count) +{ + if (!buffer || len == 0) return; + if (count > len) count = len; + char *begin = buffer + len - count; + len = count; + if (begin > buffer) memmove (buffer, begin, len); + buffer[len] = 0; +} + +//---------------------------------------- +String String::keepRightC (unsigned int count) +{ + String str (*this); + str.keepRight (count); + return str; +} + +//---------------------------------------- +String* String::keepRightS (unsigned int count) +{ + keepRight (count); + return this; } /*********************************************/ @@ -742,4 +1200,4 @@ float String::toFloat(void) const { if (buffer) return float(atof(buffer)); return 0; -} +} diff --git a/hardware/arduino/avr/cores/arduino/WString.h b/hardware/arduino/avr/cores/arduino/WString.h index b7d3852ba82..5c176e29ef0 100644 --- a/hardware/arduino/avr/cores/arduino/WString.h +++ b/hardware/arduino/avr/cores/arduino/WString.h @@ -176,14 +176,70 @@ class String String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; String substring( unsigned int beginIndex, unsigned int endIndex ) const; - // modification - void replace(char find, char replace); - void replace(const String& find, const String& replace); - void remove(unsigned int index); - void remove(unsigned int index, unsigned int count); - void toLowerCase(void); - void toUpperCase(void); - void trim(void); + // modification + // notice: void function (...) operates on the object and returns void + // String functionC (...) operates on a copy of the object and returns the copy (C=Copy) + // String* functionS (...) operates on the object and returns a pointer to the object (S=Self) + void replace (char find, char replace); + String replaceC(char find, char replace); + String* replaceS(char find, char replace); + void replace (const String& find, const String& replace); + String replaceC(const String& find, const String& replace); + String* replaceS(const String& find, const String& replace); + void remove (unsigned int index); + String removeC(unsigned int index); + String* removeS(unsigned int index); + void remove (unsigned int index, unsigned int count); + String removeC(unsigned int index, unsigned int count); + String* removeS(unsigned int index, unsigned int count); + void toLowerCase (void); + String toLowerCaseC(void); + String* toLowerCaseS(void); + void toUpperCase (void); + String toUpperCaseC(void); + String* toUpperCaseS(void); + void trim (void); + String trimC(void); + String* trimS(void); + void trim (char remove); + String trimC(char remove); + String* trimS(char remove); + void trimStart (void); + String trimStartC(void); + String* trimStartS(void); + void trimStart (char remove); + String trimStartC(char remove); + String* trimStartS(char remove); + void trimEnd (void); + String trimEndC(void); + String* trimEndS(void); + void trimEnd (char remove); + String trimEndC(char remove); + String* trimEndS(char remove); + void padLeft (unsigned int newlength); + String padLeftC(unsigned int newlength); + String* padLeftS(unsigned int newlength); + void padLeft (unsigned int newlength, char add); + String padLeftC(unsigned int newlength, char add); + String* padLeftS(unsigned int newlength, char add); + void padRight (unsigned int newlength); + String padRightC(unsigned int newlength); + String* padRightS(unsigned int newlength); + void padRight (unsigned int newlength, char add); + String padRightC(unsigned int newlength, char add); + String* padRightS(unsigned int newlength, char add); + void cropLeft (unsigned int count); + String cropLeftC(unsigned int count); + String* cropLeftS(unsigned int count); + void cropRight (unsigned int count); + String cropRightC(unsigned int count); + String* cropRightS(unsigned int count); + void keepLeft (unsigned int count); + String keepLeftC(unsigned int count); + String* keepLeftS(unsigned int count); + void keepRight (unsigned int count); + String keepRightC(unsigned int count); + String* keepRightS(unsigned int count); // parsing/conversion long toInt(void) const; @@ -223,4 +279,4 @@ class StringSumHelper : public String }; #endif // __cplusplus -#endif // String_class_h +#endif // String_class_h From e99321dc2252b8315f70c2763081e4d0bd2d016b Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Fri, 22 Apr 2016 23:34:01 +0200 Subject: [PATCH 2/6] String class: reserve for realloc When the String instance is created and/or increased, a new variable "reserverPercentage" defines how much reserve to keep when resizing. --- hardware/arduino/avr/cores/arduino/WString.cpp | 15 +++++++++++++++ hardware/arduino/avr/cores/arduino/WString.h | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/hardware/arduino/avr/cores/arduino/WString.cpp b/hardware/arduino/avr/cores/arduino/WString.cpp index e840064768a..2483c3e9795 100644 --- a/hardware/arduino/avr/cores/arduino/WString.cpp +++ b/hardware/arduino/avr/cores/arduino/WString.cpp @@ -128,11 +128,14 @@ String::~String() /* Memory Management */ /*********************************************/ +unsigned char String::defaultReservePercentage = 0; + inline void String::init(void) { buffer = NULL; capacity = 0; len = 0; + reservePercentage = defaultReservePercentage; } void String::invalidate(void) @@ -145,6 +148,8 @@ void String::invalidate(void) unsigned char String::reserve(unsigned int size) { if (buffer && capacity >= size) return 1; + unsigned int minNewSize = capacity * (1.0 + (float)reservePercentage / 100.0); + if (size < minNewSize) size = minNewSize; if (changeBuffer(size)) { if (len == 0) buffer[0] = 0; return 1; @@ -152,6 +157,11 @@ unsigned char String::reserve(unsigned int size) return 0; } +void String::setReservePercentage (unsigned char percentage) +{ + reservePercentage = percentage; +} + unsigned char String::changeBuffer(unsigned int maxStrLen) { char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); @@ -163,6 +173,11 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) return 0; } +void String::setDefaultReservePercentage (unsigned char percentage) +{ + defaultReservePercentage = percentage; +} + /*********************************************/ /* Copy and Move */ /*********************************************/ diff --git a/hardware/arduino/avr/cores/arduino/WString.h b/hardware/arduino/avr/cores/arduino/WString.h index 5c176e29ef0..af15b53c0ee 100644 --- a/hardware/arduino/avr/cores/arduino/WString.h +++ b/hardware/arduino/avr/cores/arduino/WString.h @@ -78,8 +78,11 @@ class String // is left unchanged). reserve(0), if successful, will validate an // invalid string (i.e., "if (s)" will be true afterwards) unsigned char reserve(unsigned int size); + void setReservePercentage (unsigned char percentage); inline unsigned int length(void) const {return len;} + static void setDefaultReservePercentage (unsigned char percentage); + // creates a copy of the assigned value. if the value is null or // invalid, or if the memory allocation fails, the string will be // marked as invalid ("if (s)" will be false). @@ -246,9 +249,13 @@ class String float toFloat(void) const; protected: +public: char *buffer; // the actual char array unsigned int capacity; // the array length minus one (for the '\0') unsigned int len; // the String length (not counting the '\0') + unsigned char reservePercentage = 0; // the percentage of reserved buffer when creating or resizing a String + static unsigned char defaultReservePercentage; // the default value of reservePercentage + protected: void init(void); void invalidate(void); From 3cdf5463e6f717b4b474392f040aa94b46d41967 Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Sat, 23 Apr 2016 15:29:19 +0200 Subject: [PATCH 3/6] String class: constructor takes min capacity The constructors of the String class are modified to take an additional parameter 'bufferSize' which defines the minimum capacity when the memory of the buffer array is allocated. --- WString.cpp | 1281 +++++++++++++++++++++++++++++++++++++++++++++++++++ WString.h | 289 ++++++++++++ 2 files changed, 1570 insertions(+) create mode 100644 WString.cpp create mode 100644 WString.h diff --git a/WString.cpp b/WString.cpp new file mode 100644 index 00000000000..1ac9d52d44a --- /dev/null +++ b/WString.cpp @@ -0,0 +1,1281 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ +String::String(const char *cstr, unsigned int bufferSize) +{ + init(bufferSize); + if (cstr) copy(cstr, strlen(cstr)); +} + +//---------------------------------------- +String::String(const String &value, unsigned int bufferSize) +{ + init(bufferSize); + *this = value; +} + +//---------------------------------------- +String::String(const __FlashStringHelper *pstr, unsigned int bufferSize) +{ + init(bufferSize); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- +String::String(String &&rval) +{ + init(); + move(rval); +} +//---------------------------------------- +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +//---------------------------------------- +String::String(char c, unsigned int bufferSize) +{ + init(bufferSize); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +//---------------------------------------- +String::String(unsigned char value, unsigned char base, unsigned int bufferSize) +{ + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +//---------------------------------------- +String::String(int value, unsigned char base, unsigned int bufferSize) +{ + init(bufferSize); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +//---------------------------------------- +String::String(unsigned int value, unsigned char base, unsigned int bufferSize) +{ + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +//---------------------------------------- +String::String(long value, unsigned char base, unsigned int bufferSize) +{ + init(bufferSize); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +//---------------------------------------- +String::String(unsigned long value, unsigned char base, unsigned int bufferSize) +{ + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +//---------------------------------------- +String::String(float value, unsigned char decimalPlaces, unsigned int bufferSize) +{ + init(bufferSize); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +//---------------------------------------- +String::String(double value, unsigned char decimalPlaces, unsigned int bufferSize) +{ + init(bufferSize); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +//---------------------------------------- +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ +unsigned char String::defaultReservePercentage = 0; + +//---------------------------------------- +inline void String::init(unsigned int bufferSize) +{ + buffer = NULL; + capacity = 0; + len = 0; + minCapacity = bufferSize; + reservePercentage = defaultReservePercentage; +} + +//---------------------------------------- +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +//---------------------------------------- +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + unsigned int minNewSize = (capacity > 0 ? capacity : size) * (1.0 + (float)reservePercentage / 100.0); + if (size < minNewSize ) size = minNewSize; + if (size < minCapacity) size = minCapacity; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +//---------------------------------------- +void String::setReservePercentage (unsigned char percentage) +{ + reservePercentage = percentage; +} + +//---------------------------------------- +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +//---------------------------------------- +void String::setDefaultReservePercentage (unsigned char percentage) +{ + defaultReservePercentage = percentage; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +//---------------------------------------- +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +//---------------------------------------- +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +//---------------------------------------- +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +//---------------------------------------- +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +//---------------------------------------- +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +//---------------------------------------- +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +//---------------------------------------- +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +//---------------------------------------- +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +//---------------------------------------- +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +//---------------------------------------- +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +//---------------------------------------- +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +//---------------------------------------- +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +//---------------------------------------- +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +//---------------------------------------- +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +//---------------------------------------- +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +//---------------------------------------- +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +//---------------------------------------- +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +//---------------------------------------- +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +//---------------------------------------- +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +//---------------------------------------- +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +//---------------------------------------- +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +//---------------------------------------- +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +//---------------------------------------- +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +//---------------------------------------- +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +//---------------------------------------- +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +//---------------------------------------- +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +//---------------------------------------- +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +//---------------------------------------- +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +//---------------------------------------- +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +//---------------------------------------- +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +//---------------------------------------- +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +//---------------------------------------- +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +//---------------------------------------- +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +//---------------------------------------- +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +//---------------------------------------- +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +//---------------------------------------- +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +//---------------------------------------- +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +//---------------------------------------- +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +//---------------------------------------- +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +//---------------------------------------- +// replace (char, char) +//---------------------------------------- +void String::replace (char find, char replacement) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replacement; + } +} + +//---------------------------------------- +String String::replaceC (char find, char replacement) +{ + String str (*this); + str.replace (find, replacement); + return str; +} + +//---------------------------------------- +String* String::replaceS (char find, char replacement) +{ + replace (find, replacement); + return this; +} + +//---------------------------------------- +// replace (const String&, const String&) +//---------------------------------------- +void String::replace (const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + + if (diff == 0) + { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } + else if (diff < 0) + { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } + else + { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +//---------------------------------------- +String String::replaceC (const String& find, const String& replacement) +{ + String str (*this); + str.replace (find, replacement); + return str; +} + +//---------------------------------------- +String* String::replaceS (const String& find, const String& replacement) +{ + replace (find, replacement); + return this; +} + +//---------------------------------------- +// remove (unsigned int) +//---------------------------------------- +void String::remove (unsigned int index) +{ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove (index, (unsigned int)-1); +} + +//---------------------------------------- +String String::removeC (unsigned int index) +{ + String str (*this); + str.remove (index); + return str; +} + +//---------------------------------------- +String* String::removeS (unsigned int index) +{ + remove (index); + return this; +} + +//---------------------------------------- +// remove (unsigned int, unsigned int) +//---------------------------------------- +void String::remove (unsigned int index, unsigned int count) +{ + if (index >= len) return; + if (count <= 0) return; + if (count > len - index) count = len - index; + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count, len - index); + buffer[len] = 0; +} + +//---------------------------------------- +String String::removeC (unsigned int index, unsigned int count) +{ + String str (*this); + str.remove (index, count); + return str; +} + +//---------------------------------------- +String* String::removeS (unsigned int index, unsigned int count) +{ + remove (index, count); + return this; +} + +//---------------------------------------- +// toLowerCase () +//---------------------------------------- +void String::toLowerCase (void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +//---------------------------------------- +String String::toLowerCaseC (void) +{ + String str (*this); + str.toLowerCase (); + return str; +} + +//---------------------------------------- +String* String::toLowerCaseS (void) +{ + toLowerCase (); + return this; +} + +//---------------------------------------- +// toUpperCase () +//---------------------------------------- +void String::toUpperCase (void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +//---------------------------------------- +String String::toUpperCaseC (void) +{ + String str (*this); + str.toUpperCase (); + return str; +} + +//---------------------------------------- +String* String::toUpperCaseS (void) +{ + toUpperCase (); + return this; +} + +//---------------------------------------- +// trim () +//---------------------------------------- +void String::trim (void) +{ + trim (0x20); +} + +//---------------------------------------- +String String::trimC (void) +{ + String str (*this); + str.trim(); + return str; +} + +//---------------------------------------- +String* String::trimS (void) +{ + trim (); + return this; +} + +//---------------------------------------- +// trim (char) +//---------------------------------------- +void String::trim (char remove) +{ + trimStart (remove); + trimEnd (remove); +} + +//---------------------------------------- +String String::trimC (char remove) +{ + String str (*this); + str.trim (remove); + return str; +} + +//---------------------------------------- +String* String::trimS (char remove) +{ + trim (remove); + return this; +} + +//---------------------------------------- +// trimStart () +//---------------------------------------- +void String::trimStart (void) +{ + trimStart (0x20); +} + +//---------------------------------------- +String String::trimStartC (void) +{ + String str (*this); + str.trimStart (); + return str; +} + +//---------------------------------------- +String* String::trimStartS (void) +{ + trimStart (); + return this; +} + +//---------------------------------------- +// trimStart (char) +//---------------------------------------- +void String::trimStart (char remove) +{ + if (!buffer || len == 0 || remove == 0) return; + char *begin = buffer; + while ((*begin) == remove) begin++; + len = buffer + len - begin; + if (begin > buffer) memmove (buffer, begin, len); + buffer[len] = 0; +} + +//---------------------------------------- +String String::trimStartC (char remove) +{ + String str (*this); + str.trimStart (remove); + return str; +} + +//---------------------------------------- +String* String::trimStartS (char remove) +{ + trimStart (remove); + return this; +} + +//---------------------------------------- +// trimEnd () +//---------------------------------------- +void String::trimEnd (void) +{ + trimEnd(0x20); +} + +//---------------------------------------- +String String::trimEndC (void) +{ + String str (*this); + str.trimEnd (); + return str; +} + +//---------------------------------------- +String* String::trimEndS (void) +{ + trimEnd(); + return this; +} + +//---------------------------------------- +// trimEnd (char) +//---------------------------------------- +void String::trimEnd (char remove) +{ + if (!buffer || len == 0 || remove == 0) return; + char *end = buffer + len - 1; + while ((*end) == remove && end >= buffer) end--; + len = end + 1 - buffer; + buffer[len] = 0; +} + +//---------------------------------------- +String String::trimEndC (char remove) +{ + String str (*this); + str.trimEnd (remove); + return str; +} + +//---------------------------------------- +String* String::trimEndS (char remove) +{ + trimEnd(remove); + return this; +} + +//---------------------------------------- +// padLeft (unsigned int) +//---------------------------------------- +void String::padLeft (unsigned int newlength) +{ + padLeft(newlength, 0x20); +} + +//---------------------------------------- +String String::padLeftC (unsigned int newlength) +{ + String str (*this); + str.padLeft (newlength); + return str; +} + +//---------------------------------------- +String* String::padLeftS (unsigned int newlength) +{ + padLeft (newlength); + return this; +} + +//---------------------------------------- +// padLeft (unsigned int, char) +//---------------------------------------- +void String::padLeft (unsigned int newlength, char add) +{ + if (newlength < len) newlength = len; + if (!reserve(newlength)) return; + unsigned int lenAdd = newlength - len; + char *begin = buffer + lenAdd; + memmove (begin, buffer, len); + memset (buffer, add, lenAdd); + len = newlength; + buffer[len] = 0; +} + +//---------------------------------------- +String String::padLeftC (unsigned int newlength, char add) +{ + String str (*this); + str.padLeft (newlength, add); + return str; +} + +//---------------------------------------- +String* String::padLeftS (unsigned int newlength, char add) +{ + padLeft (newlength, add); + return this; +} + +//---------------------------------------- +// padRight (unsigned int) +//---------------------------------------- +void String::padRight (unsigned int newlength) +{ + padRight (newlength, 0x20); +} + +//---------------------------------------- +String String::padRightC (unsigned int newlength) +{ + String str (*this); + str.padRight (newlength); + return str; +} + +//---------------------------------------- +String* String::padRightS (unsigned int newlength) +{ + padRight (newlength); + return this; +} + +//---------------------------------------- +// padRight (unsigned int, char) +//---------------------------------------- +void String::padRight (unsigned int newlength, char add) +{ + if (newlength < len) newlength = len; + if (!reserve(newlength)) return; + unsigned int lenAdd = newlength - len; + char *begin = buffer + len; + memset (begin, add, lenAdd); + len = newlength; + buffer[len] = 0; +} + +//---------------------------------------- +String String::padRightC (unsigned int newlength, char add) +{ + String str (*this); + str.padRight (newlength, add); + return str; +} + +//---------------------------------------- +String* String::padRightS (unsigned int newlength, char add) +{ + padRight (newlength, add); + return this; +} + +//---------------------------------------- +// cropLeft (unsigned int) +//---------------------------------------- +void String::cropLeft (unsigned int count) +{ + unsigned int lenKeep = len - count; + keepRight (lenKeep); +} + +//---------------------------------------- +String String::cropLeftC (unsigned int count) +{ + String str (*this); + str.cropLeft (count); + return str; +} + +//---------------------------------------- +String* String::cropLeftS (unsigned int count) +{ + cropLeft (count); + return this; +} + +//---------------------------------------- +// cropRight (unsigned int) +//---------------------------------------- +void String::cropRight (unsigned int count) +{ + unsigned int lenKeep = len - count; + keepLeft (lenKeep); +} + +//---------------------------------------- +String String::cropRightC (unsigned int count) +{ + String str (*this); + str.cropRight (count); + return str; +} + +//---------------------------------------- +String* String::cropRightS (unsigned int count) +{ + cropRight (count); + return this; +} + +//---------------------------------------- +// keepLeft (unsigned int) +//---------------------------------------- +void String::keepLeft (unsigned int count) +{ + if (!buffer || len == 0) return; + if (count <= len) len = count; + buffer[len] = 0; +} + +//---------------------------------------- +String String::keepLeftC (unsigned int count) +{ + String str (*this); + str.keepLeft (count); + return str; +} + +//---------------------------------------- +String* String::keepLeftS (unsigned int count) +{ + keepLeft (count); + return this; +} + +//---------------------------------------- +// keepRight (unsigned int) +//---------------------------------------- +void String::keepRight (unsigned int count) +{ + if (!buffer || len == 0) return; + if (count > len) count = len; + char *begin = buffer + len - count; + len = count; + if (begin > buffer) memmove (buffer, begin, len); + buffer[len] = 0; +} + +//---------------------------------------- +String String::keepRightC (unsigned int count) +{ + String str (*this); + str.keepRight (count); + return str; +} + +//---------------------------------------- +String* String::keepRightS (unsigned int count) +{ + keepRight (count); + return this; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} diff --git a/WString.h b/WString.h new file mode 100644 index 00000000000..4e6cb5a5836 --- /dev/null +++ b/WString.h @@ -0,0 +1,289 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = "", unsigned int bufferSize = 0); + String(const String &str, unsigned int bufferSize = 0); + String(const __FlashStringHelper *str, unsigned int bufferSize = 0); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c, unsigned int bufferSize = 0); + explicit String(unsigned char, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(int, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(unsigned int, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(long, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(unsigned long, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(float, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); + explicit String(double, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + void setReservePercentage (unsigned char percentage); + inline unsigned int length(void) const {return len;} + + static void setDefaultReservePercentage (unsigned char percentage); + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr);return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + const char* begin() { return c_str(); } + const char* end() { return c_str() + length(); } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + // notice: void function (...) operates on the object and returns void + // String functionC (...) operates on a copy of the object and returns the copy (C=Copy) + // String* functionS (...) operates on the object and returns a pointer to the object (S=Self) + void replace (char find, char replace); + String replaceC(char find, char replace); + String* replaceS(char find, char replace); + void replace (const String& find, const String& replace); + String replaceC(const String& find, const String& replace); + String* replaceS(const String& find, const String& replace); + void remove (unsigned int index); + String removeC(unsigned int index); + String* removeS(unsigned int index); + void remove (unsigned int index, unsigned int count); + String removeC(unsigned int index, unsigned int count); + String* removeS(unsigned int index, unsigned int count); + void toLowerCase (void); + String toLowerCaseC(void); + String* toLowerCaseS(void); + void toUpperCase (void); + String toUpperCaseC(void); + String* toUpperCaseS(void); + void trim (void); + String trimC(void); + String* trimS(void); + void trim (char remove); + String trimC(char remove); + String* trimS(char remove); + void trimStart (void); + String trimStartC(void); + String* trimStartS(void); + void trimStart (char remove); + String trimStartC(char remove); + String* trimStartS(char remove); + void trimEnd (void); + String trimEndC(void); + String* trimEndS(void); + void trimEnd (char remove); + String trimEndC(char remove); + String* trimEndS(char remove); + void padLeft (unsigned int newlength); + String padLeftC(unsigned int newlength); + String* padLeftS(unsigned int newlength); + void padLeft (unsigned int newlength, char add); + String padLeftC(unsigned int newlength, char add); + String* padLeftS(unsigned int newlength, char add); + void padRight (unsigned int newlength); + String padRightC(unsigned int newlength); + String* padRightS(unsigned int newlength); + void padRight (unsigned int newlength, char add); + String padRightC(unsigned int newlength, char add); + String* padRightS(unsigned int newlength, char add); + void cropLeft (unsigned int count); + String cropLeftC(unsigned int count); + String* cropLeftS(unsigned int count); + void cropRight (unsigned int count); + String cropRightC(unsigned int count); + String* cropRightS(unsigned int count); + void keepLeft (unsigned int count); + String keepLeftC(unsigned int count); + String* keepLeftS(unsigned int count); + void keepRight (unsigned int count); + String keepRightC(unsigned int count); + String* keepRightS(unsigned int count); + + // parsing/conversion + long toInt (void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') + unsigned int minCapacity; // the minimum value of capacity + unsigned char reservePercentage = 0; // the percentage of reserved buffer when creating or resizing a String + static unsigned char defaultReservePercentage; // the default value of reservePercentage + +protected: + void init(unsigned int bufferSize = 0); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h From e2938f68e6c4234ab071466d6731d9868cc03e0f Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Sat, 23 Apr 2016 15:39:28 +0200 Subject: [PATCH 4/6] added in the wrong folder --- WString.h | 289 ------------------------------------------------------ 1 file changed, 289 deletions(-) delete mode 100644 WString.h diff --git a/WString.h b/WString.h deleted file mode 100644 index 4e6cb5a5836..00000000000 --- a/WString.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - WString.h - String library for Wiring & Arduino - ...mostly rewritten by Paul Stoffregen... - Copyright (c) 2009-10 Hernando Barragan. All right reserved. - Copyright 2011, Paul Stoffregen, paul@pjrc.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef String_class_h -#define String_class_h -#ifdef __cplusplus - -#include -#include -#include -#include - -// When compiling programs with this class, the following gcc parameters -// dramatically increase performance and memory (RAM) efficiency, typically -// with little or no increase in code size. -// -felide-constructors -// -std=c++0x - -class __FlashStringHelper; -#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) - -// An inherited class for holding the result of a concatenation. These -// result objects are assumed to be writable by subsequent concatenations. -class StringSumHelper; - -// The string class -class String -{ - // use a function pointer to allow for "if (s)" without the - // complications of an operator bool(). for more information, see: - // http://www.artima.com/cppsource/safebool.html - typedef void (String::*StringIfHelperType)() const; - void StringIfHelper() const {} - -public: - // constructors - // creates a copy of the initial value. - // if the initial value is null or invalid, or if memory allocation - // fails, the string will be marked as invalid (i.e. "if (s)" will - // be false). - String(const char *cstr = "", unsigned int bufferSize = 0); - String(const String &str, unsigned int bufferSize = 0); - String(const __FlashStringHelper *str, unsigned int bufferSize = 0); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - String(String &&rval); - String(StringSumHelper &&rval); - #endif - explicit String(char c, unsigned int bufferSize = 0); - explicit String(unsigned char, unsigned char base=10, unsigned int bufferSize = 0); - explicit String(int, unsigned char base=10, unsigned int bufferSize = 0); - explicit String(unsigned int, unsigned char base=10, unsigned int bufferSize = 0); - explicit String(long, unsigned char base=10, unsigned int bufferSize = 0); - explicit String(unsigned long, unsigned char base=10, unsigned int bufferSize = 0); - explicit String(float, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); - explicit String(double, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); - ~String(void); - - // memory management - // return true on success, false on failure (in which case, the string - // is left unchanged). reserve(0), if successful, will validate an - // invalid string (i.e., "if (s)" will be true afterwards) - unsigned char reserve(unsigned int size); - void setReservePercentage (unsigned char percentage); - inline unsigned int length(void) const {return len;} - - static void setDefaultReservePercentage (unsigned char percentage); - - // creates a copy of the assigned value. if the value is null or - // invalid, or if the memory allocation fails, the string will be - // marked as invalid ("if (s)" will be false). - String & operator = (const String &rhs); - String & operator = (const char *cstr); - String & operator = (const __FlashStringHelper *str); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - String & operator = (String &&rval); - String & operator = (StringSumHelper &&rval); - #endif - - // concatenate (works w/ built-in types) - - // returns true on success, false on failure (in which case, the string - // is left unchanged). if the argument is null or invalid, the - // concatenation is considered unsucessful. - unsigned char concat(const String &str); - unsigned char concat(const char *cstr); - unsigned char concat(char c); - unsigned char concat(unsigned char c); - unsigned char concat(int num); - unsigned char concat(unsigned int num); - unsigned char concat(long num); - unsigned char concat(unsigned long num); - unsigned char concat(float num); - unsigned char concat(double num); - unsigned char concat(const __FlashStringHelper * str); - - // if there's not enough memory for the concatenated value, the string - // will be left unchanged (but this isn't signalled in any way) - String & operator += (const String &rhs) {concat(rhs); return (*this);} - String & operator += (const char *cstr) {concat(cstr);return (*this);} - String & operator += (char c) {concat(c); return (*this);} - String & operator += (unsigned char num) {concat(num); return (*this);} - String & operator += (int num) {concat(num); return (*this);} - String & operator += (unsigned int num) {concat(num); return (*this);} - String & operator += (long num) {concat(num); return (*this);} - String & operator += (unsigned long num) {concat(num); return (*this);} - String & operator += (float num) {concat(num); return (*this);} - String & operator += (double num) {concat(num); return (*this);} - String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} - - friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); - friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); - friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); - - // comparison (only works w/ Strings and "strings") - operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } - int compareTo(const String &s) const; - unsigned char equals(const String &s) const; - unsigned char equals(const char *cstr) const; - unsigned char operator == (const String &rhs) const {return equals(rhs);} - unsigned char operator == (const char *cstr) const {return equals(cstr);} - unsigned char operator != (const String &rhs) const {return !equals(rhs);} - unsigned char operator != (const char *cstr) const {return !equals(cstr);} - unsigned char operator < (const String &rhs) const; - unsigned char operator > (const String &rhs) const; - unsigned char operator <= (const String &rhs) const; - unsigned char operator >= (const String &rhs) const; - unsigned char equalsIgnoreCase(const String &s) const; - unsigned char startsWith( const String &prefix) const; - unsigned char startsWith(const String &prefix, unsigned int offset) const; - unsigned char endsWith(const String &suffix) const; - - // character acccess - char charAt(unsigned int index) const; - void setCharAt(unsigned int index, char c); - char operator [] (unsigned int index) const; - char& operator [] (unsigned int index); - void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; - void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const - {getBytes((unsigned char *)buf, bufsize, index);} - const char * c_str() const { return buffer; } - const char* begin() { return c_str(); } - const char* end() { return c_str() + length(); } - - // search - int indexOf( char ch ) const; - int indexOf( char ch, unsigned int fromIndex ) const; - int indexOf( const String &str ) const; - int indexOf( const String &str, unsigned int fromIndex ) const; - int lastIndexOf( char ch ) const; - int lastIndexOf( char ch, unsigned int fromIndex ) const; - int lastIndexOf( const String &str ) const; - int lastIndexOf( const String &str, unsigned int fromIndex ) const; - String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; - String substring( unsigned int beginIndex, unsigned int endIndex ) const; - - // modification - // notice: void function (...) operates on the object and returns void - // String functionC (...) operates on a copy of the object and returns the copy (C=Copy) - // String* functionS (...) operates on the object and returns a pointer to the object (S=Self) - void replace (char find, char replace); - String replaceC(char find, char replace); - String* replaceS(char find, char replace); - void replace (const String& find, const String& replace); - String replaceC(const String& find, const String& replace); - String* replaceS(const String& find, const String& replace); - void remove (unsigned int index); - String removeC(unsigned int index); - String* removeS(unsigned int index); - void remove (unsigned int index, unsigned int count); - String removeC(unsigned int index, unsigned int count); - String* removeS(unsigned int index, unsigned int count); - void toLowerCase (void); - String toLowerCaseC(void); - String* toLowerCaseS(void); - void toUpperCase (void); - String toUpperCaseC(void); - String* toUpperCaseS(void); - void trim (void); - String trimC(void); - String* trimS(void); - void trim (char remove); - String trimC(char remove); - String* trimS(char remove); - void trimStart (void); - String trimStartC(void); - String* trimStartS(void); - void trimStart (char remove); - String trimStartC(char remove); - String* trimStartS(char remove); - void trimEnd (void); - String trimEndC(void); - String* trimEndS(void); - void trimEnd (char remove); - String trimEndC(char remove); - String* trimEndS(char remove); - void padLeft (unsigned int newlength); - String padLeftC(unsigned int newlength); - String* padLeftS(unsigned int newlength); - void padLeft (unsigned int newlength, char add); - String padLeftC(unsigned int newlength, char add); - String* padLeftS(unsigned int newlength, char add); - void padRight (unsigned int newlength); - String padRightC(unsigned int newlength); - String* padRightS(unsigned int newlength); - void padRight (unsigned int newlength, char add); - String padRightC(unsigned int newlength, char add); - String* padRightS(unsigned int newlength, char add); - void cropLeft (unsigned int count); - String cropLeftC(unsigned int count); - String* cropLeftS(unsigned int count); - void cropRight (unsigned int count); - String cropRightC(unsigned int count); - String* cropRightS(unsigned int count); - void keepLeft (unsigned int count); - String keepLeftC(unsigned int count); - String* keepLeftS(unsigned int count); - void keepRight (unsigned int count); - String keepRightC(unsigned int count); - String* keepRightS(unsigned int count); - - // parsing/conversion - long toInt (void) const; - float toFloat(void) const; - -protected: - char *buffer; // the actual char array - unsigned int capacity; // the array length minus one (for the '\0') - unsigned int len; // the String length (not counting the '\0') - unsigned int minCapacity; // the minimum value of capacity - unsigned char reservePercentage = 0; // the percentage of reserved buffer when creating or resizing a String - static unsigned char defaultReservePercentage; // the default value of reservePercentage - -protected: - void init(unsigned int bufferSize = 0); - void invalidate(void); - unsigned char changeBuffer(unsigned int maxStrLen); - unsigned char concat(const char *cstr, unsigned int length); - - // copy and move - String & copy(const char *cstr, unsigned int length); - String & copy(const __FlashStringHelper *pstr, unsigned int length); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - void move(String &rhs); - #endif -}; - -class StringSumHelper : public String -{ -public: - StringSumHelper(const String &s) : String(s) {} - StringSumHelper(const char *p) : String(p) {} - StringSumHelper(char c) : String(c) {} - StringSumHelper(unsigned char num) : String(num) {} - StringSumHelper(int num) : String(num) {} - StringSumHelper(unsigned int num) : String(num) {} - StringSumHelper(long num) : String(num) {} - StringSumHelper(unsigned long num) : String(num) {} - StringSumHelper(float num) : String(num) {} - StringSumHelper(double num) : String(num) {} -}; - -#endif // __cplusplus -#endif // String_class_h From 8a49cb87516abe64b894d2a27324e33fab69ca5a Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Sat, 23 Apr 2016 15:39:50 +0200 Subject: [PATCH 5/6] added in the wrong folder --- WString.cpp | 1281 --------------------------------------------------- 1 file changed, 1281 deletions(-) delete mode 100644 WString.cpp diff --git a/WString.cpp b/WString.cpp deleted file mode 100644 index 1ac9d52d44a..00000000000 --- a/WString.cpp +++ /dev/null @@ -1,1281 +0,0 @@ -/* - WString.cpp - String library for Wiring & Arduino - ...mostly rewritten by Paul Stoffregen... - Copyright (c) 2009-10 Hernando Barragan. All rights reserved. - Copyright 2011, Paul Stoffregen, paul@pjrc.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "WString.h" - -/*********************************************/ -/* Constructors */ -/*********************************************/ -String::String(const char *cstr, unsigned int bufferSize) -{ - init(bufferSize); - if (cstr) copy(cstr, strlen(cstr)); -} - -//---------------------------------------- -String::String(const String &value, unsigned int bufferSize) -{ - init(bufferSize); - *this = value; -} - -//---------------------------------------- -String::String(const __FlashStringHelper *pstr, unsigned int bufferSize) -{ - init(bufferSize); - *this = pstr; -} - -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) -//---------------------------------------- -String::String(String &&rval) -{ - init(); - move(rval); -} -//---------------------------------------- -String::String(StringSumHelper &&rval) -{ - init(); - move(rval); -} -#endif - -//---------------------------------------- -String::String(char c, unsigned int bufferSize) -{ - init(bufferSize); - char buf[2]; - buf[0] = c; - buf[1] = 0; - *this = buf; -} - -//---------------------------------------- -String::String(unsigned char value, unsigned char base, unsigned int bufferSize) -{ - init(bufferSize); - char buf[1 + 8 * sizeof(unsigned char)]; - utoa(value, buf, base); - *this = buf; -} - -//---------------------------------------- -String::String(int value, unsigned char base, unsigned int bufferSize) -{ - init(bufferSize); - char buf[2 + 8 * sizeof(int)]; - itoa(value, buf, base); - *this = buf; -} - -//---------------------------------------- -String::String(unsigned int value, unsigned char base, unsigned int bufferSize) -{ - init(bufferSize); - char buf[1 + 8 * sizeof(unsigned int)]; - utoa(value, buf, base); - *this = buf; -} - -//---------------------------------------- -String::String(long value, unsigned char base, unsigned int bufferSize) -{ - init(bufferSize); - char buf[2 + 8 * sizeof(long)]; - ltoa(value, buf, base); - *this = buf; -} - -//---------------------------------------- -String::String(unsigned long value, unsigned char base, unsigned int bufferSize) -{ - init(bufferSize); - char buf[1 + 8 * sizeof(unsigned long)]; - ultoa(value, buf, base); - *this = buf; -} - -//---------------------------------------- -String::String(float value, unsigned char decimalPlaces, unsigned int bufferSize) -{ - init(bufferSize); - char buf[33]; - *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); -} - -//---------------------------------------- -String::String(double value, unsigned char decimalPlaces, unsigned int bufferSize) -{ - init(bufferSize); - char buf[33]; - *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); -} - -//---------------------------------------- -String::~String() -{ - free(buffer); -} - -/*********************************************/ -/* Memory Management */ -/*********************************************/ -unsigned char String::defaultReservePercentage = 0; - -//---------------------------------------- -inline void String::init(unsigned int bufferSize) -{ - buffer = NULL; - capacity = 0; - len = 0; - minCapacity = bufferSize; - reservePercentage = defaultReservePercentage; -} - -//---------------------------------------- -void String::invalidate(void) -{ - if (buffer) free(buffer); - buffer = NULL; - capacity = len = 0; -} - -//---------------------------------------- -unsigned char String::reserve(unsigned int size) -{ - if (buffer && capacity >= size) return 1; - unsigned int minNewSize = (capacity > 0 ? capacity : size) * (1.0 + (float)reservePercentage / 100.0); - if (size < minNewSize ) size = minNewSize; - if (size < minCapacity) size = minCapacity; - if (changeBuffer(size)) { - if (len == 0) buffer[0] = 0; - return 1; - } - return 0; -} - -//---------------------------------------- -void String::setReservePercentage (unsigned char percentage) -{ - reservePercentage = percentage; -} - -//---------------------------------------- -unsigned char String::changeBuffer(unsigned int maxStrLen) -{ - char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); - if (newbuffer) { - buffer = newbuffer; - capacity = maxStrLen; - return 1; - } - return 0; -} - -//---------------------------------------- -void String::setDefaultReservePercentage (unsigned char percentage) -{ - defaultReservePercentage = percentage; -} - -/*********************************************/ -/* Copy and Move */ -/*********************************************/ -String & String::copy(const char *cstr, unsigned int length) -{ - if (!reserve(length)) { - invalidate(); - return *this; - } - len = length; - strcpy(buffer, cstr); - return *this; -} - -//---------------------------------------- -String & String::copy(const __FlashStringHelper *pstr, unsigned int length) -{ - if (!reserve(length)) { - invalidate(); - return *this; - } - len = length; - strcpy_P(buffer, (PGM_P)pstr); - return *this; -} - -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) -//---------------------------------------- -void String::move(String &rhs) -{ - if (buffer) { - if (capacity >= rhs.len) { - strcpy(buffer, rhs.buffer); - len = rhs.len; - rhs.len = 0; - return; - } else { - free(buffer); - } - } - buffer = rhs.buffer; - capacity = rhs.capacity; - len = rhs.len; - rhs.buffer = NULL; - rhs.capacity = 0; - rhs.len = 0; -} -#endif - -//---------------------------------------- -String & String::operator = (const String &rhs) -{ - if (this == &rhs) return *this; - - if (rhs.buffer) copy(rhs.buffer, rhs.len); - else invalidate(); - - return *this; -} - -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) -//---------------------------------------- -String & String::operator = (String &&rval) -{ - if (this != &rval) move(rval); - return *this; -} - -//---------------------------------------- -String & String::operator = (StringSumHelper &&rval) -{ - if (this != &rval) move(rval); - return *this; -} -#endif - -//---------------------------------------- -String & String::operator = (const char *cstr) -{ - if (cstr) copy(cstr, strlen(cstr)); - else invalidate(); - - return *this; -} - -//---------------------------------------- -String & String::operator = (const __FlashStringHelper *pstr) -{ - if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); - else invalidate(); - - return *this; -} - -/*********************************************/ -/* concat */ -/*********************************************/ -unsigned char String::concat(const String &s) -{ - return concat(s.buffer, s.len); -} - -//---------------------------------------- -unsigned char String::concat(const char *cstr, unsigned int length) -{ - unsigned int newlen = len + length; - if (!cstr) return 0; - if (length == 0) return 1; - if (!reserve(newlen)) return 0; - strcpy(buffer + len, cstr); - len = newlen; - return 1; -} - -//---------------------------------------- -unsigned char String::concat(const char *cstr) -{ - if (!cstr) return 0; - return concat(cstr, strlen(cstr)); -} - -//---------------------------------------- -unsigned char String::concat(char c) -{ - char buf[2]; - buf[0] = c; - buf[1] = 0; - return concat(buf, 1); -} - -//---------------------------------------- -unsigned char String::concat(unsigned char num) -{ - char buf[1 + 3 * sizeof(unsigned char)]; - itoa(num, buf, 10); - return concat(buf, strlen(buf)); -} - -//---------------------------------------- -unsigned char String::concat(int num) -{ - char buf[2 + 3 * sizeof(int)]; - itoa(num, buf, 10); - return concat(buf, strlen(buf)); -} - -//---------------------------------------- -unsigned char String::concat(unsigned int num) -{ - char buf[1 + 3 * sizeof(unsigned int)]; - utoa(num, buf, 10); - return concat(buf, strlen(buf)); -} - -//---------------------------------------- -unsigned char String::concat(long num) -{ - char buf[2 + 3 * sizeof(long)]; - ltoa(num, buf, 10); - return concat(buf, strlen(buf)); -} - -//---------------------------------------- -unsigned char String::concat(unsigned long num) -{ - char buf[1 + 3 * sizeof(unsigned long)]; - ultoa(num, buf, 10); - return concat(buf, strlen(buf)); -} - -//---------------------------------------- -unsigned char String::concat(float num) -{ - char buf[20]; - char* string = dtostrf(num, 4, 2, buf); - return concat(string, strlen(string)); -} - -//---------------------------------------- -unsigned char String::concat(double num) -{ - char buf[20]; - char* string = dtostrf(num, 4, 2, buf); - return concat(string, strlen(string)); -} - -//---------------------------------------- -unsigned char String::concat(const __FlashStringHelper * str) -{ - if (!str) return 0; - int length = strlen_P((const char *) str); - if (length == 0) return 1; - unsigned int newlen = len + length; - if (!reserve(newlen)) return 0; - strcpy_P(buffer + len, (const char *) str); - len = newlen; - return 1; -} - -/*********************************************/ -/* Concatenate */ -/*********************************************/ -StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) -{ - StringSumHelper &a = const_cast(lhs); - if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, char c) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(c)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, int num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, long num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, float num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, double num) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; -} - -//---------------------------------------- -StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) -{ - StringSumHelper &a = const_cast(lhs); - if (!a.concat(rhs)) a.invalidate(); - return a; -} - -/*********************************************/ -/* Comparison */ -/*********************************************/ -int String::compareTo(const String &s) const -{ - if (!buffer || !s.buffer) { - if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; - if (buffer && len > 0) return *(unsigned char *)buffer; - return 0; - } - return strcmp(buffer, s.buffer); -} - -//---------------------------------------- -unsigned char String::equals(const String &s2) const -{ - return (len == s2.len && compareTo(s2) == 0); -} - -//---------------------------------------- -unsigned char String::equals(const char *cstr) const -{ - if (len == 0) return (cstr == NULL || *cstr == 0); - if (cstr == NULL) return buffer[0] == 0; - return strcmp(buffer, cstr) == 0; -} - -//---------------------------------------- -unsigned char String::operator<(const String &rhs) const -{ - return compareTo(rhs) < 0; -} - -//---------------------------------------- -unsigned char String::operator>(const String &rhs) const -{ - return compareTo(rhs) > 0; -} - -//---------------------------------------- -unsigned char String::operator<=(const String &rhs) const -{ - return compareTo(rhs) <= 0; -} - -//---------------------------------------- -unsigned char String::operator>=(const String &rhs) const -{ - return compareTo(rhs) >= 0; -} - -//---------------------------------------- -unsigned char String::equalsIgnoreCase( const String &s2 ) const -{ - if (this == &s2) return 1; - if (len != s2.len) return 0; - if (len == 0) return 1; - const char *p1 = buffer; - const char *p2 = s2.buffer; - while (*p1) { - if (tolower(*p1++) != tolower(*p2++)) return 0; - } - return 1; -} - -//---------------------------------------- -unsigned char String::startsWith( const String &s2 ) const -{ - if (len < s2.len) return 0; - return startsWith(s2, 0); -} - -//---------------------------------------- -unsigned char String::startsWith( const String &s2, unsigned int offset ) const -{ - if (offset > len - s2.len || !buffer || !s2.buffer) return 0; - return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; -} - -//---------------------------------------- -unsigned char String::endsWith( const String &s2 ) const -{ - if ( len < s2.len || !buffer || !s2.buffer) return 0; - return strcmp(&buffer[len - s2.len], s2.buffer) == 0; -} - -/*********************************************/ -/* Character Access */ -/*********************************************/ -char String::charAt(unsigned int loc) const -{ - return operator[](loc); -} - -//---------------------------------------- -void String::setCharAt(unsigned int loc, char c) -{ - if (loc < len) buffer[loc] = c; -} - -//---------------------------------------- -char & String::operator[](unsigned int index) -{ - static char dummy_writable_char; - if (index >= len || !buffer) { - dummy_writable_char = 0; - return dummy_writable_char; - } - return buffer[index]; -} - -//---------------------------------------- -char String::operator[]( unsigned int index ) const -{ - if (index >= len || !buffer) return 0; - return buffer[index]; -} - -//---------------------------------------- -void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const -{ - if (!bufsize || !buf) return; - if (index >= len) { - buf[0] = 0; - return; - } - unsigned int n = bufsize - 1; - if (n > len - index) n = len - index; - strncpy((char *)buf, buffer + index, n); - buf[n] = 0; -} - -/*********************************************/ -/* Search */ -/*********************************************/ -int String::indexOf(char c) const -{ - return indexOf(c, 0); -} - -//---------------------------------------- -int String::indexOf( char ch, unsigned int fromIndex ) const -{ - if (fromIndex >= len) return -1; - const char* temp = strchr(buffer + fromIndex, ch); - if (temp == NULL) return -1; - return temp - buffer; -} - -//---------------------------------------- -int String::indexOf(const String &s2) const -{ - return indexOf(s2, 0); -} - -//---------------------------------------- -int String::indexOf(const String &s2, unsigned int fromIndex) const -{ - if (fromIndex >= len) return -1; - const char *found = strstr(buffer + fromIndex, s2.buffer); - if (found == NULL) return -1; - return found - buffer; -} - -//---------------------------------------- -int String::lastIndexOf( char theChar ) const -{ - return lastIndexOf(theChar, len - 1); -} - -//---------------------------------------- -int String::lastIndexOf(char ch, unsigned int fromIndex) const -{ - if (fromIndex >= len) return -1; - char tempchar = buffer[fromIndex + 1]; - buffer[fromIndex + 1] = '\0'; - char* temp = strrchr( buffer, ch ); - buffer[fromIndex + 1] = tempchar; - if (temp == NULL) return -1; - return temp - buffer; -} - -//---------------------------------------- -int String::lastIndexOf(const String &s2) const -{ - return lastIndexOf(s2, len - s2.len); -} - -//---------------------------------------- -int String::lastIndexOf(const String &s2, unsigned int fromIndex) const -{ - if (s2.len == 0 || len == 0 || s2.len > len) return -1; - if (fromIndex >= len) fromIndex = len - 1; - int found = -1; - for (char *p = buffer; p <= buffer + fromIndex; p++) { - p = strstr(p, s2.buffer); - if (!p) break; - if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; - } - return found; -} - -//---------------------------------------- -String String::substring(unsigned int left, unsigned int right) const -{ - if (left > right) { - unsigned int temp = right; - right = left; - left = temp; - } - String out; - if (left >= len) return out; - if (right > len) right = len; - char temp = buffer[right]; // save the replaced character - buffer[right] = '\0'; - out = buffer + left; // pointer arithmetic - buffer[right] = temp; //restore character - return out; -} - -/*********************************************/ -/* Modification */ -/*********************************************/ - -//---------------------------------------- -// replace (char, char) -//---------------------------------------- -void String::replace (char find, char replacement) -{ - if (!buffer) return; - for (char *p = buffer; *p; p++) { - if (*p == find) *p = replacement; - } -} - -//---------------------------------------- -String String::replaceC (char find, char replacement) -{ - String str (*this); - str.replace (find, replacement); - return str; -} - -//---------------------------------------- -String* String::replaceS (char find, char replacement) -{ - replace (find, replacement); - return this; -} - -//---------------------------------------- -// replace (const String&, const String&) -//---------------------------------------- -void String::replace (const String& find, const String& replace) -{ - if (len == 0 || find.len == 0) return; - int diff = replace.len - find.len; - char *readFrom = buffer; - char *foundAt; - - if (diff == 0) - { - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - memcpy(foundAt, replace.buffer, replace.len); - readFrom = foundAt + replace.len; - } - } - else if (diff < 0) - { - char *writeTo = buffer; - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - unsigned int n = foundAt - readFrom; - memcpy(writeTo, readFrom, n); - writeTo += n; - memcpy(writeTo, replace.buffer, replace.len); - writeTo += replace.len; - readFrom = foundAt + find.len; - len += diff; - } - strcpy(writeTo, readFrom); - } - else - { - unsigned int size = len; // compute size needed for result - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - readFrom = foundAt + find.len; - size += diff; - } - if (size == len) return; - if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! - int index = len - 1; - while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { - readFrom = buffer + index + find.len; - memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); - len += diff; - buffer[len] = 0; - memcpy(buffer + index, replace.buffer, replace.len); - index--; - } - } -} - -//---------------------------------------- -String String::replaceC (const String& find, const String& replacement) -{ - String str (*this); - str.replace (find, replacement); - return str; -} - -//---------------------------------------- -String* String::replaceS (const String& find, const String& replacement) -{ - replace (find, replacement); - return this; -} - -//---------------------------------------- -// remove (unsigned int) -//---------------------------------------- -void String::remove (unsigned int index) -{ - // Pass the biggest integer as the count. The remove method - // below will take care of truncating it at the end of the - // string. - remove (index, (unsigned int)-1); -} - -//---------------------------------------- -String String::removeC (unsigned int index) -{ - String str (*this); - str.remove (index); - return str; -} - -//---------------------------------------- -String* String::removeS (unsigned int index) -{ - remove (index); - return this; -} - -//---------------------------------------- -// remove (unsigned int, unsigned int) -//---------------------------------------- -void String::remove (unsigned int index, unsigned int count) -{ - if (index >= len) return; - if (count <= 0) return; - if (count > len - index) count = len - index; - char *writeTo = buffer + index; - len = len - count; - strncpy(writeTo, buffer + index + count, len - index); - buffer[len] = 0; -} - -//---------------------------------------- -String String::removeC (unsigned int index, unsigned int count) -{ - String str (*this); - str.remove (index, count); - return str; -} - -//---------------------------------------- -String* String::removeS (unsigned int index, unsigned int count) -{ - remove (index, count); - return this; -} - -//---------------------------------------- -// toLowerCase () -//---------------------------------------- -void String::toLowerCase (void) -{ - if (!buffer) return; - for (char *p = buffer; *p; p++) { - *p = tolower(*p); - } -} - -//---------------------------------------- -String String::toLowerCaseC (void) -{ - String str (*this); - str.toLowerCase (); - return str; -} - -//---------------------------------------- -String* String::toLowerCaseS (void) -{ - toLowerCase (); - return this; -} - -//---------------------------------------- -// toUpperCase () -//---------------------------------------- -void String::toUpperCase (void) -{ - if (!buffer) return; - for (char *p = buffer; *p; p++) { - *p = toupper(*p); - } -} - -//---------------------------------------- -String String::toUpperCaseC (void) -{ - String str (*this); - str.toUpperCase (); - return str; -} - -//---------------------------------------- -String* String::toUpperCaseS (void) -{ - toUpperCase (); - return this; -} - -//---------------------------------------- -// trim () -//---------------------------------------- -void String::trim (void) -{ - trim (0x20); -} - -//---------------------------------------- -String String::trimC (void) -{ - String str (*this); - str.trim(); - return str; -} - -//---------------------------------------- -String* String::trimS (void) -{ - trim (); - return this; -} - -//---------------------------------------- -// trim (char) -//---------------------------------------- -void String::trim (char remove) -{ - trimStart (remove); - trimEnd (remove); -} - -//---------------------------------------- -String String::trimC (char remove) -{ - String str (*this); - str.trim (remove); - return str; -} - -//---------------------------------------- -String* String::trimS (char remove) -{ - trim (remove); - return this; -} - -//---------------------------------------- -// trimStart () -//---------------------------------------- -void String::trimStart (void) -{ - trimStart (0x20); -} - -//---------------------------------------- -String String::trimStartC (void) -{ - String str (*this); - str.trimStart (); - return str; -} - -//---------------------------------------- -String* String::trimStartS (void) -{ - trimStart (); - return this; -} - -//---------------------------------------- -// trimStart (char) -//---------------------------------------- -void String::trimStart (char remove) -{ - if (!buffer || len == 0 || remove == 0) return; - char *begin = buffer; - while ((*begin) == remove) begin++; - len = buffer + len - begin; - if (begin > buffer) memmove (buffer, begin, len); - buffer[len] = 0; -} - -//---------------------------------------- -String String::trimStartC (char remove) -{ - String str (*this); - str.trimStart (remove); - return str; -} - -//---------------------------------------- -String* String::trimStartS (char remove) -{ - trimStart (remove); - return this; -} - -//---------------------------------------- -// trimEnd () -//---------------------------------------- -void String::trimEnd (void) -{ - trimEnd(0x20); -} - -//---------------------------------------- -String String::trimEndC (void) -{ - String str (*this); - str.trimEnd (); - return str; -} - -//---------------------------------------- -String* String::trimEndS (void) -{ - trimEnd(); - return this; -} - -//---------------------------------------- -// trimEnd (char) -//---------------------------------------- -void String::trimEnd (char remove) -{ - if (!buffer || len == 0 || remove == 0) return; - char *end = buffer + len - 1; - while ((*end) == remove && end >= buffer) end--; - len = end + 1 - buffer; - buffer[len] = 0; -} - -//---------------------------------------- -String String::trimEndC (char remove) -{ - String str (*this); - str.trimEnd (remove); - return str; -} - -//---------------------------------------- -String* String::trimEndS (char remove) -{ - trimEnd(remove); - return this; -} - -//---------------------------------------- -// padLeft (unsigned int) -//---------------------------------------- -void String::padLeft (unsigned int newlength) -{ - padLeft(newlength, 0x20); -} - -//---------------------------------------- -String String::padLeftC (unsigned int newlength) -{ - String str (*this); - str.padLeft (newlength); - return str; -} - -//---------------------------------------- -String* String::padLeftS (unsigned int newlength) -{ - padLeft (newlength); - return this; -} - -//---------------------------------------- -// padLeft (unsigned int, char) -//---------------------------------------- -void String::padLeft (unsigned int newlength, char add) -{ - if (newlength < len) newlength = len; - if (!reserve(newlength)) return; - unsigned int lenAdd = newlength - len; - char *begin = buffer + lenAdd; - memmove (begin, buffer, len); - memset (buffer, add, lenAdd); - len = newlength; - buffer[len] = 0; -} - -//---------------------------------------- -String String::padLeftC (unsigned int newlength, char add) -{ - String str (*this); - str.padLeft (newlength, add); - return str; -} - -//---------------------------------------- -String* String::padLeftS (unsigned int newlength, char add) -{ - padLeft (newlength, add); - return this; -} - -//---------------------------------------- -// padRight (unsigned int) -//---------------------------------------- -void String::padRight (unsigned int newlength) -{ - padRight (newlength, 0x20); -} - -//---------------------------------------- -String String::padRightC (unsigned int newlength) -{ - String str (*this); - str.padRight (newlength); - return str; -} - -//---------------------------------------- -String* String::padRightS (unsigned int newlength) -{ - padRight (newlength); - return this; -} - -//---------------------------------------- -// padRight (unsigned int, char) -//---------------------------------------- -void String::padRight (unsigned int newlength, char add) -{ - if (newlength < len) newlength = len; - if (!reserve(newlength)) return; - unsigned int lenAdd = newlength - len; - char *begin = buffer + len; - memset (begin, add, lenAdd); - len = newlength; - buffer[len] = 0; -} - -//---------------------------------------- -String String::padRightC (unsigned int newlength, char add) -{ - String str (*this); - str.padRight (newlength, add); - return str; -} - -//---------------------------------------- -String* String::padRightS (unsigned int newlength, char add) -{ - padRight (newlength, add); - return this; -} - -//---------------------------------------- -// cropLeft (unsigned int) -//---------------------------------------- -void String::cropLeft (unsigned int count) -{ - unsigned int lenKeep = len - count; - keepRight (lenKeep); -} - -//---------------------------------------- -String String::cropLeftC (unsigned int count) -{ - String str (*this); - str.cropLeft (count); - return str; -} - -//---------------------------------------- -String* String::cropLeftS (unsigned int count) -{ - cropLeft (count); - return this; -} - -//---------------------------------------- -// cropRight (unsigned int) -//---------------------------------------- -void String::cropRight (unsigned int count) -{ - unsigned int lenKeep = len - count; - keepLeft (lenKeep); -} - -//---------------------------------------- -String String::cropRightC (unsigned int count) -{ - String str (*this); - str.cropRight (count); - return str; -} - -//---------------------------------------- -String* String::cropRightS (unsigned int count) -{ - cropRight (count); - return this; -} - -//---------------------------------------- -// keepLeft (unsigned int) -//---------------------------------------- -void String::keepLeft (unsigned int count) -{ - if (!buffer || len == 0) return; - if (count <= len) len = count; - buffer[len] = 0; -} - -//---------------------------------------- -String String::keepLeftC (unsigned int count) -{ - String str (*this); - str.keepLeft (count); - return str; -} - -//---------------------------------------- -String* String::keepLeftS (unsigned int count) -{ - keepLeft (count); - return this; -} - -//---------------------------------------- -// keepRight (unsigned int) -//---------------------------------------- -void String::keepRight (unsigned int count) -{ - if (!buffer || len == 0) return; - if (count > len) count = len; - char *begin = buffer + len - count; - len = count; - if (begin > buffer) memmove (buffer, begin, len); - buffer[len] = 0; -} - -//---------------------------------------- -String String::keepRightC (unsigned int count) -{ - String str (*this); - str.keepRight (count); - return str; -} - -//---------------------------------------- -String* String::keepRightS (unsigned int count) -{ - keepRight (count); - return this; -} - -/*********************************************/ -/* Parsing / Conversion */ -/*********************************************/ - -long String::toInt(void) const -{ - if (buffer) return atol(buffer); - return 0; -} - -float String::toFloat(void) const -{ - if (buffer) return float(atof(buffer)); - return 0; -} From a78a0976193a7f15fe486d7c386f57b3601b8d61 Mon Sep 17 00:00:00 2001 From: TobiasKnauss Date: Sat, 23 Apr 2016 15:41:44 +0200 Subject: [PATCH 6/6] String class: constructor takes min capacity The constructors of the String class are modified to take an additional parameter 'bufferSize' which defines the minimum capacity when the memory of the buffer array is allocated. Whitespace tabs converted to spaces. --- .../arduino/avr/cores/arduino/WString.cpp | 779 ++++++++++-------- hardware/arduino/avr/cores/arduino/WString.h | 294 +++---- 2 files changed, 568 insertions(+), 505 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/WString.cpp b/hardware/arduino/avr/cores/arduino/WString.cpp index 2483c3e9795..1ac9d52d44a 100644 --- a/hardware/arduino/avr/cores/arduino/WString.cpp +++ b/hardware/arduino/avr/cores/arduino/WString.cpp @@ -24,155 +24,174 @@ /*********************************************/ /* Constructors */ /*********************************************/ - -String::String(const char *cstr) +String::String(const char *cstr, unsigned int bufferSize) { - init(); - if (cstr) copy(cstr, strlen(cstr)); + init(bufferSize); + if (cstr) copy(cstr, strlen(cstr)); } -String::String(const String &value) +//---------------------------------------- +String::String(const String &value, unsigned int bufferSize) { - init(); - *this = value; + init(bufferSize); + *this = value; } -String::String(const __FlashStringHelper *pstr) +//---------------------------------------- +String::String(const __FlashStringHelper *pstr, unsigned int bufferSize) { - init(); - *this = pstr; + init(bufferSize); + *this = pstr; } #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- String::String(String &&rval) { - init(); - move(rval); + init(); + move(rval); } +//---------------------------------------- String::String(StringSumHelper &&rval) { - init(); - move(rval); + init(); + move(rval); } #endif -String::String(char c) +//---------------------------------------- +String::String(char c, unsigned int bufferSize) { - init(); - char buf[2]; - buf[0] = c; - buf[1] = 0; - *this = buf; + init(bufferSize); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; } -String::String(unsigned char value, unsigned char base) +//---------------------------------------- +String::String(unsigned char value, unsigned char base, unsigned int bufferSize) { - init(); - char buf[1 + 8 * sizeof(unsigned char)]; - utoa(value, buf, base); - *this = buf; + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; } -String::String(int value, unsigned char base) +//---------------------------------------- +String::String(int value, unsigned char base, unsigned int bufferSize) { - init(); - char buf[2 + 8 * sizeof(int)]; - itoa(value, buf, base); - *this = buf; + init(bufferSize); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; } -String::String(unsigned int value, unsigned char base) +//---------------------------------------- +String::String(unsigned int value, unsigned char base, unsigned int bufferSize) { - init(); - char buf[1 + 8 * sizeof(unsigned int)]; - utoa(value, buf, base); - *this = buf; + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; } -String::String(long value, unsigned char base) +//---------------------------------------- +String::String(long value, unsigned char base, unsigned int bufferSize) { - init(); - char buf[2 + 8 * sizeof(long)]; - ltoa(value, buf, base); - *this = buf; + init(bufferSize); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; } -String::String(unsigned long value, unsigned char base) +//---------------------------------------- +String::String(unsigned long value, unsigned char base, unsigned int bufferSize) { - init(); - char buf[1 + 8 * sizeof(unsigned long)]; - ultoa(value, buf, base); - *this = buf; + init(bufferSize); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; } -String::String(float value, unsigned char decimalPlaces) +//---------------------------------------- +String::String(float value, unsigned char decimalPlaces, unsigned int bufferSize) { - init(); - char buf[33]; - *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); + init(bufferSize); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); } -String::String(double value, unsigned char decimalPlaces) +//---------------------------------------- +String::String(double value, unsigned char decimalPlaces, unsigned int bufferSize) { - init(); - char buf[33]; - *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); + init(bufferSize); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); } +//---------------------------------------- String::~String() { - free(buffer); + free(buffer); } /*********************************************/ /* Memory Management */ /*********************************************/ - unsigned char String::defaultReservePercentage = 0; -inline void String::init(void) +//---------------------------------------- +inline void String::init(unsigned int bufferSize) { - buffer = NULL; - capacity = 0; - len = 0; + buffer = NULL; + capacity = 0; + len = 0; + minCapacity = bufferSize; reservePercentage = defaultReservePercentage; } +//---------------------------------------- void String::invalidate(void) { - if (buffer) free(buffer); - buffer = NULL; - capacity = len = 0; + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; } +//---------------------------------------- unsigned char String::reserve(unsigned int size) { - if (buffer && capacity >= size) return 1; - unsigned int minNewSize = capacity * (1.0 + (float)reservePercentage / 100.0); - if (size < minNewSize) size = minNewSize; - if (changeBuffer(size)) { - if (len == 0) buffer[0] = 0; - return 1; - } - return 0; + if (buffer && capacity >= size) return 1; + unsigned int minNewSize = (capacity > 0 ? capacity : size) * (1.0 + (float)reservePercentage / 100.0); + if (size < minNewSize ) size = minNewSize; + if (size < minCapacity) size = minCapacity; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; } +//---------------------------------------- void String::setReservePercentage (unsigned char percentage) { reservePercentage = percentage; } +//---------------------------------------- unsigned char String::changeBuffer(unsigned int maxStrLen) { - char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); - if (newbuffer) { - buffer = newbuffer; - capacity = maxStrLen; - return 1; - } - return 0; + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; } +//---------------------------------------- void String::setDefaultReservePercentage (unsigned char percentage) { defaultReservePercentage = percentage; @@ -181,466 +200,510 @@ void String::setDefaultReservePercentage (unsigned char percentage) /*********************************************/ /* Copy and Move */ /*********************************************/ - String & String::copy(const char *cstr, unsigned int length) { - if (!reserve(length)) { - invalidate(); - return *this; - } - len = length; - strcpy(buffer, cstr); - return *this; + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; } +//---------------------------------------- String & String::copy(const __FlashStringHelper *pstr, unsigned int length) { - if (!reserve(length)) { - invalidate(); - return *this; - } - len = length; - strcpy_P(buffer, (PGM_P)pstr); - return *this; + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; } #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- void String::move(String &rhs) { - if (buffer) { - if (capacity >= rhs.len) { - strcpy(buffer, rhs.buffer); - len = rhs.len; - rhs.len = 0; - return; - } else { - free(buffer); - } - } - buffer = rhs.buffer; - capacity = rhs.capacity; - len = rhs.len; - rhs.buffer = NULL; - rhs.capacity = 0; - rhs.len = 0; + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; } #endif +//---------------------------------------- String & String::operator = (const String &rhs) { - if (this == &rhs) return *this; + if (this == &rhs) return *this; - if (rhs.buffer) copy(rhs.buffer, rhs.len); - else invalidate(); + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); - return *this; + return *this; } #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +//---------------------------------------- String & String::operator = (String &&rval) { - if (this != &rval) move(rval); - return *this; + if (this != &rval) move(rval); + return *this; } +//---------------------------------------- String & String::operator = (StringSumHelper &&rval) { - if (this != &rval) move(rval); - return *this; + if (this != &rval) move(rval); + return *this; } #endif +//---------------------------------------- String & String::operator = (const char *cstr) { - if (cstr) copy(cstr, strlen(cstr)); - else invalidate(); + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); - return *this; + return *this; } +//---------------------------------------- String & String::operator = (const __FlashStringHelper *pstr) { - if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); - else invalidate(); + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); - return *this; + return *this; } /*********************************************/ /* concat */ /*********************************************/ - unsigned char String::concat(const String &s) { - return concat(s.buffer, s.len); + return concat(s.buffer, s.len); } +//---------------------------------------- unsigned char String::concat(const char *cstr, unsigned int length) { - unsigned int newlen = len + length; - if (!cstr) return 0; - if (length == 0) return 1; - if (!reserve(newlen)) return 0; - strcpy(buffer + len, cstr); - len = newlen; - return 1; + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; } +//---------------------------------------- unsigned char String::concat(const char *cstr) { - if (!cstr) return 0; - return concat(cstr, strlen(cstr)); + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); } +//---------------------------------------- unsigned char String::concat(char c) { - char buf[2]; - buf[0] = c; - buf[1] = 0; - return concat(buf, 1); + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); } +//---------------------------------------- unsigned char String::concat(unsigned char num) { - char buf[1 + 3 * sizeof(unsigned char)]; - itoa(num, buf, 10); - return concat(buf, strlen(buf)); + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); } +//---------------------------------------- unsigned char String::concat(int num) { - char buf[2 + 3 * sizeof(int)]; - itoa(num, buf, 10); - return concat(buf, strlen(buf)); + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); } +//---------------------------------------- unsigned char String::concat(unsigned int num) { - char buf[1 + 3 * sizeof(unsigned int)]; - utoa(num, buf, 10); - return concat(buf, strlen(buf)); + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); } +//---------------------------------------- unsigned char String::concat(long num) { - char buf[2 + 3 * sizeof(long)]; - ltoa(num, buf, 10); - return concat(buf, strlen(buf)); + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); } +//---------------------------------------- unsigned char String::concat(unsigned long num) { - char buf[1 + 3 * sizeof(unsigned long)]; - ultoa(num, buf, 10); - return concat(buf, strlen(buf)); + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); } +//---------------------------------------- unsigned char String::concat(float num) { - char buf[20]; - char* string = dtostrf(num, 4, 2, buf); - return concat(string, strlen(string)); + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); } +//---------------------------------------- unsigned char String::concat(double num) { - char buf[20]; - char* string = dtostrf(num, 4, 2, buf); - return concat(string, strlen(string)); + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); } +//---------------------------------------- unsigned char String::concat(const __FlashStringHelper * str) { - if (!str) return 0; - int length = strlen_P((const char *) str); - if (length == 0) return 1; - unsigned int newlen = len + length; - if (!reserve(newlen)) return 0; - strcpy_P(buffer + len, (const char *) str); - len = newlen; - return 1; + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; } /*********************************************/ /* Concatenate */ /*********************************************/ - StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) { - StringSumHelper &a = const_cast(lhs); - if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, char c) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(c)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, int num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, long num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, float num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, double num) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(num)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; } +//---------------------------------------- StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) { - StringSumHelper &a = const_cast(lhs); - if (!a.concat(rhs)) a.invalidate(); - return a; + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; } /*********************************************/ /* Comparison */ /*********************************************/ - int String::compareTo(const String &s) const { - if (!buffer || !s.buffer) { - if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; - if (buffer && len > 0) return *(unsigned char *)buffer; - return 0; - } - return strcmp(buffer, s.buffer); + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); } +//---------------------------------------- unsigned char String::equals(const String &s2) const { - return (len == s2.len && compareTo(s2) == 0); + return (len == s2.len && compareTo(s2) == 0); } +//---------------------------------------- unsigned char String::equals(const char *cstr) const { - if (len == 0) return (cstr == NULL || *cstr == 0); - if (cstr == NULL) return buffer[0] == 0; - return strcmp(buffer, cstr) == 0; + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; } +//---------------------------------------- unsigned char String::operator<(const String &rhs) const { - return compareTo(rhs) < 0; + return compareTo(rhs) < 0; } +//---------------------------------------- unsigned char String::operator>(const String &rhs) const { - return compareTo(rhs) > 0; + return compareTo(rhs) > 0; } +//---------------------------------------- unsigned char String::operator<=(const String &rhs) const { - return compareTo(rhs) <= 0; + return compareTo(rhs) <= 0; } +//---------------------------------------- unsigned char String::operator>=(const String &rhs) const { - return compareTo(rhs) >= 0; + return compareTo(rhs) >= 0; } +//---------------------------------------- unsigned char String::equalsIgnoreCase( const String &s2 ) const { - if (this == &s2) return 1; - if (len != s2.len) return 0; - if (len == 0) return 1; - const char *p1 = buffer; - const char *p2 = s2.buffer; - while (*p1) { - if (tolower(*p1++) != tolower(*p2++)) return 0; - } - return 1; + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; } +//---------------------------------------- unsigned char String::startsWith( const String &s2 ) const { - if (len < s2.len) return 0; - return startsWith(s2, 0); + if (len < s2.len) return 0; + return startsWith(s2, 0); } +//---------------------------------------- unsigned char String::startsWith( const String &s2, unsigned int offset ) const { - if (offset > len - s2.len || !buffer || !s2.buffer) return 0; - return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; } +//---------------------------------------- unsigned char String::endsWith( const String &s2 ) const { - if ( len < s2.len || !buffer || !s2.buffer) return 0; - return strcmp(&buffer[len - s2.len], s2.buffer) == 0; + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; } /*********************************************/ /* Character Access */ /*********************************************/ - char String::charAt(unsigned int loc) const { - return operator[](loc); + return operator[](loc); } +//---------------------------------------- void String::setCharAt(unsigned int loc, char c) { - if (loc < len) buffer[loc] = c; + if (loc < len) buffer[loc] = c; } +//---------------------------------------- char & String::operator[](unsigned int index) { - static char dummy_writable_char; - if (index >= len || !buffer) { - dummy_writable_char = 0; - return dummy_writable_char; - } - return buffer[index]; + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; } +//---------------------------------------- char String::operator[]( unsigned int index ) const { - if (index >= len || !buffer) return 0; - return buffer[index]; + if (index >= len || !buffer) return 0; + return buffer[index]; } +//---------------------------------------- void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const { - if (!bufsize || !buf) return; - if (index >= len) { - buf[0] = 0; - return; - } - unsigned int n = bufsize - 1; - if (n > len - index) n = len - index; - strncpy((char *)buf, buffer + index, n); - buf[n] = 0; + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; } /*********************************************/ /* Search */ /*********************************************/ - int String::indexOf(char c) const { - return indexOf(c, 0); + return indexOf(c, 0); } +//---------------------------------------- int String::indexOf( char ch, unsigned int fromIndex ) const { - if (fromIndex >= len) return -1; - const char* temp = strchr(buffer + fromIndex, ch); - if (temp == NULL) return -1; - return temp - buffer; + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; } +//---------------------------------------- int String::indexOf(const String &s2) const { - return indexOf(s2, 0); + return indexOf(s2, 0); } +//---------------------------------------- int String::indexOf(const String &s2, unsigned int fromIndex) const { - if (fromIndex >= len) return -1; - const char *found = strstr(buffer + fromIndex, s2.buffer); - if (found == NULL) return -1; - return found - buffer; + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; } +//---------------------------------------- int String::lastIndexOf( char theChar ) const { - return lastIndexOf(theChar, len - 1); + return lastIndexOf(theChar, len - 1); } +//---------------------------------------- int String::lastIndexOf(char ch, unsigned int fromIndex) const { - if (fromIndex >= len) return -1; - char tempchar = buffer[fromIndex + 1]; - buffer[fromIndex + 1] = '\0'; - char* temp = strrchr( buffer, ch ); - buffer[fromIndex + 1] = tempchar; - if (temp == NULL) return -1; - return temp - buffer; + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; } +//---------------------------------------- int String::lastIndexOf(const String &s2) const { - return lastIndexOf(s2, len - s2.len); + return lastIndexOf(s2, len - s2.len); } +//---------------------------------------- int String::lastIndexOf(const String &s2, unsigned int fromIndex) const { - if (s2.len == 0 || len == 0 || s2.len > len) return -1; - if (fromIndex >= len) fromIndex = len - 1; - int found = -1; - for (char *p = buffer; p <= buffer + fromIndex; p++) { - p = strstr(p, s2.buffer); - if (!p) break; - if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; - } - return found; + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; } +//---------------------------------------- String String::substring(unsigned int left, unsigned int right) const { - if (left > right) { - unsigned int temp = right; - right = left; - left = temp; - } - String out; - if (left >= len) return out; - if (right > len) right = len; - char temp = buffer[right]; // save the replaced character - buffer[right] = '\0'; - out = buffer + left; // pointer arithmetic - buffer[right] = temp; //restore character - return out; + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; } /*********************************************/ @@ -652,10 +715,10 @@ String String::substring(unsigned int left, unsigned int right) const //---------------------------------------- void String::replace (char find, char replacement) { - if (!buffer) return; - for (char *p = buffer; *p; p++) { - if (*p == find) *p = replacement; - } + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replacement; + } } //---------------------------------------- @@ -678,51 +741,51 @@ String* String::replaceS (char find, char replacement) //---------------------------------------- void String::replace (const String& find, const String& replace) { - if (len == 0 || find.len == 0) return; - int diff = replace.len - find.len; - char *readFrom = buffer; - char *foundAt; + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; - if (diff == 0) + if (diff == 0) { - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - memcpy(foundAt, replace.buffer, replace.len); - readFrom = foundAt + replace.len; - } - } + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { - char *writeTo = buffer; - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - unsigned int n = foundAt - readFrom; - memcpy(writeTo, readFrom, n); - writeTo += n; - memcpy(writeTo, replace.buffer, replace.len); - writeTo += replace.len; - readFrom = foundAt + find.len; - len += diff; - } - strcpy(writeTo, readFrom); - } + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { - unsigned int size = len; // compute size needed for result - while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - readFrom = foundAt + find.len; - size += diff; - } - if (size == len) return; - if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! - int index = len - 1; - while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { - readFrom = buffer + index + find.len; - memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); - len += diff; - buffer[len] = 0; - memcpy(buffer + index, replace.buffer, replace.len); - index--; - } - } + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } } //---------------------------------------- @@ -745,10 +808,10 @@ String* String::replaceS (const String& find, const String& replacement) //---------------------------------------- void String::remove (unsigned int index) { - // Pass the biggest integer as the count. The remove method - // below will take care of truncating it at the end of the - // string. - remove (index, (unsigned int)-1); + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove (index, (unsigned int)-1); } //---------------------------------------- @@ -771,13 +834,13 @@ String* String::removeS (unsigned int index) //---------------------------------------- void String::remove (unsigned int index, unsigned int count) { - if (index >= len) return; - if (count <= 0) return; - if (count > len - index) count = len - index; - char *writeTo = buffer + index; - len = len - count; - strncpy(writeTo, buffer + index + count, len - index); - buffer[len] = 0; + if (index >= len) return; + if (count <= 0) return; + if (count > len - index) count = len - index; + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count, len - index); + buffer[len] = 0; } //---------------------------------------- @@ -800,10 +863,10 @@ String* String::removeS (unsigned int index, unsigned int count) //---------------------------------------- void String::toLowerCase (void) { - if (!buffer) return; - for (char *p = buffer; *p; p++) { - *p = tolower(*p); - } + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } } //---------------------------------------- @@ -826,10 +889,10 @@ String* String::toLowerCaseS (void) //---------------------------------------- void String::toUpperCase (void) { - if (!buffer) return; - for (char *p = buffer; *p; p++) { - *p = toupper(*p); - } + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } } //---------------------------------------- @@ -1207,12 +1270,12 @@ String* String::keepRightS (unsigned int count) long String::toInt(void) const { - if (buffer) return atol(buffer); - return 0; + if (buffer) return atol(buffer); + return 0; } float String::toFloat(void) const { - if (buffer) return float(atof(buffer)); - return 0; + if (buffer) return float(atof(buffer)); + return 0; } diff --git a/hardware/arduino/avr/cores/arduino/WString.h b/hardware/arduino/avr/cores/arduino/WString.h index af15b53c0ee..4e6cb5a5836 100644 --- a/hardware/arduino/avr/cores/arduino/WString.h +++ b/hardware/arduino/avr/cores/arduino/WString.h @@ -44,140 +44,140 @@ class StringSumHelper; // The string class class String { - // use a function pointer to allow for "if (s)" without the - // complications of an operator bool(). for more information, see: - // http://www.artima.com/cppsource/safebool.html - typedef void (String::*StringIfHelperType)() const; - void StringIfHelper() const {} + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} public: - // constructors - // creates a copy of the initial value. - // if the initial value is null or invalid, or if memory allocation - // fails, the string will be marked as invalid (i.e. "if (s)" will - // be false). - String(const char *cstr = ""); - String(const String &str); - String(const __FlashStringHelper *str); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - String(String &&rval); - String(StringSumHelper &&rval); - #endif - explicit String(char c); - explicit String(unsigned char, unsigned char base=10); - explicit String(int, unsigned char base=10); - explicit String(unsigned int, unsigned char base=10); - explicit String(long, unsigned char base=10); - explicit String(unsigned long, unsigned char base=10); - explicit String(float, unsigned char decimalPlaces=2); - explicit String(double, unsigned char decimalPlaces=2); - ~String(void); + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = "", unsigned int bufferSize = 0); + String(const String &str, unsigned int bufferSize = 0); + String(const __FlashStringHelper *str, unsigned int bufferSize = 0); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c, unsigned int bufferSize = 0); + explicit String(unsigned char, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(int, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(unsigned int, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(long, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(unsigned long, unsigned char base=10, unsigned int bufferSize = 0); + explicit String(float, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); + explicit String(double, unsigned char decimalPlaces=2, unsigned int bufferSize = 0); + ~String(void); - // memory management - // return true on success, false on failure (in which case, the string - // is left unchanged). reserve(0), if successful, will validate an - // invalid string (i.e., "if (s)" will be true afterwards) - unsigned char reserve(unsigned int size); + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); void setReservePercentage (unsigned char percentage); - inline unsigned int length(void) const {return len;} + inline unsigned int length(void) const {return len;} static void setDefaultReservePercentage (unsigned char percentage); - // creates a copy of the assigned value. if the value is null or - // invalid, or if the memory allocation fails, the string will be - // marked as invalid ("if (s)" will be false). - String & operator = (const String &rhs); - String & operator = (const char *cstr); - String & operator = (const __FlashStringHelper *str); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - String & operator = (String &&rval); - String & operator = (StringSumHelper &&rval); - #endif + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif - // concatenate (works w/ built-in types) + // concatenate (works w/ built-in types) - // returns true on success, false on failure (in which case, the string - // is left unchanged). if the argument is null or invalid, the - // concatenation is considered unsucessful. - unsigned char concat(const String &str); - unsigned char concat(const char *cstr); - unsigned char concat(char c); - unsigned char concat(unsigned char c); - unsigned char concat(int num); - unsigned char concat(unsigned int num); - unsigned char concat(long num); - unsigned char concat(unsigned long num); - unsigned char concat(float num); - unsigned char concat(double num); - unsigned char concat(const __FlashStringHelper * str); + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); - // if there's not enough memory for the concatenated value, the string - // will be left unchanged (but this isn't signalled in any way) - String & operator += (const String &rhs) {concat(rhs); return (*this);} - String & operator += (const char *cstr) {concat(cstr); return (*this);} - String & operator += (char c) {concat(c); return (*this);} - String & operator += (unsigned char num) {concat(num); return (*this);} - String & operator += (int num) {concat(num); return (*this);} - String & operator += (unsigned int num) {concat(num); return (*this);} - String & operator += (long num) {concat(num); return (*this);} - String & operator += (unsigned long num) {concat(num); return (*this);} - String & operator += (float num) {concat(num); return (*this);} - String & operator += (double num) {concat(num); return (*this);} - String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr);return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} - friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); - friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); - friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); - friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); - // comparison (only works w/ Strings and "strings") - operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } - int compareTo(const String &s) const; - unsigned char equals(const String &s) const; - unsigned char equals(const char *cstr) const; - unsigned char operator == (const String &rhs) const {return equals(rhs);} - unsigned char operator == (const char *cstr) const {return equals(cstr);} - unsigned char operator != (const String &rhs) const {return !equals(rhs);} - unsigned char operator != (const char *cstr) const {return !equals(cstr);} - unsigned char operator < (const String &rhs) const; - unsigned char operator > (const String &rhs) const; - unsigned char operator <= (const String &rhs) const; - unsigned char operator >= (const String &rhs) const; - unsigned char equalsIgnoreCase(const String &s) const; - unsigned char startsWith( const String &prefix) const; - unsigned char startsWith(const String &prefix, unsigned int offset) const; - unsigned char endsWith(const String &suffix) const; + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; - // character acccess - char charAt(unsigned int index) const; - void setCharAt(unsigned int index, char c); - char operator [] (unsigned int index) const; - char& operator [] (unsigned int index); - void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; - void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const - {getBytes((unsigned char *)buf, bufsize, index);} - const char * c_str() const { return buffer; } - const char* begin() { return c_str(); } - const char* end() { return c_str() + length(); } + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + const char* begin() { return c_str(); } + const char* end() { return c_str() + length(); } - // search - int indexOf( char ch ) const; - int indexOf( char ch, unsigned int fromIndex ) const; - int indexOf( const String &str ) const; - int indexOf( const String &str, unsigned int fromIndex ) const; - int lastIndexOf( char ch ) const; - int lastIndexOf( char ch, unsigned int fromIndex ) const; - int lastIndexOf( const String &str ) const; - int lastIndexOf( const String &str, unsigned int fromIndex ) const; - String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; - String substring( unsigned int beginIndex, unsigned int endIndex ) const; + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; // modification // notice: void function (...) operates on the object and returns void @@ -244,45 +244,45 @@ class String String keepRightC(unsigned int count); String* keepRightS(unsigned int count); - // parsing/conversion - long toInt(void) const; - float toFloat(void) const; + // parsing/conversion + long toInt (void) const; + float toFloat(void) const; protected: -public: - char *buffer; // the actual char array - unsigned int capacity; // the array length minus one (for the '\0') - unsigned int len; // the String length (not counting the '\0') + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') + unsigned int minCapacity; // the minimum value of capacity unsigned char reservePercentage = 0; // the percentage of reserved buffer when creating or resizing a String static unsigned char defaultReservePercentage; // the default value of reservePercentage protected: - void init(void); - void invalidate(void); - unsigned char changeBuffer(unsigned int maxStrLen); - unsigned char concat(const char *cstr, unsigned int length); + void init(unsigned int bufferSize = 0); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); - // copy and move - String & copy(const char *cstr, unsigned int length); - String & copy(const __FlashStringHelper *pstr, unsigned int length); - #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) - void move(String &rhs); - #endif + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif }; class StringSumHelper : public String { public: - StringSumHelper(const String &s) : String(s) {} - StringSumHelper(const char *p) : String(p) {} - StringSumHelper(char c) : String(c) {} - StringSumHelper(unsigned char num) : String(num) {} - StringSumHelper(int num) : String(num) {} - StringSumHelper(unsigned int num) : String(num) {} - StringSumHelper(long num) : String(num) {} - StringSumHelper(unsigned long num) : String(num) {} - StringSumHelper(float num) : String(num) {} - StringSumHelper(double num) : String(num) {} + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} }; #endif // __cplusplus