M0 communication to configurable-Web-Server (MQTT) Version 0.1

Dependencies:   LM75B mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers String.cpp Source File

String.cpp

00001 #include <stdio.h>
00002 //#include <mem.h>
00003 #include <string.h>
00004 //#include <iostream.h>
00005 
00006 /*
00007 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
00008 double byte strings as you would encounter in the far east languages or arabic alphabet which is bidirectional.
00009 I also do not provide extensive error checking for parameters. If you pass null for the sz in the constructor below the code GPFs.
00010 Doing any operator like = or > on an empty string will result in predictable but disastrous results like GPF. I could instead make it
00011 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
00012 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
00013 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
00014 or have it throw exceptions. You can also assert. But it's always better to deal with the exception than to simply assert.
00015 */
00016 
00017 class String
00018 {
00019 private:
00020     // Added const member only to demonstrate initialization of const members.
00021     const int m_cchTest;
00022     // length of the string
00023     int m_cch;
00024     // null terminated string. Makes it easy to give out null terminated strings.
00025     char *m_pch;
00026 
00027     // Technique 56
00028     void InitString(const char *pch, int cch);
00029     void Append(const char *pch, int cch);
00030     void ReinitString(const char *pch, int cch);
00031 public:
00032     // Technique 69
00033     // Technique 70
00034     // Technique 91
00035     String(void) : m_cch(0), m_cchTest(10)
00036     {
00037         m_pch =NULL;
00038         // Technique 71
00039         // m_cchTest = 10; Not OK
00040     }
00041     
00042     // Technique 94
00043     String(const String &string): m_cchTest(10)
00044     {
00045         InitString(string.m_pch, string.m_cch);
00046     }
00047 
00048     String(char *sz): m_cchTest(10)
00049     {
00050         InitString(sz, strlen(sz));
00051     }
00052 
00053     ~String(void)
00054     {
00055         // Technique 50
00056         if(m_pch)
00057             delete m_pch;
00058     }
00059 
00060     char & operator[](int i)
00061     {
00062         // if i < 0 or >= cch then it will cause access violation just like normal arrays.
00063         return m_pch[i];
00064     }
00065 
00066     const char& operator[](int i) const
00067     {
00068         // if i < 0 or >= cch then it will cause access violation just like normal arrays.
00069         return m_pch[i];
00070     }
00071 
00072     // Technique 77
00073     const String& operator=(const String &string)
00074     {
00075         // Technique 78
00076         if(&string != this)
00077             ReinitString(string.m_pch, string.m_cch);
00078         return *this;
00079     }
00080 
00081     const String& operator=(const char *sz)
00082     {
00083         ReinitString(sz, strlen(sz));
00084         return *this;
00085     }
00086 
00087     const String& operator+=(const String& string)
00088     {
00089         Append(string.m_pch, string.m_cch);
00090         return *this;
00091     }
00092 
00093     const String& operator+=(const char *sz)
00094     {
00095         Append(sz, strlen(sz));
00096         return *this;
00097     }
00098 
00099     int operator==(const String& string) const
00100     {
00101         return(strcmp(m_pch, string.m_pch) == 0);
00102     }
00103 
00104     int operator==(const char *sz) const
00105     {
00106         return(strcmp(m_pch, sz) == 0);
00107     }
00108 
00109     int operator>(const String& string) const
00110     {
00111         return(strcmp(m_pch, string.m_pch) > 0);
00112     }
00113 
00114     int operator>(const char *sz) const
00115     {
00116         return(strcmp(m_pch, sz) > 0);
00117     }
00118 
00119     int operator<(const String& string) const
00120     {
00121         return(strcmp(m_pch, string.m_pch) < 0);
00122     }
00123 
00124     int operator<(const char *sz) const
00125     {
00126         return(strcmp(m_pch, sz) < 0);
00127     }
00128     
00129     // Technique 53
00130 #ifdef CODE_GPF
00131     String &operator+(const String&string) const
00132     {
00133         String stringNew(m_pch);
00134 
00135         stringNew.Append(string.m_pch, string.m_cch);
00136         return stringNew;
00137     }
00138 #endif
00139 
00140     String operator+(const String&string) const
00141     {
00142         String stringNew(m_pch);
00143 
00144         stringNew.Append(string.m_pch, string.m_cch);
00145         return stringNew;
00146     }
00147 };
00148 
00149 // Technique 56
00150 void String::InitString(const char * pch, int cch)
00151 {
00152     m_cch = 0;
00153     m_pch = NULL;
00154     if(cch)
00155     {
00156         m_pch = new char[cch+1];
00157         if(m_pch)
00158         {
00159             strcpy(m_pch, pch);
00160             m_cch = cch;
00161         }
00162     }
00163 }
00164 
00165 void String::Append(const char *pch, int cch)
00166 {
00167     char *pchNew;
00168     int cchNew;
00169 
00170 
00171     // Technique 18
00172     // Technique 79
00173     if(!cch)
00174         return;
00175     if(!m_pch)
00176     {
00177         // If this is empty string, then just initialize it with this string.
00178         InitString(pch, cch);
00179         return;
00180     }
00181     // Allocate an extra character for the null terminator at the end
00182     cchNew = m_cch + cch;
00183     pchNew = new char[cchNew + 1];
00184 
00185     // Technique 49
00186     if(!pchNew)
00187         return;
00188     // Successfully allocated new buffer
00189     strcpy(pchNew, m_pch);
00190     
00191     // Technique 128
00192     strcpy(pchNew+m_cch, pch);
00193     if(m_pch)
00194         delete m_pch;
00195     m_pch = pchNew;
00196     m_cch = cchNew;
00197 }
00198 
00199 void String::ReinitString(const char *pch, int cch)
00200 {
00201     char *pchOld;
00202     int cchOld;
00203 
00204 
00205     if(cch != m_cch)
00206     {
00207         pchOld = m_pch;
00208         cchOld = m_cch;
00209         InitString(pch, cch);
00210         if(m_pch)
00211         {
00212             // Successfully Inited the string? Now we can delete the memory for the old pch if there was one.
00213             if(pchOld)
00214                 delete pchOld;
00215         }
00216         else
00217         {
00218             // Failed to allocate space for the string? Restore the old values.
00219             m_pch = pchOld;
00220             m_cch = cchOld;
00221         }
00222     }
00223     else
00224     {
00225         // If the length of the sting is the same, then no need to reallocate the buffer.
00226         strcpy(m_pch, pch);
00227     }
00228 }
00229 void PrintConstString(const String &string)
00230 {
00231     int i = 0;
00232     while(string[i])
00233     {
00234         //cout << string[i];
00235         // Technique 80
00236         // NOCOMPILE the following won't compile if you remove the comments.
00237         // string[i] = ' ';
00238         i++;
00239     }
00240     //cout << '\n';
00241 }
00242 
00243 void PrintString(String &string)
00244 {
00245     int i = 0;
00246     while(string[i])
00247     {
00248         //cout << string[i];
00249         // Unlike above this compiles.
00250         string[i] = ' ';
00251         i++;
00252     }
00253 }
00254 
00255 void TestStringClass(void)
00256 {
00257     String string("Test");
00258     String string1(string);
00259     String string2;
00260 
00261 
00262     string1 = "Test1";
00263     string1 += string;
00264     string ="zing";
00265     // Technique 105
00266     PrintConstString(string);
00267 
00268     if(string1 == string)
00269         string1 = "equal";
00270     else if(string1 < string)
00271         string1 = "less";
00272     else
00273         string1 = "greater";
00274     PrintConstString(string);
00275     PrintConstString(string1);
00276     string2 = string + string1;
00277     PrintConstString(string2);
00278 }
00279