diff --git a/cores/arduino/IPAddress.cpp b/cores/arduino/IPAddress.cpp index 899cbd4e..76aefa8b 100644 --- a/cores/arduino/IPAddress.cpp +++ b/cores/arduino/IPAddress.cpp @@ -43,6 +43,48 @@ IPAddress::IPAddress(const uint8_t *address) memcpy(_address.bytes, address, sizeof(_address.bytes)); } +bool IPAddress::fromString(const char *address) +{ + // TODO: add support for "a", "a.b", "a.b.c" formats + + uint16_t acc = 0; // Accumulator + uint8_t dots = 0; + + while (*address) + { + char c = *address++; + if (c >= '0' && c <= '9') + { + acc = acc * 10 + (c - '0'); + if (acc > 255) { + // Value out of [0..255] range + return false; + } + } + else if (c == '.') + { + if (dots == 3) { + // Too much dots (there must be 3 dots) + return false; + } + _address.bytes[dots++] = acc; + acc = 0; + } + else + { + // Invalid char + return false; + } + } + + if (dots != 3) { + // Too few dots (there must be 3 dots) + return false; + } + _address.bytes[3] = acc; + return true; +} + IPAddress& IPAddress::operator=(const uint8_t *address) { memcpy(_address.bytes, address, sizeof(_address.bytes)); diff --git a/cores/arduino/IPAddress.h b/cores/arduino/IPAddress.h index 94acdc45..d762f2c0 100644 --- a/cores/arduino/IPAddress.h +++ b/cores/arduino/IPAddress.h @@ -21,7 +21,8 @@ #define IPAddress_h #include -#include +#include "Printable.h" +#include "WString.h" // A class to make it easier to handle and pass around IP addresses @@ -45,6 +46,9 @@ class IPAddress : public Printable { IPAddress(uint32_t address); IPAddress(const uint8_t *address); + bool fromString(const char *address); + bool fromString(const String &address) { return fromString(address.c_str()); } + // Overloaded cast operator to allow IPAddress objects to be used where a pointer // to a four-byte uint8_t array is expected operator uint32_t() const { return _address.dword; }; @@ -71,5 +75,4 @@ class IPAddress : public Printable { const IPAddress INADDR_NONE(0,0,0,0); - #endif diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index 7b0082a2..a604d2a7 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -31,15 +31,7 @@ #include -// following the C++ standard operators with attributes in right -// side must be defined globally -String operator + ( const char *cstr, const String &str_arg) -{ - String &str_arg_o = const_cast(str_arg); - String aux = String(cstr); - aux.concat(str_arg_o); - return aux; -} + /*********************************************/ /* Constructors */ /*********************************************/ @@ -56,7 +48,13 @@ String::String(const String &value) *this = value; } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) String::String(String &&rval) { init(); @@ -162,7 +160,6 @@ inline void String::init(void) buffer = NULL; capacity = 0; len = 0; - flags = 0; } void String::invalidate(void) @@ -197,18 +194,29 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) /* Copy and Move */ /*********************************************/ -String & String::copy(const char *cstr, unsigned int _length) +String & String::copy(const char *cstr, unsigned int length) { - if (!reserve(_length)) { + if (!reserve(length)) { invalidate(); return *this; } - len = _length; + len = length; strcpy(buffer, cstr); return *this; } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ +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) { @@ -240,7 +248,7 @@ String & String::operator = (const String &rhs) return *this; } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) String & String::operator = (String &&rval) { if (this != &rval) move(rval); @@ -262,6 +270,14 @@ String & String::operator = (const char *cstr) return *this; } +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + /*********************************************/ /* concat */ /*********************************************/ @@ -359,6 +375,18 @@ unsigned char String::concat(double num) 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 */ /*********************************************/ @@ -447,6 +475,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, double num) return a; } +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + /*********************************************/ /* Comparison */ /*********************************************/ @@ -639,7 +674,7 @@ String String::substring(unsigned int left, unsigned int right) const left = temp; } String out; - if (left > len) return out; + if (left >= len) return out; if (right > len) right = len; char temp = buffer[right]; // save the replaced character buffer[right] = '\0'; @@ -652,24 +687,24 @@ String String::substring(unsigned int left, unsigned int right) const /* Modification */ /*********************************************/ -void String::replace(char find, char _replace) +void String::replace(char find, char replace) { if (!buffer) return; for (char *p = buffer; *p; p++) { - if (*p == find) *p = _replace; + if (*p == find) *p = replace; } } -void String::replace(const String& find, const String& _replace) +void String::replace(const String& find, const String& replace) { if (len == 0 || find.len == 0) return; - int diff = _replace.len - find.len; + 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; + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; } } else if (diff < 0) { char *writeTo = buffer; @@ -677,8 +712,8 @@ void String::replace(const String& find, const String& _replace) unsigned int n = foundAt - readFrom; memcpy(writeTo, readFrom, n); writeTo += n; - memcpy(writeTo, _replace.buffer, _replace.len); - writeTo += _replace.len; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; readFrom = foundAt + find.len; len += diff; } @@ -697,7 +732,7 @@ void String::replace(const String& find, const String& _replace) memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); len += diff; buffer[len] = 0; - memcpy(buffer + index, _replace.buffer, _replace.len); + memcpy(buffer + index, replace.buffer, replace.len); index--; } } diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h index cfade3d1..541a0035 100644 --- a/cores/arduino/WString.h +++ b/cores/arduino/WString.h @@ -63,7 +63,8 @@ class String // be false). String(const char *cstr = ""); String(const String &str); - #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String(const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) String(String &&rval); String(StringSumHelper &&rval); #endif @@ -91,7 +92,8 @@ class String // marked as invalid ("if (s)" will be false). String & operator = (const String &rhs); String & operator = (const char *cstr); - #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) String & operator = (String &&rval); String & operator = (StringSumHelper &&rval); #endif @@ -113,6 +115,7 @@ class String unsigned char concat(unsigned long 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) @@ -128,6 +131,7 @@ class String String & operator += (unsigned long 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); @@ -141,6 +145,7 @@ class String friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long 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; } @@ -196,11 +201,11 @@ class String float toFloat(void) const; char * getCSpec(int base, bool issigned, bool islong); +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 char flags; // unused, for future features - +protected: void init(void); void invalidate(void); unsigned char changeBuffer(unsigned int maxStrLen); @@ -208,7 +213,8 @@ class String // copy and move String & copy(const char *cstr, unsigned int length); - #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) void move(String &rhs); #endif };