Franz Pucher
/
ESP8266_HTTP_MQTT_Server
M0 communication to configurable-Web-Server (MQTT) Version 0.1
- Arduino IDE
- Sensoren
- ESP-Programmierung
- Web-Server
- Netzwerktopologie
- Browser basierende Kommunikation
- M2M Kommunikation
- MQTT over TLS-M3-Projekt (1/2018)
Siehe auch FTKL-Tagung 2016
String.cpp@2:63135b94c898, 2018-01-14 (annotated)
- Committer:
- fpucher
- Date:
- Sun Jan 14 19:49:08 2018 +0000
- Revision:
- 2:63135b94c898
New Program
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fpucher | 2:63135b94c898 | 1 | #include <stdio.h> |
fpucher | 2:63135b94c898 | 2 | //#include <mem.h> |
fpucher | 2:63135b94c898 | 3 | #include <string.h> |
fpucher | 2:63135b94c898 | 4 | //#include <iostream.h> |
fpucher | 2:63135b94c898 | 5 | |
fpucher | 2:63135b94c898 | 6 | /* |
fpucher | 2:63135b94c898 | 7 | Caveats in this class are I do not deal with UNICODE text or any type of extended ascii text. For example this class can not handle |
fpucher | 2:63135b94c898 | 8 | double byte strings as you would encounter in the far east languages or arabic alphabet which is bidirectional. |
fpucher | 2:63135b94c898 | 9 | I also do not provide extensive error checking for parameters. If you pass null for the sz in the constructor below the code GPFs. |
fpucher | 2:63135b94c898 | 10 | Doing any operator like = or > on an empty string will result in predictable but disastrous results like GPF. I could instead make it |
fpucher | 2:63135b94c898 | 11 | return something but it's better to GPF than fail in benign way and not let the caller know about it. It will hide a potential bug in |
fpucher | 2:63135b94c898 | 12 | callers code which might have other side effects that won't as obvious as the GPF this produces. If you want to use this code for |
fpucher | 2:63135b94c898 | 13 | a class libarary where you may not have control over the callers actions, you need to make it fail benignly and have an error mechanism |
fpucher | 2:63135b94c898 | 14 | or have it throw exceptions. You can also assert. But it's always better to deal with the exception than to simply assert. |
fpucher | 2:63135b94c898 | 15 | */ |
fpucher | 2:63135b94c898 | 16 | |
fpucher | 2:63135b94c898 | 17 | class String |
fpucher | 2:63135b94c898 | 18 | { |
fpucher | 2:63135b94c898 | 19 | private: |
fpucher | 2:63135b94c898 | 20 | // Added const member only to demonstrate initialization of const members. |
fpucher | 2:63135b94c898 | 21 | const int m_cchTest; |
fpucher | 2:63135b94c898 | 22 | // length of the string |
fpucher | 2:63135b94c898 | 23 | int m_cch; |
fpucher | 2:63135b94c898 | 24 | // null terminated string. Makes it easy to give out null terminated strings. |
fpucher | 2:63135b94c898 | 25 | char *m_pch; |
fpucher | 2:63135b94c898 | 26 | |
fpucher | 2:63135b94c898 | 27 | // Technique 56 |
fpucher | 2:63135b94c898 | 28 | void InitString(const char *pch, int cch); |
fpucher | 2:63135b94c898 | 29 | void Append(const char *pch, int cch); |
fpucher | 2:63135b94c898 | 30 | void ReinitString(const char *pch, int cch); |
fpucher | 2:63135b94c898 | 31 | public: |
fpucher | 2:63135b94c898 | 32 | // Technique 69 |
fpucher | 2:63135b94c898 | 33 | // Technique 70 |
fpucher | 2:63135b94c898 | 34 | // Technique 91 |
fpucher | 2:63135b94c898 | 35 | String(void) : m_cch(0), m_cchTest(10) |
fpucher | 2:63135b94c898 | 36 | { |
fpucher | 2:63135b94c898 | 37 | m_pch =NULL; |
fpucher | 2:63135b94c898 | 38 | // Technique 71 |
fpucher | 2:63135b94c898 | 39 | // m_cchTest = 10; Not OK |
fpucher | 2:63135b94c898 | 40 | } |
fpucher | 2:63135b94c898 | 41 | |
fpucher | 2:63135b94c898 | 42 | // Technique 94 |
fpucher | 2:63135b94c898 | 43 | String(const String &string): m_cchTest(10) |
fpucher | 2:63135b94c898 | 44 | { |
fpucher | 2:63135b94c898 | 45 | InitString(string.m_pch, string.m_cch); |
fpucher | 2:63135b94c898 | 46 | } |
fpucher | 2:63135b94c898 | 47 | |
fpucher | 2:63135b94c898 | 48 | String(char *sz): m_cchTest(10) |
fpucher | 2:63135b94c898 | 49 | { |
fpucher | 2:63135b94c898 | 50 | InitString(sz, strlen(sz)); |
fpucher | 2:63135b94c898 | 51 | } |
fpucher | 2:63135b94c898 | 52 | |
fpucher | 2:63135b94c898 | 53 | ~String(void) |
fpucher | 2:63135b94c898 | 54 | { |
fpucher | 2:63135b94c898 | 55 | // Technique 50 |
fpucher | 2:63135b94c898 | 56 | if(m_pch) |
fpucher | 2:63135b94c898 | 57 | delete m_pch; |
fpucher | 2:63135b94c898 | 58 | } |
fpucher | 2:63135b94c898 | 59 | |
fpucher | 2:63135b94c898 | 60 | char & operator[](int i) |
fpucher | 2:63135b94c898 | 61 | { |
fpucher | 2:63135b94c898 | 62 | // if i < 0 or >= cch then it will cause access violation just like normal arrays. |
fpucher | 2:63135b94c898 | 63 | return m_pch[i]; |
fpucher | 2:63135b94c898 | 64 | } |
fpucher | 2:63135b94c898 | 65 | |
fpucher | 2:63135b94c898 | 66 | const char& operator[](int i) const |
fpucher | 2:63135b94c898 | 67 | { |
fpucher | 2:63135b94c898 | 68 | // if i < 0 or >= cch then it will cause access violation just like normal arrays. |
fpucher | 2:63135b94c898 | 69 | return m_pch[i]; |
fpucher | 2:63135b94c898 | 70 | } |
fpucher | 2:63135b94c898 | 71 | |
fpucher | 2:63135b94c898 | 72 | // Technique 77 |
fpucher | 2:63135b94c898 | 73 | const String& operator=(const String &string) |
fpucher | 2:63135b94c898 | 74 | { |
fpucher | 2:63135b94c898 | 75 | // Technique 78 |
fpucher | 2:63135b94c898 | 76 | if(&string != this) |
fpucher | 2:63135b94c898 | 77 | ReinitString(string.m_pch, string.m_cch); |
fpucher | 2:63135b94c898 | 78 | return *this; |
fpucher | 2:63135b94c898 | 79 | } |
fpucher | 2:63135b94c898 | 80 | |
fpucher | 2:63135b94c898 | 81 | const String& operator=(const char *sz) |
fpucher | 2:63135b94c898 | 82 | { |
fpucher | 2:63135b94c898 | 83 | ReinitString(sz, strlen(sz)); |
fpucher | 2:63135b94c898 | 84 | return *this; |
fpucher | 2:63135b94c898 | 85 | } |
fpucher | 2:63135b94c898 | 86 | |
fpucher | 2:63135b94c898 | 87 | const String& operator+=(const String& string) |
fpucher | 2:63135b94c898 | 88 | { |
fpucher | 2:63135b94c898 | 89 | Append(string.m_pch, string.m_cch); |
fpucher | 2:63135b94c898 | 90 | return *this; |
fpucher | 2:63135b94c898 | 91 | } |
fpucher | 2:63135b94c898 | 92 | |
fpucher | 2:63135b94c898 | 93 | const String& operator+=(const char *sz) |
fpucher | 2:63135b94c898 | 94 | { |
fpucher | 2:63135b94c898 | 95 | Append(sz, strlen(sz)); |
fpucher | 2:63135b94c898 | 96 | return *this; |
fpucher | 2:63135b94c898 | 97 | } |
fpucher | 2:63135b94c898 | 98 | |
fpucher | 2:63135b94c898 | 99 | int operator==(const String& string) const |
fpucher | 2:63135b94c898 | 100 | { |
fpucher | 2:63135b94c898 | 101 | return(strcmp(m_pch, string.m_pch) == 0); |
fpucher | 2:63135b94c898 | 102 | } |
fpucher | 2:63135b94c898 | 103 | |
fpucher | 2:63135b94c898 | 104 | int operator==(const char *sz) const |
fpucher | 2:63135b94c898 | 105 | { |
fpucher | 2:63135b94c898 | 106 | return(strcmp(m_pch, sz) == 0); |
fpucher | 2:63135b94c898 | 107 | } |
fpucher | 2:63135b94c898 | 108 | |
fpucher | 2:63135b94c898 | 109 | int operator>(const String& string) const |
fpucher | 2:63135b94c898 | 110 | { |
fpucher | 2:63135b94c898 | 111 | return(strcmp(m_pch, string.m_pch) > 0); |
fpucher | 2:63135b94c898 | 112 | } |
fpucher | 2:63135b94c898 | 113 | |
fpucher | 2:63135b94c898 | 114 | int operator>(const char *sz) const |
fpucher | 2:63135b94c898 | 115 | { |
fpucher | 2:63135b94c898 | 116 | return(strcmp(m_pch, sz) > 0); |
fpucher | 2:63135b94c898 | 117 | } |
fpucher | 2:63135b94c898 | 118 | |
fpucher | 2:63135b94c898 | 119 | int operator<(const String& string) const |
fpucher | 2:63135b94c898 | 120 | { |
fpucher | 2:63135b94c898 | 121 | return(strcmp(m_pch, string.m_pch) < 0); |
fpucher | 2:63135b94c898 | 122 | } |
fpucher | 2:63135b94c898 | 123 | |
fpucher | 2:63135b94c898 | 124 | int operator<(const char *sz) const |
fpucher | 2:63135b94c898 | 125 | { |
fpucher | 2:63135b94c898 | 126 | return(strcmp(m_pch, sz) < 0); |
fpucher | 2:63135b94c898 | 127 | } |
fpucher | 2:63135b94c898 | 128 | |
fpucher | 2:63135b94c898 | 129 | // Technique 53 |
fpucher | 2:63135b94c898 | 130 | #ifdef CODE_GPF |
fpucher | 2:63135b94c898 | 131 | String &operator+(const String&string) const |
fpucher | 2:63135b94c898 | 132 | { |
fpucher | 2:63135b94c898 | 133 | String stringNew(m_pch); |
fpucher | 2:63135b94c898 | 134 | |
fpucher | 2:63135b94c898 | 135 | stringNew.Append(string.m_pch, string.m_cch); |
fpucher | 2:63135b94c898 | 136 | return stringNew; |
fpucher | 2:63135b94c898 | 137 | } |
fpucher | 2:63135b94c898 | 138 | #endif |
fpucher | 2:63135b94c898 | 139 | |
fpucher | 2:63135b94c898 | 140 | String operator+(const String&string) const |
fpucher | 2:63135b94c898 | 141 | { |
fpucher | 2:63135b94c898 | 142 | String stringNew(m_pch); |
fpucher | 2:63135b94c898 | 143 | |
fpucher | 2:63135b94c898 | 144 | stringNew.Append(string.m_pch, string.m_cch); |
fpucher | 2:63135b94c898 | 145 | return stringNew; |
fpucher | 2:63135b94c898 | 146 | } |
fpucher | 2:63135b94c898 | 147 | }; |
fpucher | 2:63135b94c898 | 148 | |
fpucher | 2:63135b94c898 | 149 | // Technique 56 |
fpucher | 2:63135b94c898 | 150 | void String::InitString(const char * pch, int cch) |
fpucher | 2:63135b94c898 | 151 | { |
fpucher | 2:63135b94c898 | 152 | m_cch = 0; |
fpucher | 2:63135b94c898 | 153 | m_pch = NULL; |
fpucher | 2:63135b94c898 | 154 | if(cch) |
fpucher | 2:63135b94c898 | 155 | { |
fpucher | 2:63135b94c898 | 156 | m_pch = new char[cch+1]; |
fpucher | 2:63135b94c898 | 157 | if(m_pch) |
fpucher | 2:63135b94c898 | 158 | { |
fpucher | 2:63135b94c898 | 159 | strcpy(m_pch, pch); |
fpucher | 2:63135b94c898 | 160 | m_cch = cch; |
fpucher | 2:63135b94c898 | 161 | } |
fpucher | 2:63135b94c898 | 162 | } |
fpucher | 2:63135b94c898 | 163 | } |
fpucher | 2:63135b94c898 | 164 | |
fpucher | 2:63135b94c898 | 165 | void String::Append(const char *pch, int cch) |
fpucher | 2:63135b94c898 | 166 | { |
fpucher | 2:63135b94c898 | 167 | char *pchNew; |
fpucher | 2:63135b94c898 | 168 | int cchNew; |
fpucher | 2:63135b94c898 | 169 | |
fpucher | 2:63135b94c898 | 170 | |
fpucher | 2:63135b94c898 | 171 | // Technique 18 |
fpucher | 2:63135b94c898 | 172 | // Technique 79 |
fpucher | 2:63135b94c898 | 173 | if(!cch) |
fpucher | 2:63135b94c898 | 174 | return; |
fpucher | 2:63135b94c898 | 175 | if(!m_pch) |
fpucher | 2:63135b94c898 | 176 | { |
fpucher | 2:63135b94c898 | 177 | // If this is empty string, then just initialize it with this string. |
fpucher | 2:63135b94c898 | 178 | InitString(pch, cch); |
fpucher | 2:63135b94c898 | 179 | return; |
fpucher | 2:63135b94c898 | 180 | } |
fpucher | 2:63135b94c898 | 181 | // Allocate an extra character for the null terminator at the end |
fpucher | 2:63135b94c898 | 182 | cchNew = m_cch + cch; |
fpucher | 2:63135b94c898 | 183 | pchNew = new char[cchNew + 1]; |
fpucher | 2:63135b94c898 | 184 | |
fpucher | 2:63135b94c898 | 185 | // Technique 49 |
fpucher | 2:63135b94c898 | 186 | if(!pchNew) |
fpucher | 2:63135b94c898 | 187 | return; |
fpucher | 2:63135b94c898 | 188 | // Successfully allocated new buffer |
fpucher | 2:63135b94c898 | 189 | strcpy(pchNew, m_pch); |
fpucher | 2:63135b94c898 | 190 | |
fpucher | 2:63135b94c898 | 191 | // Technique 128 |
fpucher | 2:63135b94c898 | 192 | strcpy(pchNew+m_cch, pch); |
fpucher | 2:63135b94c898 | 193 | if(m_pch) |
fpucher | 2:63135b94c898 | 194 | delete m_pch; |
fpucher | 2:63135b94c898 | 195 | m_pch = pchNew; |
fpucher | 2:63135b94c898 | 196 | m_cch = cchNew; |
fpucher | 2:63135b94c898 | 197 | } |
fpucher | 2:63135b94c898 | 198 | |
fpucher | 2:63135b94c898 | 199 | void String::ReinitString(const char *pch, int cch) |
fpucher | 2:63135b94c898 | 200 | { |
fpucher | 2:63135b94c898 | 201 | char *pchOld; |
fpucher | 2:63135b94c898 | 202 | int cchOld; |
fpucher | 2:63135b94c898 | 203 | |
fpucher | 2:63135b94c898 | 204 | |
fpucher | 2:63135b94c898 | 205 | if(cch != m_cch) |
fpucher | 2:63135b94c898 | 206 | { |
fpucher | 2:63135b94c898 | 207 | pchOld = m_pch; |
fpucher | 2:63135b94c898 | 208 | cchOld = m_cch; |
fpucher | 2:63135b94c898 | 209 | InitString(pch, cch); |
fpucher | 2:63135b94c898 | 210 | if(m_pch) |
fpucher | 2:63135b94c898 | 211 | { |
fpucher | 2:63135b94c898 | 212 | // Successfully Inited the string? Now we can delete the memory for the old pch if there was one. |
fpucher | 2:63135b94c898 | 213 | if(pchOld) |
fpucher | 2:63135b94c898 | 214 | delete pchOld; |
fpucher | 2:63135b94c898 | 215 | } |
fpucher | 2:63135b94c898 | 216 | else |
fpucher | 2:63135b94c898 | 217 | { |
fpucher | 2:63135b94c898 | 218 | // Failed to allocate space for the string? Restore the old values. |
fpucher | 2:63135b94c898 | 219 | m_pch = pchOld; |
fpucher | 2:63135b94c898 | 220 | m_cch = cchOld; |
fpucher | 2:63135b94c898 | 221 | } |
fpucher | 2:63135b94c898 | 222 | } |
fpucher | 2:63135b94c898 | 223 | else |
fpucher | 2:63135b94c898 | 224 | { |
fpucher | 2:63135b94c898 | 225 | // If the length of the sting is the same, then no need to reallocate the buffer. |
fpucher | 2:63135b94c898 | 226 | strcpy(m_pch, pch); |
fpucher | 2:63135b94c898 | 227 | } |
fpucher | 2:63135b94c898 | 228 | } |
fpucher | 2:63135b94c898 | 229 | void PrintConstString(const String &string) |
fpucher | 2:63135b94c898 | 230 | { |
fpucher | 2:63135b94c898 | 231 | int i = 0; |
fpucher | 2:63135b94c898 | 232 | while(string[i]) |
fpucher | 2:63135b94c898 | 233 | { |
fpucher | 2:63135b94c898 | 234 | //cout << string[i]; |
fpucher | 2:63135b94c898 | 235 | // Technique 80 |
fpucher | 2:63135b94c898 | 236 | // NOCOMPILE the following won't compile if you remove the comments. |
fpucher | 2:63135b94c898 | 237 | // string[i] = ' '; |
fpucher | 2:63135b94c898 | 238 | i++; |
fpucher | 2:63135b94c898 | 239 | } |
fpucher | 2:63135b94c898 | 240 | //cout << '\n'; |
fpucher | 2:63135b94c898 | 241 | } |
fpucher | 2:63135b94c898 | 242 | |
fpucher | 2:63135b94c898 | 243 | void PrintString(String &string) |
fpucher | 2:63135b94c898 | 244 | { |
fpucher | 2:63135b94c898 | 245 | int i = 0; |
fpucher | 2:63135b94c898 | 246 | while(string[i]) |
fpucher | 2:63135b94c898 | 247 | { |
fpucher | 2:63135b94c898 | 248 | //cout << string[i]; |
fpucher | 2:63135b94c898 | 249 | // Unlike above this compiles. |
fpucher | 2:63135b94c898 | 250 | string[i] = ' '; |
fpucher | 2:63135b94c898 | 251 | i++; |
fpucher | 2:63135b94c898 | 252 | } |
fpucher | 2:63135b94c898 | 253 | } |
fpucher | 2:63135b94c898 | 254 | |
fpucher | 2:63135b94c898 | 255 | void TestStringClass(void) |
fpucher | 2:63135b94c898 | 256 | { |
fpucher | 2:63135b94c898 | 257 | String string("Test"); |
fpucher | 2:63135b94c898 | 258 | String string1(string); |
fpucher | 2:63135b94c898 | 259 | String string2; |
fpucher | 2:63135b94c898 | 260 | |
fpucher | 2:63135b94c898 | 261 | |
fpucher | 2:63135b94c898 | 262 | string1 = "Test1"; |
fpucher | 2:63135b94c898 | 263 | string1 += string; |
fpucher | 2:63135b94c898 | 264 | string ="zing"; |
fpucher | 2:63135b94c898 | 265 | // Technique 105 |
fpucher | 2:63135b94c898 | 266 | PrintConstString(string); |
fpucher | 2:63135b94c898 | 267 | |
fpucher | 2:63135b94c898 | 268 | if(string1 == string) |
fpucher | 2:63135b94c898 | 269 | string1 = "equal"; |
fpucher | 2:63135b94c898 | 270 | else if(string1 < string) |
fpucher | 2:63135b94c898 | 271 | string1 = "less"; |
fpucher | 2:63135b94c898 | 272 | else |
fpucher | 2:63135b94c898 | 273 | string1 = "greater"; |
fpucher | 2:63135b94c898 | 274 | PrintConstString(string); |
fpucher | 2:63135b94c898 | 275 | PrintConstString(string1); |
fpucher | 2:63135b94c898 | 276 | string2 = string + string1; |
fpucher | 2:63135b94c898 | 277 | PrintConstString(string2); |
fpucher | 2:63135b94c898 | 278 | } |
fpucher | 2:63135b94c898 | 279 |