Pico-Arduino
WString.h
1 /*
2  String library for Wiring & Arduino
3  ...mostly rewritten by Paul Stoffregen...
4  Copyright (c) 2009-10 Hernando Barragan. All right reserved.
5  Copyright 2011, Paul Stoffregen, paul@pjrc.com
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
22 #ifdef __cplusplus
23 
24 #ifndef __ARDUINO_STRINGS__
25 #define __ARDUINO_STRINGS__
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #if defined(__AVR__)
31 #include "avr/pgmspace.h"
32 #else
33 #include "deprecated-avr-comp/avr/pgmspace.h"
34 #endif
35 
36 namespace arduino {
37 
38 // When compiling programs with this class, the following gcc parameters
39 // dramatically increase performance and memory (RAM) efficiency, typically
40 // with little or no increase in code size.
41 // -felide-constructors
42 // -std=c++0x
43 
44 class __FlashStringHelper;
45 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
46 
47 // An inherited class for holding the result of a concatenation. These
48 // result objects are assumed to be writable by subsequent concatenations.
49 class StringSumHelper;
50 
51 // The string class
52 class String
53 {
54  friend class StringSumHelper;
55  // use a function pointer to allow for "if (s)" without the
56  // complications of an operator bool(). for more information, see:
57  // http://www.artima.com/cppsource/safebool.html
58  typedef void (String::*StringIfHelperType)() const;
59  void StringIfHelper() const {}
60 
61  static size_t const FLT_MAX_DECIMAL_PLACES = 10;
62  static size_t const DBL_MAX_DECIMAL_PLACES = FLT_MAX_DECIMAL_PLACES;
63 
64 public:
65  // constructors
66  // creates a copy of the initial value.
67  // if the initial value is null or invalid, or if memory allocation
68  // fails, the string will be marked as invalid (i.e. "if (s)" will
69  // be false).
70  String(const char *cstr = "");
71  String(const String &str);
72  String(const __FlashStringHelper *str);
73  #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
74  String(String &&rval);
75  String(StringSumHelper &&rval);
76  #endif
77  explicit String(char c);
78  explicit String(unsigned char, unsigned char base=10);
79  explicit String(int, unsigned char base=10);
80  explicit String(unsigned int, unsigned char base=10);
81  explicit String(long, unsigned char base=10);
82  explicit String(unsigned long, unsigned char base=10);
83  explicit String(float, unsigned char decimalPlaces=2);
84  explicit String(double, unsigned char decimalPlaces=2);
85  ~String(void);
86 
87  // memory management
88  // return true on success, false on failure (in which case, the string
89  // is left unchanged). reserve(0), if successful, will validate an
90  // invalid string (i.e., "if (s)" will be true afterwards)
91  unsigned char reserve(unsigned int size);
92  inline unsigned int length(void) const {return len;}
93 
94  // creates a copy of the assigned value. if the value is null or
95  // invalid, or if the memory allocation fails, the string will be
96  // marked as invalid ("if (s)" will be false).
97  String & operator = (const String &rhs);
98  String & operator = (const char *cstr);
99  String & operator = (const __FlashStringHelper *str);
100  #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
101  String & operator = (String &&rval);
102  String & operator = (StringSumHelper &&rval);
103  #endif
104 
105  // concatenate (works w/ built-in types)
106 
107  // returns true on success, false on failure (in which case, the string
108  // is left unchanged). if the argument is null or invalid, the
109  // concatenation is considered unsucessful.
110  unsigned char concat(const String &str);
111  unsigned char concat(const char *cstr);
112  unsigned char concat(char c);
113  unsigned char concat(unsigned char num);
114  unsigned char concat(int num);
115  unsigned char concat(unsigned int num);
116  unsigned char concat(long num);
117  unsigned char concat(unsigned long num);
118  unsigned char concat(float num);
119  unsigned char concat(double num);
120  unsigned char concat(const __FlashStringHelper * str);
121 
122  // if there's not enough memory for the concatenated value, the string
123  // will be left unchanged (but this isn't signalled in any way)
124  String & operator += (const String &rhs) {concat(rhs); return (*this);}
125  String & operator += (const char *cstr) {concat(cstr); return (*this);}
126  String & operator += (char c) {concat(c); return (*this);}
127  String & operator += (unsigned char num) {concat(num); return (*this);}
128  String & operator += (int num) {concat(num); return (*this);}
129  String & operator += (unsigned int num) {concat(num); return (*this);}
130  String & operator += (long num) {concat(num); return (*this);}
131  String & operator += (unsigned long num) {concat(num); return (*this);}
132  String & operator += (float num) {concat(num); return (*this);}
133  String & operator += (double num) {concat(num); return (*this);}
134  String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
135 
136  friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
137  friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
138  friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
139  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
140  friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
141  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
142  friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
143  friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
144  friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
145  friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
146  friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
147 
148  // comparison (only works w/ Strings and "strings")
149  operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
150  int compareTo(const String &s) const;
151  int compareTo(const char *cstr) const;
152  unsigned char equals(const String &s) const;
153  unsigned char equals(const char *cstr) const;
154 
155  friend unsigned char operator == (const String &a, const String &b) { return a.equals(b); }
156  friend unsigned char operator == (const String &a, const char *b) { return a.equals(b); }
157  friend unsigned char operator == (const char *a, const String &b) { return b == a; }
158  friend unsigned char operator < (const String &a, const String &b) { return a.compareTo(b) < 0; }
159  friend unsigned char operator < (const String &a, const char *b) { return a.compareTo(b) < 0; }
160  friend unsigned char operator < (const char *a, const String &b) { return b.compareTo(a) > 0; }
161 
162  friend unsigned char operator != (const String &a, const String &b) { return !(a == b); }
163  friend unsigned char operator != (const String &a, const char *b) { return !(a == b); }
164  friend unsigned char operator != (const char *a, const String &b) { return !(a == b); }
165  friend unsigned char operator > (const String &a, const String &b) { return b < a; }
166  friend unsigned char operator > (const String &a, const char *b) { return b < a; }
167  friend unsigned char operator > (const char *a, const String &b) { return b < a; }
168  friend unsigned char operator <= (const String &a, const String &b) { return !(b < a); }
169  friend unsigned char operator <= (const String &a, const char *b) { return !(b < a); }
170  friend unsigned char operator <= (const char *a, const String &b) { return !(b < a); }
171  friend unsigned char operator >= (const String &a, const String &b) { return !(a < b); }
172  friend unsigned char operator >= (const String &a, const char *b) { return !(a < b); }
173  friend unsigned char operator >= (const char *a, const String &b) { return !(a < b); }
174 
175  unsigned char equalsIgnoreCase(const String &s) const;
176  unsigned char startsWith( const String &prefix) const;
177  unsigned char startsWith(const String &prefix, unsigned int offset) const;
178  unsigned char endsWith(const String &suffix) const;
179 
180  // character acccess
181  char charAt(unsigned int index) const;
182  void setCharAt(unsigned int index, char c);
183  char operator [] (unsigned int index) const;
184  char& operator [] (unsigned int index);
185  void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
186  void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
187  { getBytes((unsigned char *)buf, bufsize, index); }
188  const char* c_str() const { return buffer; }
189  char* begin() { return buffer; }
190  char* end() { return buffer + length(); }
191  const char* begin() const { return c_str(); }
192  const char* end() const { return c_str() + length(); }
193 
194  // search
195  int indexOf( char ch ) const;
196  int indexOf( char ch, unsigned int fromIndex ) const;
197  int indexOf( const String &str ) const;
198  int indexOf( const String &str, unsigned int fromIndex ) const;
199  int lastIndexOf( char ch ) const;
200  int lastIndexOf( char ch, unsigned int fromIndex ) const;
201  int lastIndexOf( const String &str ) const;
202  int lastIndexOf( const String &str, unsigned int fromIndex ) const;
203  String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
204  String substring( unsigned int beginIndex, unsigned int endIndex ) const;
205 
206  // modification
207  void replace(char find, char replace);
208  void replace(const String& find, const String& replace);
209  void remove(unsigned int index);
210  void remove(unsigned int index, unsigned int count);
211  void toLowerCase(void);
212  void toUpperCase(void);
213  void trim(void);
214 
215  // parsing/conversion
216  long toInt(void) const;
217  float toFloat(void) const;
218  double toDouble(void) const;
219 
220 protected:
221  char *buffer; // the actual char array
222  unsigned int capacity; // the array length minus one (for the '\0')
223  unsigned int len; // the String length (not counting the '\0')
224 protected:
225  void init(void);
226  void invalidate(void);
227  unsigned char changeBuffer(unsigned int maxStrLen);
228  unsigned char concat(const char *cstr, unsigned int length);
229 
230  // copy and move
231  String & copy(const char *cstr, unsigned int length);
232  String & copy(const __FlashStringHelper *pstr, unsigned int length);
233  #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
234  void move(String &rhs);
235  #endif
236 };
237 
238 class StringSumHelper : public String
239 {
240 public:
241  StringSumHelper(const String &s) : String(s) {}
242  StringSumHelper(const char *p) : String(p) {}
243  StringSumHelper(char c) : String(c) {}
244  StringSumHelper(unsigned char num) : String(num) {}
245  StringSumHelper(int num) : String(num) {}
246  StringSumHelper(unsigned int num) : String(num) {}
247  StringSumHelper(long num) : String(num) {}
248  StringSumHelper(unsigned long num) : String(num) {}
249  StringSumHelper(float num) : String(num) {}
250  StringSumHelper(double num) : String(num) {}
251 };
252 
253 } // namespace arduino
254 
255 #endif // __cplusplus
256 #endif // __ARDUINO_STRINGS__