Sming Framework API
Sming - Open Source framework for high efficiency WiFi SoC ESP8266 native development with C++ language.
WString.h
1 /* $Id: WString.h 1156 2011-06-07 04:01:16Z bhagman $
2 ||
3 || @author Paul Stoffregen <paul@pjrc.com>
4 || @url http://wiring.org.co/
5 || @contribution Hernando Barragan <b@wiring.org.co>
6 || @contribution Brett Hagman <bhagman@wiring.org.co>
7 || @contribution Alexander Brevig <abrevig@wiring.org.co>
8 ||
9 || @description
10 || | String class.
11 || |
12 || | Wiring Common API
13 || #
14 ||
15 || @license Please see cores/Common/License.txt.
16 ||
17 */
18 
19 /*
20  * @author: 2 Oct 2018 - mikee47 <mike@sillyhouse.net>
21  *
22  * The standard String object default constructor creates an empty string, which requires a heap allocation of 1 byte.
23  * I changed this behaviour to default to a null string (invalid) to avoid this (usually) un-necessary allocation.
24  * If the value of the string hasn't actually been assigned yet then an 'invalid' (or null) string is the more logical choice.
25  * Additional changes ensure that the content of such a string are equivalent to an empty string "".
26  *
27  * Background
28  *
29  * The intent of the Wiring authors seems to be that an expression producing a String object will fail and produce
30  * an 'invalid' String (that evaluates to False) if any of the allocations within that expression fail. This could
31  * be due to heap fragmentation, low memory or a String which is just too big.
32  *
33  * By example:
34  *
35  * String tmp = String("A") + String("B");
36  *
37  * If a heap allocation fails on either "A" or "B" the the result should be a null string. However, this is not actually
38  * the case. In practice, if "A" fails but "B" does not then the result will be "B", while if "A" succeeds but "B" fails
39  * then the result will be 'invalid'. This would appear to be an oversight in the Wiring library (last updated July 2016).
40  *
41  * I made a decision with these changes that heap allocation errors are a rare enough occurrence that attempting to deal with
42  * them in such a manner causes more problems than it solves.
43  *
44  * These changes have a knock-on effect in that if any of the allocations in an expression fail, then the result, tmp,
45  * will be unpredictable.
46  *
47  */
48 
49 #ifndef WSTRING_H
50 #define WSTRING_H
51 
52 #ifdef __cplusplus
53 
54 #include "WiringFrameworkDependencies.h"
55 #include "WVector.h"
56 
57 // @deprecated Should not be using String in interrupt context
58 #define STRING_IRAM_ATTR // IRAM_ATTR
59 
60 #ifndef __GXX_EXPERIMENTAL_CXX0X__
61 #define __GXX_EXPERIMENTAL_CXX0X__
62 #endif
63 
64 // When compiling programs with this class, the following gcc parameters
65 // dramatically increase performance and memory (RAM) efficiency, typically
66 // with little or no increase in code size.
67 // -felide-constructors
68 // -std=c++0x
69 
70 // An inherited class for holding the result of a concatenation. These
71 // result objects are assumed to be writable by subsequent concatenations.
72 class StringSumHelper;
73 
74 /* Arduino-style flash strings
75  *
76  * __FlashStringHelper* provides strongly-typed pointer to allow safe implicit
77  * operation using String class methods.
78  */
79 class __FlashStringHelper; // Never actually defined
80 typedef const __FlashStringHelper* flash_string_t;
81 
82 // Cast a PGM_P (flash memory) pointer to a flash string pointer
83 #define FPSTR(pstr_pointer) reinterpret_cast<flash_string_t>(pstr_pointer)
84 
85 /*
86  * Use this macro to wrap a string literal and access it using a String object.
87  * The string data is stored in flash and only read into RAM when executed.
88  * For example: Serial.print(F("This is a test string\n"));
89  */
90 #define F(string_literal) String(FPSTR(PSTR(string_literal)), sizeof(string_literal) - 1)
91 
92 // Forward declaration for counted flash string - see FlashString.h
93 struct FlashString;
94 
103 // The string class
104 class String
105 {
106  // use a function pointer to allow for "if (s)" without the
107  // complications of an operator bool(). for more information, see:
108  // http://www.artima.com/cppsource/safebool.html
109  typedef void (String::*StringIfHelperType)() const;
110  void STRING_IRAM_ATTR StringIfHelper() const {}
111 
112  public:
113  // Use these for const references, e.g. in function return values
114  static const String nullstr;
115  static const String empty;
116 
117  /* constructors
118 
119  creates a copy of the initial value.
120  if the initial value is null or invalid, or if memory allocation
121  fails, the string will be marked as invalid (i.e. "if (s)" will be false).
122  */
123  STRING_IRAM_ATTR String(const char *cstr = nullptr);
124  STRING_IRAM_ATTR String(const char *cstr, unsigned int length);
125  STRING_IRAM_ATTR String(const String &str);
126  explicit String(flash_string_t pstr, int length = -1);
127  String(const FlashString& fstr);
128 
129 #ifdef __GXX_EXPERIMENTAL_CXX0X__
130  STRING_IRAM_ATTR String(String && rval);
131  STRING_IRAM_ATTR String(StringSumHelper && rval);
132 #endif
133  explicit String(char c);
134  explicit String(unsigned char, unsigned char base = 10);
135  explicit String(int, unsigned char base = 10);
136  explicit String(unsigned int, unsigned char base = 10);
137  explicit String(long, unsigned char base = 10);
138  explicit String(unsigned long, unsigned char base = 10);
139  explicit String(float, unsigned char decimalPlaces=2);
140  explicit String(double, unsigned char decimalPlaces=2);
141  ~String(void);
142 
143  void setString(const char *cstr, int length = -1);
144  void setString(flash_string_t pstr, int length = -1);
145 
146  // memory management
147  // return true on success, false on failure (in which case, the string
148  // is left unchanged). reserve(0), if successful, will validate an
149  // invalid string (i.e., "if (s)" will be true afterwards)
150  bool reserve(unsigned int size);
151 
157  bool setLength(unsigned int length);
158 
159  inline unsigned int length(void) const
160  {
161  return len;
162  }
163 
164  // creates a copy of the assigned value. if the value is null or
165  // invalid, or if the memory allocation fails, the string will be
166  // marked as invalid ("if (s)" will be false).
167  String & STRING_IRAM_ATTR operator = (const String &rhs);
168  String & STRING_IRAM_ATTR operator = (const char *cstr);
169 #ifdef __GXX_EXPERIMENTAL_CXX0X__
170  String & operator = (String && rval);
171  String & operator = (StringSumHelper && rval);
172 #endif
173 
174  // concatenate (works w/ built-in types)
175 
176  // returns true on success, false on failure (in which case, the string
177  // is left unchanged). if the argument is null or invalid, the
178  // concatenation is considered unsucessful.
179  bool concat(const String &str);
180  bool concat(const char *cstr);
181  bool STRING_IRAM_ATTR concat(const char *cstr, unsigned int length);
182  bool concat(char c);
183  bool concat(unsigned char c);
184  bool concat(int num);
185  bool concat(unsigned int num);
186  bool concat(long num);
187  bool concat(unsigned long num);
188  bool concat(float num);
189  bool concat(double num);
190 
191  // if there's not enough memory for the concatenated value, the string
192  // will be left unchanged (but this isn't signalled in any way)
193  String & operator += (const String &rhs)
194  {
195  concat(rhs);
196  return (*this);
197  }
198  String & operator += (const char *cstr)
199  {
200  concat(cstr);
201  return (*this);
202  }
203  String & operator += (char c)
204  {
205  concat(c);
206  return (*this);
207  }
208  String & operator += (unsigned char num)
209  {
210  concat(num);
211  return (*this);
212  }
213  String & operator += (int num)
214  {
215  concat(num);
216  return (*this);
217  }
218  String & operator += (unsigned int num)
219  {
220  concat(num);
221  return (*this);
222  }
223  String & operator += (long num)
224  {
225  concat(num);
226  return (*this);
227  }
228  String & operator += (unsigned long num)
229  {
230  concat(num);
231  return (*this);
232  }
233  String & operator += (float num)
234  {
235  concat(num);
236  return (*this);
237  }
238  String & operator += (double num)
239  {
240  concat(num);
241  return (*this);
242  }
243 
244  friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
245  friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
246  friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
247  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
248  friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
249  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
250  friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
251  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
252  friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
253  friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
254 
255  // comparison (only works w/ Strings and "strings")
256  operator StringIfHelperType() const
257  {
258  return buffer ? &String::StringIfHelper : 0;
259  }
260  int STRING_IRAM_ATTR compareTo(const String &s) const;
261  bool STRING_IRAM_ATTR equals(const String &s) const;
262  bool STRING_IRAM_ATTR equals(const char *cstr) const;
263  bool equals(const FlashString& fstr) const;
264 
265  bool STRING_IRAM_ATTR operator == (const String &rhs) const
266  {
267  return equals(rhs);
268  }
269  bool STRING_IRAM_ATTR operator == (const char *cstr) const
270  {
271  return equals(cstr);
272  }
273  bool STRING_IRAM_ATTR operator==(const FlashString& fstr) const
274  {
275  return equals(fstr);
276  }
277  bool STRING_IRAM_ATTR operator != (const String &rhs) const
278  {
279  return !equals(rhs);
280  }
281  bool STRING_IRAM_ATTR operator != (const char *cstr) const
282  {
283  return !equals(cstr);
284  }
285  bool operator < (const String &rhs) const;
286  bool operator > (const String &rhs) const;
287  bool operator <= (const String &rhs) const;
288  bool operator >= (const String &rhs) const;
289  bool equalsIgnoreCase(const char* cstr) const;
290  bool equalsIgnoreCase(const String &s2) const;
291  bool equalsIgnoreCase(const FlashString& fstr) const;
292  bool startsWith(const String &prefix) const;
293  bool startsWith(const String &prefix, unsigned int offset) const;
294  bool endsWith(const String &suffix) const;
295 
296  // character acccess
297  char STRING_IRAM_ATTR charAt(unsigned int index) const;
298  void STRING_IRAM_ATTR setCharAt(unsigned int index, char c);
299  char STRING_IRAM_ATTR operator [](unsigned int index) const;
300  char& STRING_IRAM_ATTR operator [](unsigned int index);
301 
310  unsigned int getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
311 
312  void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const
313  {
314  getBytes((unsigned char *)buf, bufsize, index);
315  }
316  const char* c_str() const { return buffer ?: empty.buffer; }
317  char* begin() { return buffer; }
318  char* end() { return buffer + length(); }
319  const char* begin() const { return c_str(); }
320  const char* end() const { return c_str() + length(); }
321 
322  // search
323  int STRING_IRAM_ATTR indexOf(char ch) const;
324  int indexOf(char ch, unsigned int fromIndex) const;
325  int STRING_IRAM_ATTR indexOf(const String &str) const;
326  int indexOf(const String &s2, unsigned int fromIndex) const;
327  int lastIndexOf(char ch) const;
328  int lastIndexOf(char ch, unsigned int fromIndex) const;
329  int lastIndexOf(const String &s2) const;
330  int lastIndexOf(const String &s2, unsigned int fromIndex) const;
331  String substring(unsigned int beginIndex) const { return substring(beginIndex, len); }
332  String substring(unsigned int beginIndex, unsigned int endIndex) const;
333 
334  // modification
335  void replace(char find, char replace);
336  void replace(const String& find, const String& replace);
337  void remove(unsigned int index);
338  void remove(unsigned int index, unsigned int count);
339  void toLowerCase(void);
340  void toUpperCase(void);
341  void trim(void);
342 
343  // parsing/conversion
344  long toInt(void) const;
345  float toFloat(void) const;
346 
347 
348  //void printTo(Print &p) const;
349 
350 
351  protected:
352  char *buffer = nullptr; // the actual char array
353  uint16_t capacity = 0; // the array length minus one (for the '\0')
354  uint16_t len = 0; // the String length (not counting the '\0')
355  //unsigned char flags; // unused, for future features
356 
357  protected:
358  void STRING_IRAM_ATTR invalidate(void);
359  bool STRING_IRAM_ATTR changeBuffer(unsigned int maxStrLen);
360 
361  // copy and move
362  String & copy(const char *cstr, unsigned int length);
363  String& copy(flash_string_t pstr, unsigned int length);
364 #ifdef __GXX_EXPERIMENTAL_CXX0X__
365  void move(String &rhs);
366 #endif
367 };
368 
369 class StringSumHelper : public String
370 {
371  public:
372  StringSumHelper(const String &s) : String(s) {}
373  StringSumHelper(const char *p) : String(p) {}
374  StringSumHelper(char c) : String(c) {}
375  StringSumHelper(unsigned char num) : String(num) {}
376  StringSumHelper(int num) : String(num) {}
377  StringSumHelper(unsigned int num) : String(num) {}
378  StringSumHelper(long num) : String(num) {}
379  StringSumHelper(unsigned long num) : String(num) {}
380  StringSumHelper(float num) : String(num) {}
381  StringSumHelper(double num) : String(num) {}
382 };
383 
384 #include "FlashString.h"
385 #include "SplitString.h"
386 
387 #endif // __cplusplus
388 #endif
389 // WSTRING_H
bool setLength(unsigned int length)
set the string length accordingly, expanding if necessary
static const String empty
An empty string evaluates to true.
Definition: WString.h:115
describes a counted string stored in flash memory
Definition: FlashString.h:171
The string class.
Definition: WString.h:104
static const String nullstr
A null string evaluates to false.
Definition: WString.h:114
unsigned int getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const
read contents of string into a buffer
Definition: WString.h:369