Skip to content

Commit 1130fed

Browse files
committed
Added support for Flash string on String class.
1 parent b341a7c commit 1130fed

File tree

6 files changed

+104
-1
lines changed

6 files changed

+104
-1
lines changed

build/shared/revisions.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ARDUINO 1.5.3 BETA
1414
* sam: Added compatibility for avr/pgmspace.h (Paul Stoffregen)
1515
* sam: Added serialEvent*() support
1616
* sam: Fixed micros() to work with inside interrupts. (stimmer)
17+
* avr: Added support for Flash strings on String class (Jantje)
1718

1819
[libraries]
1920
* sam: Added CAN library (still in early stage of development) (Palliser)

hardware/arduino/avr/cores/arduino/WString.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ String::String(const String &value)
3838
*this = value;
3939
}
4040

41+
String::String(const __FlashStringHelper *pstr)
42+
{
43+
init();
44+
*this = pstr;
45+
}
46+
4147
#ifdef __GXX_EXPERIMENTAL_CXX0X__
4248
String::String(String &&rval)
4349
{
@@ -160,6 +166,17 @@ String & String::copy(const char *cstr, unsigned int length)
160166
return *this;
161167
}
162168

169+
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
170+
{
171+
if (!reserve(length)) {
172+
invalidate();
173+
return *this;
174+
}
175+
len = length;
176+
strcpy_P(buffer, (const prog_char *)pstr);
177+
return *this;
178+
}
179+
163180
#ifdef __GXX_EXPERIMENTAL_CXX0X__
164181
void String::move(String &rhs)
165182
{
@@ -214,6 +231,14 @@ String & String::operator = (const char *cstr)
214231
return *this;
215232
}
216233

234+
String & String::operator = (const __FlashStringHelper *pstr)
235+
{
236+
if (pstr) copy(pstr, strlen_P((const prog_char *)pstr));
237+
else invalidate();
238+
239+
return *this;
240+
}
241+
217242
/*********************************************/
218243
/* concat */
219244
/*********************************************/
@@ -283,6 +308,18 @@ unsigned char String::concat(unsigned long num)
283308
return concat(buf, strlen(buf));
284309
}
285310

311+
unsigned char String::concat(const __FlashStringHelper * str)
312+
{
313+
if (!str) return 0;
314+
int length = strlen_P((const char *) str);
315+
if (length == 0) return 1;
316+
unsigned int newlen = len + length;
317+
if (!reserve(newlen)) return 0;
318+
strcpy_P(buffer + len, (const char *) str);
319+
len = newlen;
320+
return 1;
321+
}
322+
286323
/*********************************************/
287324
/* Concatenate */
288325
/*********************************************/
@@ -343,6 +380,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
343380
return a;
344381
}
345382

383+
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
384+
{
385+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
386+
if (!a.concat(rhs)) a.invalidate();
387+
return a;
388+
}
389+
346390
/*********************************************/
347391
/* Comparison */
348392
/*********************************************/

hardware/arduino/avr/cores/arduino/WString.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class String
5858
// be false).
5959
String(const char *cstr = "");
6060
String(const String &str);
61+
String(const __FlashStringHelper *str);
6162
#ifdef __GXX_EXPERIMENTAL_CXX0X__
6263
String(String &&rval);
6364
String(StringSumHelper &&rval);
@@ -82,6 +83,7 @@ class String
8283
// marked as invalid ("if (s)" will be false).
8384
String & operator = (const String &rhs);
8485
String & operator = (const char *cstr);
86+
String & operator = (const __FlashStringHelper *str);
8587
#ifdef __GXX_EXPERIMENTAL_CXX0X__
8688
String & operator = (String &&rval);
8789
String & operator = (StringSumHelper &&rval);
@@ -100,17 +102,19 @@ class String
100102
unsigned char concat(unsigned int num);
101103
unsigned char concat(long num);
102104
unsigned char concat(unsigned long num);
105+
unsigned char concat(const __FlashStringHelper * str);
103106

104107
// if there's not enough memory for the concatenated value, the string
105108
// will be left unchanged (but this isn't signalled in any way)
106109
String & operator += (const String &rhs) {concat(rhs); return (*this);}
107110
String & operator += (const char *cstr) {concat(cstr); return (*this);}
108111
String & operator += (char c) {concat(c); return (*this);}
109-
String & operator += (unsigned char num) {concat(num); return (*this);}
112+
String & operator += (unsigned char num) {concat(num); return (*this);}
110113
String & operator += (int num) {concat(num); return (*this);}
111114
String & operator += (unsigned int num) {concat(num); return (*this);}
112115
String & operator += (long num) {concat(num); return (*this);}
113116
String & operator += (unsigned long num) {concat(num); return (*this);}
117+
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
114118

115119
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
116120
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
@@ -120,6 +124,7 @@ class String
120124
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
121125
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
122126
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
127+
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
123128

124129
// comparison (only works w/ Strings and "strings")
125130
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@@ -184,6 +189,7 @@ class String
184189

