1 /*
2   WString.h - 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 #ifndef String_class_h
23 #define String_class_h
24 #ifdef __cplusplus
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <avr/pgmspace.h>
30 
31 // When compiling programs with this class, the following gcc parameters
32 // dramatically increase performance and memory (RAM) efficiency, typically
33 // with little or no increase in code size.
34 //     -felide-constructors
35 //     -std=c++0x
36 
37 class __FlashStringHelper;
38 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
39 
40 // An inherited class for holding the result of a concatenation.  These
41 // result objects are assumed to be writable by subsequent concatenations.
42 class StringSumHelper;
43 
44 // The string class
45 class String
46 {
47 	// use a function pointer to allow for "if (s)" without the
48 	// complications of an operator bool(). for more information, see:
49 	// http://www.artima.com/cppsource/safebool.html
50 	typedef void (String::*StringIfHelperType)() const;
StringIfHelper()51 	void StringIfHelper() const {}
52 
53 public:
54 	// constructors
55 	// creates a copy of the initial value.
56 	// if the initial value is null or invalid, or if memory allocation
57 	// fails, the string will be marked as invalid (i.e. "if (s)" will
58 	// be false).
59 	String(const char *cstr = "");
60 	String(const String &str);
61 	String(const __FlashStringHelper *str);
62        #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
63 	String(String &&rval);
64 	String(StringSumHelper &&rval);
65 	#endif
66 	explicit String(char c);
67 	explicit String(unsigned char, unsigned char base=10);
68 	explicit String(int, unsigned char base=10);
69 	explicit String(unsigned int, unsigned char base=10);
70 	explicit String(long, unsigned char base=10);
71 	explicit String(unsigned long, unsigned char base=10);
72 	explicit String(float, unsigned char decimalPlaces=2);
73 	explicit String(double, unsigned char decimalPlaces=2);
74 	~String(void);
75 
76 	// memory management
77 	// return true on success, false on failure (in which case, the string
78 	// is left unchanged).  reserve(0), if successful, will validate an
79 	// invalid string (i.e., "if (s)" will be true afterwards)
80 	unsigned char reserve(unsigned int size);
length(void)81 	inline unsigned int length(void) const {return len;}
82 
83 	// creates a copy of the assigned value.  if the value is null or
84 	// invalid, or if the memory allocation fails, the string will be
85 	// marked as invalid ("if (s)" will be false).
86 	String & operator = (const String &rhs);
87 	String & operator = (const char *cstr);
88 	String & operator = (const __FlashStringHelper *str);
89        #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
90 	String & operator = (String &&rval);
91 	String & operator = (StringSumHelper &&rval);
92 	#endif
93 
94 	// concatenate (works w/ built-in types)
95 
96 	// returns true on success, false on failure (in which case, the string
97 	// is left unchanged).  if the argument is null or invalid, the
98 	// concatenation is considered unsucessful.
99 	unsigned char concat(const String &str);
100 	unsigned char concat(const char *cstr);
101 	unsigned char concat(char c);
102 	unsigned char concat(unsigned char c);
103 	unsigned char concat(int num);
104 	unsigned char concat(unsigned int num);
105 	unsigned char concat(long num);
106 	unsigned char concat(unsigned long num);
107 	unsigned char concat(float num);
108 	unsigned char concat(double num);
109 	unsigned char concat(const __FlashStringHelper * str);
110 
111 	// if there's not enough memory for the concatenated value, the string
112 	// will be left unchanged (but this isn't signalled in any way)
113 	String & operator += (const String &rhs)	{concat(rhs); return (*this);}
114 	String & operator += (const char *cstr)		{concat(cstr); return (*this);}
115 	String & operator += (char c)			{concat(c); return (*this);}
116 	String & operator += (unsigned char num)		{concat(num); return (*this);}
117 	String & operator += (int num)			{concat(num); return (*this);}
118 	String & operator += (unsigned int num)		{concat(num); return (*this);}
119 	String & operator += (long num)			{concat(num); return (*this);}
120 	String & operator += (unsigned long num)	{concat(num); return (*this);}
121 	String & operator += (float num)		{concat(num); return (*this);}
122 	String & operator += (double num)		{concat(num); return (*this);}
123 	String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
124 
125 	friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
126 	friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
127 	friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
128 	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
129 	friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
130 	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
131 	friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
132 	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
133 	friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
134 	friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
135 	friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
136 
137 	// comparison (only works w/ Strings and "strings")
StringIfHelperType()138 	operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
139 	int compareTo(const String &s) const;
140 	unsigned char equals(const String &s) const;
141 	unsigned char equals(const char *cstr) const;
142 	unsigned char operator == (const String &rhs) const {return equals(rhs);}
143 	unsigned char operator == (const char *cstr) const {return equals(cstr);}
144 	unsigned char operator != (const String &rhs) const {return !equals(rhs);}
145 	unsigned char operator != (const char *cstr) const {return !equals(cstr);}
146 	unsigned char operator <  (const String &rhs) const;
147 	unsigned char operator >  (const String &rhs) const;
148 	unsigned char operator <= (const String &rhs) const;
149 	unsigned char operator >= (const String &rhs) const;
150 	unsigned char equalsIgnoreCase(const String &s) const;
151 	unsigned char startsWith( const String &prefix) const;
152 	unsigned char startsWith(const String &prefix, unsigned int offset) const;
153 	unsigned char endsWith(const String &suffix) const;
154 
155 	// character acccess
156 	char charAt(unsigned int index) const;
157 	void setCharAt(unsigned int index, char c);
158 	char operator [] (unsigned int index) const;
159 	char& operator [] (unsigned int index);
160 	void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
161 	void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
162 		{ getBytes((unsigned char *)buf, bufsize, index); }
c_str()163 	const char* c_str() const { return buffer; }
begin()164 	char* begin() { return buffer; }
end()165 	char* end() { return buffer + length(); }
begin()166 	const char* begin() const { return c_str(); }
end()167 	const char* end() const { return c_str() + length(); }
168 
169 	// search
170 	int indexOf( char ch ) const;
171 	int indexOf( char ch, unsigned int fromIndex ) const;
172 	int indexOf( const String &str ) const;
173 	int indexOf( const String &str, unsigned int fromIndex ) const;
174 	int lastIndexOf( char ch ) const;
175 	int lastIndexOf( char ch, unsigned int fromIndex ) const;
176 	int lastIndexOf( const String &str ) const;
177 	int lastIndexOf( const String &str, unsigned int fromIndex ) const;
substring(unsigned int beginIndex)178 	String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
179 	String substring( unsigned int beginIndex, unsigned int endIndex ) const;
180 
181 	// modification
182 	void replace(char find, char replace);
183 	void replace(const String& find, const String& replace);
184 	void remove(unsigned int index);
185 	void remove(unsigned int index, unsigned int count);
186 	void toLowerCase(void);
187 	void toUpperCase(void);
188 	void trim(void);
189 
190 	// parsing/conversion
191 	long toInt(void) const;
192 	float toFloat(void) const;
193 	double toDouble(void) const;
194 
195 protected:
196 	char *buffer;	        // the actual char array
197 	unsigned int capacity;  // the array length minus one (for the '\0')
198 	unsigned int len;       // the String length (not counting the '\0')
199 protected:
200 	void init(void);
201 	void invalidate(void);
202 	unsigned char changeBuffer(unsigned int maxStrLen);
203 	unsigned char concat(const char *cstr, unsigned int length);
204 
205 	// copy and move
206 	String & copy(const char *cstr, unsigned int length);
207 	String & copy(const __FlashStringHelper *pstr, unsigned int length);
208        #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
209 	void move(String &rhs);
210 	#endif
211 };
212 
213 class StringSumHelper : public String
214 {
215 public:
StringSumHelper(const String & s)216 	StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char * p)217 	StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c)218 	StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num)219 	StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num)220 	StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num)221 	StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num)222 	StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num)223 	StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num)224 	StringSumHelper(float num) : String(num) {}
StringSumHelper(double num)225 	StringSumHelper(double num) : String(num) {}
226 };
227 
228 #endif  // __cplusplus
229 #endif  // String_class_h
230