WString.h 10.4 KB
Newer Older
M
me-no-dev 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 WString.h - String library for Wiring & Arduino
 ...mostly rewritten by Paul Stoffregen...
 Copyright (c) 2009-10 Hernando Barragan.  All right reserved.
 Copyright 2011, Paul Stoffregen, paul@pjrc.com

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
M
me-no-dev 已提交
29
#include <pgmspace.h>
M
me-no-dev 已提交
30 31 32 33 34 35 36

// An inherited class for holding the result of a concatenation.  These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;

// an abstract class used as a means to proide a unique pointer type
// but really has no body
37 38
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
M
me-no-dev 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

// The string class
class String
{
    // use a function pointer to allow for "if (s)" without the
    // complications of an operator bool(). for more information, see:
    // http://www.artima.com/cppsource/safebool.html
    typedef void (String::*StringIfHelperType)() const;
    void StringIfHelper() const
    {
    }

public:
    // constructors
    // creates a copy of the initial value.
    // if the initial value is null or invalid, or if memory allocation
    // fails, the string will be marked as invalid (i.e. "if (s)" will
    // be false).
    String(const char *cstr = "");
    String(const String &str);
59
    String(const __FlashStringHelper *str) : String(reinterpret_cast<const char *>(str)) {};
M
me-no-dev 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    String(String &&rval);
    String(StringSumHelper &&rval);
#endif
    explicit String(char c);
    explicit String(unsigned char, unsigned char base = 10);
    explicit String(int, unsigned char base = 10);
    explicit String(unsigned int, unsigned char base = 10);
    explicit String(long, unsigned char base = 10);
    explicit String(unsigned long, unsigned char base = 10);
    explicit String(float, unsigned char decimalPlaces = 2);
    explicit String(double, unsigned char decimalPlaces = 2);
    ~String(void);

    // memory management
    // return true on success, false on failure (in which case, the string
    // is left unchanged).  reserve(0), if successful, will validate an
    // invalid string (i.e., "if (s)" will be true afterwards)
    unsigned char reserve(unsigned int size);
    inline unsigned int length(void) const
    {
        if(buffer) {
            return len;
        } else {
            return 0;
        }
    }

    // creates a copy of the assigned value.  if the value is null or
    // invalid, or if the memory allocation fails, the string will be
    // marked as invalid ("if (s)" will be false).
    String & operator =(const String &rhs);
    String & operator =(const char *cstr);
93
    String & operator = (const __FlashStringHelper *str);
M
me-no-dev 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    String & operator =(String &&rval);
    String & operator =(StringSumHelper &&rval);
#endif

    // concatenate (works w/ built-in types)

    // returns true on success, false on failure (in which case, the string
    // is left unchanged).  if the argument is null or invalid, the
    // concatenation is considered unsucessful.
    unsigned char concat(const String &str);
    unsigned char concat(const char *cstr);
    unsigned char concat(char c);
    unsigned char concat(unsigned char c);
    unsigned char concat(int num);
    unsigned char concat(unsigned int num);
    unsigned char concat(long num);
    unsigned char concat(unsigned long num);
    unsigned char concat(float num);
    unsigned char concat(double num);
114
    unsigned char concat(const __FlashStringHelper * str);
M
me-no-dev 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167

