Skip to content

Commit ff9a16a

Browse files
committed
Add FlashString abstract class to support extension of String and Print methods to core specific program memory implementation.
1 parent 8ad0c60 commit ff9a16a

File tree

5 files changed

+45
-200
lines changed

5 files changed

+45
-200
lines changed

api/Print.cpp

+9-33
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,6 @@ size_t Print::write(const uint8_t *buffer, size_t size)
3636
return n;
3737
}
3838

39-
size_t Print::print(const __FlashStringHelper *ifsh)
40-
{
41-
#if defined(__AVR__)
42-
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
43-
size_t n = 0;
44-
while (1) {
45-
unsigned char c = pgm_read_byte(p++);
46-
if (c == 0) break;
47-
if (write(c)) n++;
48-
else break;
49-
}
50-
return n;
51-
#else
52-
return print(reinterpret_cast<const char *>(ifsh));
53-
#endif
54-
}
55-
5639
size_t Print::print(const String &s)
5740
{
5841
return write(s.c_str(), s.length());
@@ -132,13 +115,6 @@ size_t Print::print(double n, int digits)
132115
return printFloat(n, digits);
133116
}
134117

135-
size_t Print::println(const __FlashStringHelper *ifsh)
136-
{
137-
size_t n = print(ifsh);
138-
n += println();
139-
return n;
140-
}
141-
142118
size_t Print::print(const Printable& x)
143119
{
144120
return x.printTo(*this);
@@ -330,15 +306,15 @@ size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
330306
return bytes;
331307
}
332308

333-
size_t Print::printFloat(double number, uint8_t digits)
334-
{
309+
size_t Print::printFloat(double number, uint8_t digits)
310+
{
335311
size_t n = 0;
336-
312+
337313
if (isnan(number)) return print("nan");
338314
if (isinf(number)) return print("inf");
339315
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
340316
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
341-
317+
342318
// Handle negative numbers
343319
if (number < 0.0)
344320
{
@@ -350,7 +326,7 @@ size_t Print::printFloat(double number, uint8_t digits)
350326
double rounding = 0.5;
351327
for (uint8_t i=0; i<digits; ++i)
352328
rounding /= 10.0;
353-
329+
354330
number += rounding;
355331

356332
// Extract the integer part of the number and print it
@@ -360,7 +336,7 @@ size_t Print::printFloat(double number, uint8_t digits)
360336

361337
// Print the decimal point, but only if there are digits beyond
362338
if (digits > 0) {
363-
n += print(".");
339+
n += print('.');
364340
}
365341

366342
// Extract digits from the remainder one at a time
@@ -369,8 +345,8 @@ size_t Print::printFloat(double number, uint8_t digits)
369345
remainder *= 10.0;
370346
unsigned int toPrint = (unsigned int)remainder;
371347
n += print(toPrint);
372-
remainder -= toPrint;
373-
}
374-
348+
remainder -= toPrint;
349+
}
350+
375351
return n;
376352
}

api/Print.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class Print
5353
size_t write(const char *buffer, size_t size) {
5454
return write((const uint8_t *)buffer, size);
5555
}
56-
57-
size_t print(const __FlashStringHelper *);
56+
5857
size_t print(const String &);
5958
size_t print(const char[]);
6059
size_t print(char);
@@ -68,7 +67,6 @@ class Print
6867
size_t print(double, int = 2);
6968
size_t print(const Printable&);
7069

71-
size_t println(const __FlashStringHelper *);
7270
size_t println(const String &s);
7371
size_t println(const char[]);
7472
size_t println(char);

api/String.cpp

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

42-
String::String(const __FlashStringHelper *pstr)
42+
String::String(const FlashString &fstr)
4343
{
44-
init();
45-
*this = pstr;
44+
init();
45+
*this = fstr;
4646
}
4747

4848
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
@@ -180,17 +180,6 @@ String & String::copy(const char *cstr, unsigned int length)
180180
return *this;
181181
}
182182

183-
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
184-
{
185-
if (!reserve(length)) {
186-
invalidate();
187-
return *this;
188-
}
189-
len = length;
190-
strcpy_P(buffer, (PGM_P)pstr);
191-
return *this;
192-
}
193-
194183
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
195184
void String::move(String &rhs)
196185
{
@@ -245,11 +234,9 @@ String & String::operator = (const char *cstr)
245234
return *this;
246235
}
247236

248-
String & String::operator = (const __FlashStringHelper *pstr)
237+
String & String::operator = (const FlashString &fstr)
249238
{
250-
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
251-
else invalidate();
252-
239+
*this = fstr.toString();
253240
return *this;
254241
}
255242

@@ -336,16 +323,9 @@ unsigned char String::concat(double num)
336323
return concat(string, strlen(string));
337324
}
338325

