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

Dependencies:   LM75B mbed

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);
}