    // if there's not enough memory for the concatenated value, the string
    // will be left unchanged (but this isn't signalled in any way)
    String & operator +=(const String &rhs)
    {
        concat(rhs);
        return (*this);
    }
    String & operator +=(const char *cstr)
    {
        concat(cstr);
        return (*this);
    }
    String & operator +=(char c)
    {
        concat(c);
        return (*this);
    }
    String & operator +=(unsigned char num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(int num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(unsigned int num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(long num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(unsigned long num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(float num)
    {
        concat(num);
        return (*this);
    }
    String & operator +=(double num)
    {
        concat(num);
        return (*this);
    }
168 169 170 171 172
    String & operator += (const __FlashStringHelper *str)
    {
        concat(str);
        return (*this);
    }
M
me-no-dev 已提交
173 174 175 176 177 178 179 180 181 182 183

    friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, char c);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, int num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, long num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
    friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
184
    friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
M
me-no-dev 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

    // comparison (only works w/ Strings and "strings")
    operator StringIfHelperType() const
    {
        return buffer ? &String::StringIfHelper : 0;
    }
    int compareTo(const String &s) const;
    unsigned char equals(const String &s) const;
    unsigned char equals(const char *cstr) const;
    unsigned char operator ==(const String &rhs) const
    {
        return equals(rhs);
    }
    unsigned char operator ==(const char *cstr) const
    {
        return equals(cstr);
    }
    unsigned char operator !=(const String &rhs) const
    {
        return !equals(rhs);
    }
    unsigned char operator !=(const char *cstr) const
    {
        return !equals(cstr);
    }
    unsigned char operator <(const String &rhs) const;
    unsigned char operator >(const String &rhs) const;
    unsigned char operator <=(const String &rhs) const;
    unsigned char operator >=(const String &rhs) const;
    unsigned char equalsIgnoreCase(const String &s) const;
M
Me No Dev 已提交
215
    unsigned char equalsConstantTime(const String &s) const;
M
me-no-dev 已提交
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
    unsigned char startsWith(const String &prefix) const;
    unsigned char startsWith(const String &prefix, unsigned int offset) const;
    unsigned char endsWith(const String &suffix) const;

    // character acccess
    char charAt(unsigned int index) const;
    void setCharAt(unsigned int index, char c);
    char operator [](unsigned int index) const;
    char& operator [](unsigned int index);
    void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
    void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const
    {
        getBytes((unsigned char *) buf, bufsize, index);
    }
    const char * c_str() const
    {
        return buffer;
    }

    // search
    int indexOf(char ch) const;
    int indexOf(char ch, unsigned int fromIndex) const;
    int indexOf(const String &str) const;
    int indexOf(const String &str, unsigned int fromIndex) const;
    int lastIndexOf(char ch) const;
    int lastIndexOf(char ch, unsigned int fromIndex) const;
    int lastIndexOf(const String &str) const;
    int lastIndexOf(const String &str, unsigned int fromIndex) const;
    String substring(unsigned int beginIndex) const
    {
        return substring(beginIndex, len);
    }
    ;
    String substring(unsigned int beginIndex, unsigned int endIndex) const;

    // modification
    void replace(char find, char replace);
    void replace(const String& find, const String& replace);
    void remove(unsigned int index);
    void remove(unsigned int index, unsigned int count);
    void toLowerCase(void);
    void toUpperCase(void);
    void trim(void);

    // parsing/conversion
    long toInt(void) const;
    float toFloat(void) const;
T
Terry J Myers 已提交
263
    double toDouble(void) const;
M
me-no-dev 已提交
264 265 266 267 268 269 270 271 272 273 274 275 276

protected:
    char *buffer;	        // the actual char array
    unsigned int capacity;  // the array length minus one (for the '\0')
    unsigned int len;       // the String length (not counting the '\0')
protected:
    void init(void);
    void invalidate(void);
    unsigned char changeBuffer(unsigned int maxStrLen);
    unsigned char concat(const char *cstr, unsigned int length);

    // copy and move
    String & copy(const char *cstr, unsigned int length);
277
    String & copy(const __FlashStringHelper *pstr, unsigned int length);
M
me-no-dev 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    void move(String &rhs);
#endif
};

class StringSumHelper: public String
{
public:
    StringSumHelper(const String &s) :
        String(s)
    {
    }
    StringSumHelper(const char *p) :
        String(p)
    {
    }
    StringSumHelper(char c) :
        String(c)
    {
    }
    StringSumHelper(unsigned char num) :
        String(num)
    {
    }
    StringSumHelper(int num) :
        String(num)
    {
    }
    StringSumHelper(unsigned int num) :
        String(num)
    {
    }
    StringSumHelper(long num) :
        String(num)
    {
    }
    StringSumHelper(unsigned long num) :
        String(num)
    {
    }
    StringSumHelper(float num) :
        String(num)
    {
    }
    StringSumHelper(double num) :
        String(num)
    {
    }
};

#endif  // __cplusplus
#endif  // String_class_h