|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <stdlib.h> |
| 4 | +#include <string> |
| 5 | +#include <algorithm> |
| 6 | +#include <iostream> |
| 7 | +#include "AvrMath.h" |
| 8 | + |
| 9 | +typedef std::string string; |
| 10 | + |
| 11 | + |
| 12 | +// Compatibility with string class |
| 13 | +class String: public string |
| 14 | +{ |
| 15 | + public: |
| 16 | + |
| 17 | + // allow "string s; if (s) {}" |
| 18 | + // http://www.artima.com/cppsource/safebool.html |
| 19 | + typedef void (String::*TTDNSCstring)() const; |
| 20 | + void ttdnsc() const {} |
| 21 | + operator TTDNSCstring() const { return &String::ttdnsc; } |
| 22 | + |
| 23 | + private: |
| 24 | + static const char* digit(int val) { |
| 25 | + const char* bank = "0123456789ABCDEF"; |
| 26 | + return bank + val; |
| 27 | + } |
| 28 | + |
| 29 | + static string mytoa(unsigned long val, int base) { |
| 30 | + int n = val % base; |
| 31 | + string place = string(digit(n), 1); |
| 32 | + if (val < base) return place; |
| 33 | + return mytoa(val / base, base) + place; |
| 34 | + } |
| 35 | + |
| 36 | + static string mytoas(long val, int base) { |
| 37 | + string ret = mytoa(abs(val), base); |
| 38 | + return 0 <= val ? ret : string("-") + ret; |
| 39 | + } |
| 40 | + |
| 41 | +public: |
| 42 | + ~String(void) {} |
| 43 | + String(const char *cstr = ""): string(cstr) {} |
| 44 | + String(const string &str): string(str.c_str()) {} |
| 45 | + String(const String &str): string(str.c_str()) {} |
| 46 | + explicit String(char c): string(&c, 1) {} |
| 47 | + |
| 48 | + explicit String(unsigned char val, unsigned char base=10): string(mytoa(val, base)) {} |
| 49 | + explicit String(int val, unsigned char base=10): string(mytoas(val, base)) {} |
| 50 | + explicit String(unsigned int val , unsigned char base=10): string(mytoa(val, base)) {} |
| 51 | + explicit String(long val, unsigned char base=10): string(mytoas(val, base)) {} |
| 52 | + explicit String(unsigned long val, unsigned char base=10): string(mytoa(val, base)) {} |
| 53 | + |
| 54 | + explicit String(float val, unsigned char decimalPlaces=2): |
| 55 | + string(mytoas(val, 10) + "." + mytoa(abs(val - (long)val) * pow(10, decimalPlaces), 10)) {} |
| 56 | + explicit String(double val, unsigned char decimalPlaces=2): |
| 57 | + string(mytoas(val, 10) + "." + mytoa(abs(val - (long)val) * pow(10, decimalPlaces), 10)) {} |
| 58 | + |
| 59 | + String & operator = (const String &rhs) { assign(rhs); return *this; } |
| 60 | + String & operator = (const char *cstr) { assign(cstr); return *this; } |
| 61 | + |
| 62 | + unsigned char reserve(unsigned int size) { return true; } // calling reserve(size) segfaults, no idea why |
| 63 | + |
| 64 | + unsigned char concat(const String &str) { append(str); return 1; } |
| 65 | + unsigned char concat(const char *cstr) { append(cstr); return 1; } |
| 66 | + unsigned char concat(char c) { append((const char*)&c, 1); return 1; } |
| 67 | + unsigned char concat(unsigned char c) { append((const char*)&c, 1); return 1; } |
| 68 | + unsigned char concat(int num) { append(String(num)); return 1; } |
| 69 | + unsigned char concat(unsigned int num) { append(String(num)); return 1; } |
| 70 | + unsigned char concat(long num) { append(String(num)); return 1; } |
| 71 | + unsigned char concat(unsigned long num) { append(String(num)); return 1; } |
| 72 | + unsigned char concat(float num) { append(String(num)); return 1; } |
| 73 | + unsigned char concat(double num) { append(String(num)); return 1; } |
| 74 | + |
| 75 | + String & operator += (const String &rhs) { concat(rhs); return *this; } |
| 76 | + String & operator += (const char *cstr) { concat(cstr); return *this; } |
| 77 | + String & operator += (char c) { concat(c); return *this; } |
| 78 | + String & operator += (unsigned char num) { concat(num); return *this; } |
| 79 | + String & operator += (int num) { concat(num); return *this; } |
| 80 | + String & operator += (unsigned int num) { concat(num); return *this; } |
| 81 | + String & operator += (long num) { concat(num); return *this; } |
| 82 | + String & operator += (unsigned long num) { concat(num); return *this; } |
| 83 | + String & operator += (float num) { concat(num); return *this; } |
| 84 | + String & operator += (double num) { concat(num); return *this; } |
| 85 | + |
| 86 | + |
| 87 | + int compareTo(const String &s) const { return compare(s); } |
| 88 | + unsigned char equals(const String &s) const { return compareTo(s) == 0; } |
| 89 | + unsigned char equals(const char *cstr) const { return compareTo(String(cstr)) == 0; } |
| 90 | + unsigned char equal(const String &s) const { return equals(s); } |
| 91 | + unsigned char equal(const char *cstr) const { return equals(cstr); } |
| 92 | + unsigned char equalsIgnoreCase(const String &s) const { |
| 93 | + String a = String(*this); |
| 94 | + String b = String(s); |
| 95 | + a.toUpperCase(); |
| 96 | + b.toUpperCase(); |
| 97 | + return a.compare(b) == 0; |
| 98 | + } |
| 99 | + |
| 100 | + unsigned char startsWith(const String &prefix) const { return find(prefix) == 0; } |
| 101 | + unsigned char startsWith(const String &prefix, unsigned int offset) const { return find(prefix, offset) == offset; } |
| 102 | + unsigned char endsWith(const String &suffix) const { return rfind(suffix) == length() - suffix.length(); } |
| 103 | + |
| 104 | + char charAt(unsigned int index) const { return operator[](index); } |
| 105 | + void setCharAt(unsigned int index, char c) { (*this)[index] = c; } |
| 106 | + |
| 107 | + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const { copy((char*)buf, bufsize, index); } |
| 108 | + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const |
| 109 | + { getBytes((unsigned char *)buf, bufsize, index); } |
| 110 | + |
| 111 | + int indexOf( char ch ) const { return find(ch); } |
| 112 | + int indexOf( char ch, unsigned int fromIndex ) const { return find(ch, fromIndex); } |
| 113 | + int indexOf( const String &str ) const { return find(str); } |
| 114 | + int indexOf( const String &str, unsigned int fromIndex ) const { return find(str, fromIndex); } |
| 115 | + int lastIndexOf( char ch ) const { return rfind(ch); } |
| 116 | + int lastIndexOf( char ch, unsigned int fromIndex ) const { return rfind(ch, fromIndex); } |
| 117 | + int lastIndexOf( const String &str ) const { return rfind(str); } |
| 118 | + int lastIndexOf( const String &str, unsigned int fromIndex ) const { return rfind(str, fromIndex); } |
| 119 | + String substring( unsigned int beginIndex ) const { return String(substr(beginIndex)); } |
| 120 | + String substring( unsigned int beginIndex, unsigned int endIndex ) const { return String(substr(beginIndex, endIndex)); } |
| 121 | + |
| 122 | + void replace(const String& target, const String& repl) { |
| 123 | + int i = 0; |
| 124 | + while ((i = find(target, i)) != npos) { |
| 125 | + assign(substr(0, i) + repl + substr(i + target.length())); |
| 126 | + i += repl.length(); |
| 127 | + } |
| 128 | + } |
| 129 | + void replace(char target, char repl) { |
| 130 | + replace(String(target), String(repl)); |
| 131 | + } |
| 132 | + void remove(unsigned int index) { assign(substr(0, index)); } |
| 133 | + void remove(unsigned int index, unsigned int count) { assign(substr(0, index) + substr(min(length(), index + count), count)); } |
| 134 | + void toLowerCase(void) { std::transform(begin(), end(), begin(), ::tolower); } |
| 135 | + void toUpperCase(void) { std::transform(begin(), end(), begin(), ::toupper); } |
| 136 | + |
| 137 | + void trim(void) { |
| 138 | + int b; |
| 139 | + int e; |
| 140 | + for (b = 0; b < length() && isSpace(charAt(b)); ++b); |
| 141 | + for (e = length() - 1; e > b && isSpace(charAt(e)); --e); |
| 142 | + assign(substr(b, e - b + 1)); |
| 143 | + } |
| 144 | + |
| 145 | + long toInt(void) const { return std::stol(*this); } |
| 146 | + float toFloat(void) const { return std::stof(*this); } |
| 147 | + double toDouble(void) const { return std::stod(*this); } |
| 148 | + |
| 149 | +}; |
| 150 | + |
| 151 | +template <typename T> inline std::ostream& operator << ( std::ostream& out, const std::basic_string<T>& bs ) { |
| 152 | + out << bs.c_str(); |
| 153 | + return out; |
| 154 | +} |
| 155 | + |
| 156 | +inline std::ostream& operator << ( std::ostream& out, const String& bs ) { |
| 157 | + out << bs.c_str(); |
| 158 | + return out; |
| 159 | +} |
| 160 | + |
0 commit comments