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
- Committer:
- fpucher
- Date:
- 2018-01-16
- Revision:
- 3:c14eb9159a88
- Parent:
- 2:63135b94c898
File content as of revision 3:c14eb9159a88:
#include <stdio.h> //#include <mem.h> #include <string.h> //#include <iostream.h> /* 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 double byte strings as you would encounter in the far east languages or arabic alphabet which is bidirectional. I also do not provide extensive error checking for parameters. If you pass null for the sz in the constructor below the code GPFs. Doing any operator like = or > on an empty string will result in predictable but disastrous results like GPF. I could instead make it 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 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 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 or have it throw exceptions. You can also assert. But it's always better to deal with the exception than to simply assert. */ class String { private: // Added const member only to demonstrate initialization of const members. const int m_cchTest; // length of the string int m_cch; // null terminated string. Makes it easy to give out null terminated strings. char *m_pch; // Technique 56 void InitString(const char *pch, int cch); void Append(const char *pch, int cch); void ReinitString(const char *pch, int cch); public: // Technique 69 // Technique 70 // Technique 91 String(void) : m_cch(0), m_cchTest(10) { m_pch =NULL; // Technique 71 // m_cchTest = 10; Not OK } // Technique 94 String(const String &string): m_cchTest(10) { InitString(string.m_pch, string.m_cch); } String(char *sz): m_cchTest(10) { InitString(sz, strlen(sz)); } ~String(void) { // Technique 50 if(m_pch) delete m_pch; } char & operator[](int i) { // if i < 0 or >= cch then it will cause access violation just like normal arrays. return m_pch[i]; } const char& operator[](int i) const { // if i < 0 or >= cch then it will cause access violation just like normal arrays. return m_pch[i]; } // Technique 77 const String& operator=(const String &string) { // Technique 78 if(&string != this) ReinitString(string.m_pch, string.m_cch); return *this; } const String& operator=(const char *sz) { ReinitString(sz, strlen(sz)); return *this; } const String& operator+=(const String& string) { Append(string.m_pch, string.m_cch); return *this; } const String& operator+=(const char *sz) { Append(sz, strlen(sz)); return *this; } int operator==(const String& string) const { return(strcmp(m_pch, string.m_pch) == 0); } int operator==(const char *sz) const { return(strcmp(m_pch, sz) == 0); } int operator>(const String& string) const { return(strcmp(m_pch, string.m_pch) > 0); } int operator>(const char *sz) const { return(strcmp(m_pch, sz) > 0); } int operator<(const String& string) const { return(strcmp(m_pch, string.m_pch) < 0); } int operator<(const char *sz) const { return(strcmp(m_pch, sz) < 0); } // Technique 53 #ifdef CODE_GPF String &operator+(const String&string) const { String stringNew(m_pch); stringNew.Append(string.m_pch, string.m_cch); return stringNew; } #endif String operator+(const String&string) const { String stringNew(m_pch); stringNew.Append(string.m_pch, string.m_cch); return stringNew; } }; // Technique 56 void String::InitString(const char * pch, int cch) { m_cch = 0; m_pch = NULL; if(cch) { m_pch = new char[cch+1]; if(m_pch) { strcpy(m_pch, pch); m_cch = cch; } } } void String::Append(const char *pch, int cch) { char *pchNew; int cchNew; // Technique 18 // Technique 79 if(!cch) return; if(!m_pch) { // If this is empty string, then just initialize it with this string. InitString(pch, cch); return; } // Allocate an extra character for the null terminator at the end cchNew = m_cch + cch; pchNew = new char[cchNew + 1]; // Technique 49 if(!pchNew) return; // Successfully allocated new buffer strcpy(pchNew, m_pch); // Technique 128 strcpy(pchNew+m_cch, pch); if(m_pch) delete m_pch; m_pch = pchNew; m_cch = cchNew; } void String::ReinitString(const char *pch, int cch) { char *pchOld; int cchOld; if(cch != m_cch) { pchOld = m_pch; cchOld = m_cch; InitString(pch, cch); if(m_pch) { // Successfully Inited the string? Now we can delete the memory for the old pch if there was one. if(pchOld) delete pchOld; } else { // Failed to allocate space for the string? Restore the old values. m_pch = pchOld; m_cch = cchOld; } } else { // If the length of the sting is the same, then no need to reallocate the buffer. strcpy(m_pch, pch); } } void PrintConstString(const String &string) { int i = 0; while(string[i]) { //cout << string[i]; // Technique 80 // NOCOMPILE the following won't compile if you remove the comments. // string[i] = ' '; i++; } //cout << '\n'; } void PrintString(String &string) { int i = 0; while(string[i]) { //cout << string[i]; // Unlike above this compiles. string[i] = ' '; i++; } } void TestStringClass(void) { String string("Test"); String string1(string); String string2; string1 = "Test1"; string1 += string; string ="zing"; // Technique 105 PrintConstString(string); if(string1 == string) string1 = "equal"; else if(string1 < string) string1 = "less"; else string1 = "greater"; PrintConstString(string); PrintConstString(string1); string2 = string + string1; PrintConstString(string2); }