From 67128fcb2c01205da697cff04d45ba7566393183 Mon Sep 17 00:00:00 2001 From: Martin Sloup Date: Wed, 8 Feb 2017 18:57:26 +0100 Subject: [PATCH] Fixes implementation of __FlashStringHelper (#183) Previous __FlashStringHelper implementation was defines as a char which brought problem in case the method with char* parameter used overloading with __FlashStringHelper* parameter (they was identical). Now __FlashStringHelper is defined as a class and all casts between char* and __FlashStringHelper* are made with reinterpret_cast sugar. --- cores/esp32/Print.cpp | 19 ++++++----------- cores/esp32/Print.h | 4 ++-- cores/esp32/WString.cpp | 46 ++++++++++++++--------------------------- cores/esp32/WString.h | 22 +++++++++++--------- cores/esp32/pgmspace.h | 3 --- 5 files changed, 35 insertions(+), 59 deletions(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index 8c1d46e3..a0c7a4a8 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -68,19 +68,12 @@ size_t Print::printf(const char *format, ...) } return len; } -/* -size_t Print::print(const __FlashStringHelper *ifsh) { - PGM_P p = reinterpret_cast(ifsh); - size_t n = 0; - while (1) { - uint8_t c = pgm_read_byte(p++); - if (c == 0) break; - n += write(c); - } - return n; +size_t Print::print(const __FlashStringHelper *ifsh) +{ + return print(reinterpret_cast(ifsh)); } -*/ + size_t Print::print(const String &s) { return write(s.c_str(), s.length()); @@ -140,14 +133,14 @@ size_t Print::print(double n, int digits) { return printFloat(n, digits); } -/* + size_t Print::println(const __FlashStringHelper *ifsh) { size_t n = print(ifsh); n += println(); return n; } -*/ + size_t Print::print(const Printable& x) { return x.printTo(*this); diff --git a/cores/esp32/Print.h b/cores/esp32/Print.h index d1763aa6..eb295858 100644 --- a/cores/esp32/Print.h +++ b/cores/esp32/Print.h @@ -72,7 +72,7 @@ public: } size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3))); - //size_t print(const __FlashStringHelper *); + size_t print(const __FlashStringHelper *); size_t print(const String &); size_t print(const char[]); size_t print(char); @@ -85,7 +85,7 @@ public: size_t print(const Printable&); size_t print(struct tm * timeinfo, const char * format = NULL); - //size_t println(const __FlashStringHelper *); + size_t println(const __FlashStringHelper *); size_t println(const String &s); size_t println(const char[]); size_t println(char); diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index e67eb7f9..3ca49822 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -44,12 +44,7 @@ String::String(const String &value) init(); *this = value; } -/* -String::String(const __FlashStringHelper *pstr) { - init(); - *this = pstr; // see operator = -} -*/ + #ifdef __GXX_EXPERIMENTAL_CXX0X__ String::String(String &&rval) { @@ -200,17 +195,12 @@ String & String::copy(const char *cstr, unsigned int 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; + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + return copy(reinterpret_cast(pstr), length); } -*/ + #ifdef __GXX_EXPERIMENTAL_CXX0X__ void String::move(String &rhs) { @@ -276,7 +266,7 @@ String & String::operator =(const char *cstr) return *this; } -/* + String & String::operator = (const __FlashStringHelper *pstr) { if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); @@ -284,7 +274,7 @@ String & String::operator = (const __FlashStringHelper *pstr) return *this; } -*/ + // /*********************************************/ // /* concat */ // /*********************************************/ @@ -375,18 +365,12 @@ unsigned char String::concat(double num) 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((PGM_P)str); - if (length == 0) return 1; - unsigned int newlen = len + length; - if (!reserve(newlen)) return 0; - strcpy_P(buffer + len, (PGM_P)str); - len = newlen; - return 1; + +unsigned char String::concat(const __FlashStringHelper * str) +{ + return concat(reinterpret_cast(str)); } -*/ + /*********************************************/ /* Concatenate */ /*********************************************/ @@ -480,14 +464,14 @@ 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 */ // /*********************************************/ diff --git a/cores/esp32/WString.h b/cores/esp32/WString.h index d99352f4..9d49377c 100644 --- a/cores/esp32/WString.h +++ b/cores/esp32/WString.h @@ -34,7 +34,8 @@ class StringSumHelper; // an abstract class used as a means to proide a unique pointer type // but really has no body -//class __FlashStringHelper; +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) // The string class class String @@ -55,7 +56,7 @@ public: // be false). String(const char *cstr = ""); String(const String &str); - //String(const __FlashStringHelper *str); + String(const __FlashStringHelper *str) : String(reinterpret_cast(str)) {}; #ifdef __GXX_EXPERIMENTAL_CXX0X__ String(String &&rval); String(StringSumHelper &&rval); @@ -89,7 +90,7 @@ public: // marked as invalid ("if (s)" will be false). String & operator =(const String &rhs); String & operator =(const char *cstr); - //String & operator = (const __FlashStringHelper *str); + String & operator = (const __FlashStringHelper *str); #ifdef __GXX_EXPERIMENTAL_CXX0X__ String & operator =(String &&rval); String & operator =(StringSumHelper &&rval); @@ -110,7 +111,7 @@ public: unsigned char concat(unsigned long num); unsigned char concat(float num); unsigned char concat(double num); - //unsigned char concat(const __FlashStringHelper * str); + 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) @@ -164,10 +165,11 @@ public: concat(num); return (*this); } - //String & operator += (const __FlashStringHelper *str){ - // concat(str); - // 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); @@ -179,7 +181,7 @@ public: 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 __FlashStringHelper *rhs); // comparison (only works w/ Strings and "strings") operator StringIfHelperType() const @@ -270,7 +272,7 @@ protected: // copy and move String & copy(const char *cstr, unsigned int length); - //String & copy(const __FlashStringHelper *pstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); #ifdef __GXX_EXPERIMENTAL_CXX0X__ void move(String &rhs); #endif diff --git a/cores/esp32/pgmspace.h b/cores/esp32/pgmspace.h index 6e10d926..51faac16 100644 --- a/cores/esp32/pgmspace.h +++ b/cores/esp32/pgmspace.h @@ -29,8 +29,6 @@ typedef unsigned short prog_uint16_t; typedef long prog_int32_t; typedef unsigned long prog_uint32_t; -typedef char __FlashStringHelper; - #define SIZE_IRRELEVANT 0x7fffffff #define PROGMEM @@ -38,7 +36,6 @@ typedef char __FlashStringHelper; #define PGM_VOID_P const void * #define FPSTR(p) ((const char *)(p)) #define PSTR(s) (s) -#define F(s) (s) #define _SFR_BYTE(n) (n) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))