339-
unsigned char String::concat(const __FlashStringHelper * str)
326+
unsigned char String::concat(const FlashString &fstr)
340327
{
341-
if (!str) return 0;
342-
int length = strlen_P((const char *) str);
343-
if (length == 0) return 1;
344-
unsigned int newlen = len + length;
345-
if (!reserve(newlen)) return 0;
346-
strcpy_P(buffer + len, (const char *) str);
347-
len = newlen;
348-
return 1;
328+
return concat(fstr.toString());
349329
}
350330

351331
/*********************************************/
@@ -422,7 +402,7 @@ StringSumHelper & operator + (const StringSumHelper &lhs, double num)
422402
return a;
423403
}
424404

425-
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
405+
StringSumHelper & operator + (const StringSumHelper &lhs, const FlashString &rhs)
426406
{
427407
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
428408
if (!a.concat(rhs)) a.invalidate();
@@ -592,7 +572,7 @@ int String::lastIndexOf(const String &s2) const
592572

593573
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
594574
{
595-
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
575+
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
596576
if (fromIndex >= len) fromIndex = len - 1;
597577
int found = -1;
598578
for (char *p = buffer; p <= buffer + fromIndex; p++) {

api/String.h

+26-13
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,37 @@
2323

2424
#ifdef __cplusplus
2525

26+
#include "Printable.h"
27+
2628
#include <stdlib.h>
2729
#include <string.h>
2830
#include <ctype.h>
29-
#if defined(__AVR__)
30-
#include "avr/pgmspace.h"
31-
#else
32-
#include "deprecated-avr-comp/avr/pgmspace.h"
33-
#endif
3431

3532
// When compiling programs with this class, the following gcc parameters
3633
// dramatically increase performance and memory (RAM) efficiency, typically
3734
// with little or no increase in code size.
3835
// -felide-constructors
3936
// -std=c++0x
4037

41-
class __FlashStringHelper;
42-
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
38+
class String;
39+
40+
// Default implemtation of 'F' macro for cores than can use
41+
// string literals directly as (const char *).
42+
// For cores that require special interface to program memory,
43+
// the default 'F' macro can be undefined at core
44+
// implementation level and redefined as needed.
45+
#define F(string_literal) (string_literal)
46+
47+
// Base Class for strings stored in program memory.
48+
// For cores that require special interface to program memory,
49+
// this class can be extended at the core implementation
50+
// level in order to support String and Print operations from
51+
// program memory.
52+
class FlashString : public Printable
53+
{
54+
public:
55+
virtual String toString() const = 0;
56+
};
4357

4458
// An inherited class for holding the result of a concatenation. These
4559
// result objects are assumed to be writable by subsequent concatenations.
@@ -62,7 +76,7 @@ class String
6276
// be false).
6377
String(const char *cstr = "");
6478
String(const String &str);
65-
String(const __FlashStringHelper *str);
79+
String(const FlashString &fstr);
6680
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
6781
String(String &&rval);
6882
String(StringSumHelper &&rval);
@@ -89,7 +103,7 @@ class String
89103
// marked as invalid ("if (s)" will be false).
90104
String & operator = (const String &rhs);
91105
String & operator = (const char *cstr);
92-
String & operator = (const __FlashStringHelper *str);
106+
String & operator = (const FlashString &fstr);
93107
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
94108
String & operator = (String &&rval);
95109
String & operator = (StringSumHelper &&rval);
@@ -110,7 +124,7 @@ class String
110124
unsigned char concat(unsigned long num);
111125
unsigned char concat(float num);
112126
unsigned char concat(double num);
113-
unsigned char concat(const __FlashStringHelper * str);
127+
unsigned char concat(const FlashString &fstr);
114128

115129
// if there's not enough memory for the concatenated value, the string
116130
// will be left unchanged (but this isn't signalled in any way)
@@ -124,7 +138,7 @@ class String
124138
String & operator += (unsigned long num) {concat(num); return (*this);}
125139
String & operator += (float num) {concat(num); return (*this);}
126140
String & operator += (double num) {concat(num); return (*this);}
127-
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
141+
String & operator += (const FlashString &fstr){concat(fstr); return (*this);}
128142

129143
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
130144
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
@@ -136,7 +150,7 @@ class String
136150
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
137151
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
138152
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
139-
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
153+
friend StringSumHelper & operator + (const StringSumHelper &lhs, const FlashString &rhs);
140154

141155
// comparison (only works w/ Strings and "strings")
142156
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@@ -222,7 +236,6 @@ class String
222236

223237
// copy and move
224238
String & copy(const char *cstr, unsigned int length);
225-
String & copy(const __FlashStringHelper *pstr, unsigned int length);
226239
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
227240
void move(String &rhs);
228241
#endif

0 commit comments

Comments
 (0)