185190
// copy and move
186191
String & copy(const char *cstr, unsigned int length);
192+
String & copy(const __FlashStringHelper *pstr, unsigned int length);
187193
#ifdef __GXX_EXPERIMENTAL_CXX0X__
188194
void move(String &rhs);
189195
#endif

hardware/arduino/sam/cores/arduino/WString.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ String::String(const String &value)
3939
*this = value;
4040
}
4141

42+
String::String(const __FlashStringHelper *pstr)
43+
{
44+
init();
45+
*this = pstr;
46+
}
47+
4248
#ifdef __GXX_EXPERIMENTAL_CXX0X__
4349
String::String(String &&rval)
4450
{
@@ -161,6 +167,17 @@ String & String::copy(const char *cstr, unsigned int length)
161167
return *this;
162168
}
163169

170+
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
171+
{
172+
if (!reserve(length)) {
173+
invalidate();
174+
return *this;
175+
}
176+
len = length;
177+
strcpy_P(buffer, (const prog_char *)pstr);
178+
return *this;
179+
}
180+
164181
#ifdef __GXX_EXPERIMENTAL_CXX0X__
165182
void String::move(String &rhs)
166183
{
@@ -215,6 +232,14 @@ String & String::operator = (const char *cstr)
215232
return *this;
216233
}
217234

235+
String & String::operator = (const __FlashStringHelper *pstr)
236+
{
237+
if (pstr) copy(pstr, strlen_P((const prog_char *)pstr));
238+
else invalidate();
239+
240+
return *this;
241+
}
242+
218243
/*********************************************/
219244
/* concat */
220245
/*********************************************/
@@ -284,6 +309,18 @@ unsigned char String::concat(unsigned long num)
284309
return concat(buf, strlen(buf));
285310
}
286311

312+
unsigned char String::concat(const __FlashStringHelper * str)
313+
{
314+
if (!str) return 0;
315+
int length = strlen_P((const char *) str);
316+
if (length == 0) return 1;
317+
unsigned int newlen = len + length;
318+
if (!reserve(newlen)) return 0;
319+
strcpy_P(buffer + len, (const char *) str);
320+
len = newlen;
321+
return 1;
322+
}
323+
287324
/*********************************************/
288325
/* Concatenate */
289326
/*********************************************/
@@ -344,6 +381,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
344381
return a;
345382
}
346383

384+
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
385+
{
386+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
387+
if (!a.concat(rhs)) a.invalidate();
388+
return a;
389+
}
390+
347391
/*********************************************/
348392
/* Comparison */
349393
/*********************************************/

hardware/arduino/sam/cores/arduino/WString.h

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <stdlib.h>
2727
#include <string.h>
2828
#include <ctype.h>
29+
#include <avr/pgmspace.h>
2930

3031
// When compiling programs with this class, the following gcc parameters
3132
// dramatically increase performance and memory (RAM) efficiency, typically
@@ -57,6 +58,7 @@ class String
5758
// be false).
5859
String(const char *cstr = "");
5960
String(const String &str);
61+
String(const __FlashStringHelper *str);
6062
#ifdef __GXX_EXPERIMENTAL_CXX0X__
6163
String(String &&rval);
6264
String(StringSumHelper &&rval);
@@ -81,6 +83,7 @@ class String
8183
// marked as invalid ("if (s)" will be false).
8284
String & operator = (const String &rhs);
8385
String & operator = (const char *cstr);
86+
String & operator = (const __FlashStringHelper *str);
8487
#ifdef __GXX_EXPERIMENTAL_CXX0X__
8588
String & operator = (String &&rval);
8689
String & operator = (StringSumHelper &&rval);
@@ -99,6 +102,7 @@ class String
99102
unsigned char concat(unsigned int num);
100103
unsigned char concat(long num);
101104
unsigned char concat(unsigned long num);
105+
unsigned char concat(const __FlashStringHelper * str);
102106

103107
// if there's not enough memory for the concatenated value, the string
104108
// will be left unchanged (but this isn't signalled in any way)
@@ -110,6 +114,7 @@ class String
110114
String & operator += (unsigned int num) {concat(num); return (*this);}
111115
String & operator += (long num) {concat(num); return (*this);}
112116
String & operator += (unsigned long num) {concat(num); return (*this);}
117+
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
113118

114119
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
115120
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
@@ -119,6 +124,7 @@ class String
119124
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
120125
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
121126
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
127+
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
122128

123129
// comparison (only works w/ Strings and "strings")
124130
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@@ -183,6 +189,7 @@ class String
183189

184190
// copy and move
185191
String & copy(const char *cstr, unsigned int length);
192+
String & copy(const __FlashStringHelper *pstr, unsigned int length);
186193
#ifdef __GXX_EXPERIMENTAL_CXX0X__
187194
void move(String &rhs);
188195
#endif

hardware/arduino/sam/cores/arduino/avr/pgmspace.h

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ typedef uint32_t prog_uint32_t;
2424
#define strcat_P(dest, src) strcat((dest), (src))
2525
#define strcmp_P(a, b) strcmp((a), (b))
2626
#define strstr_P(a, b) strstr((a), (b))
27+
#define strlen_P(a) strlen((a))
2728
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
2829

2930
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

0 commit comments

Comments
 (0)