1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-29 10:24:12 +01:00

Added support for Flash string on String class.

This commit is contained in:
Cristian Maglie 2013-06-06 15:41:23 +02:00
parent b341a7c751
commit 1130fede3a
6 changed files with 104 additions and 1 deletions

View File

@ -14,6 +14,7 @@ ARDUINO 1.5.3 BETA
* sam: Added compatibility for avr/pgmspace.h (Paul Stoffregen)
* sam: Added serialEvent*() support
* sam: Fixed micros() to work with inside interrupts. (stimmer)
* avr: Added support for Flash strings on String class (Jantje)
[libraries]
* sam: Added CAN library (still in early stage of development) (Palliser)

View File

@ -38,6 +38,12 @@ String::String(const String &value)
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{
@ -160,6 +166,17 @@ String & String::copy(const char *cstr, unsigned int length)
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (const prog_char *)pstr);
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void String::move(String &rhs)
{
@ -214,6 +231,14 @@ String & String::operator = (const char *cstr)
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((const prog_char *)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
@ -283,6 +308,18 @@ unsigned char String::concat(unsigned long num)
return concat(buf, strlen(buf));
}
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 */
/*********************************************/
@ -343,6 +380,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/

View File

@ -58,6 +58,7 @@ public:
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
@ -82,6 +83,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);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
@ -100,17 +102,19 @@ public:
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long 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 += (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 += (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);
@ -120,6 +124,7 @@ public:
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, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@ -184,6 +189,7 @@ protected:
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs);
#endif

View File

@ -39,6 +39,12 @@ String::String(const String &value)
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{
@ -161,6 +167,17 @@ String & String::copy(const char *cstr, unsigned int length)
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (const prog_char *)pstr);
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void String::move(String &rhs)
{
@ -215,6 +232,14 @@ String & String::operator = (const char *cstr)
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((const prog_char *)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
@ -284,6 +309,18 @@ unsigned char String::concat(unsigned long num)
return concat(buf, strlen(buf));
}
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 */
/*********************************************/
@ -344,6 +381,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
@ -57,6 +58,7 @@ public:
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
@ -81,6 +83,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);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
@ -99,6 +102,7 @@ public:
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long 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)
@ -110,6 +114,7 @@ public:
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 += (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);
@ -119,6 +124,7 @@ public:
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, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@ -183,6 +189,7 @@ protected:
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs);
#endif

View File

@ -24,6 +24,7 @@ typedef uint32_t prog_uint32_t;
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define strstr_P(a, b) strstr((a), (b))
#define strlen_P(a) strlen((a))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))