module;
#include <cstring>

export module CString;

// Klassendefinition
export class CString
{
    char *pString;          // String
public:
    // ctor
    CString();
    // dtor
    ~CString();
    // String setzen
    void SetString(const char *const pS);
    void SetString(const CString& source);
    // Strings addieren
    void AddString(const char *const pS);
    void AddString(const CString& add);
    // String zurueckgeben
    const char* GetString() const
    {
        return pString;
    }
};

// Definition der Memberfunktionen
// Konstruktor
CString::CString()
{

    // char-Feld mit einem Element anlegen
    pString = new char[1];
    // String als leeren String kennzeichnen
    pString[0] = 0;
}
// Destruktor
CString::~CString()
{
    // Speicher für char-Feld freigeben!
    delete [] pString;
}
// Legt den über den char-Zeiger übergebenen String ab
void CString::SetString(const char *const pS)
{
    // Zuerst alten Speicherplatz freigeben!
    delete [] pString;
    // Nun neuen Speicherplatz für String anfordern
    // Die abschliessende binäre 0 dabei nicht vergessen!
    auto len = strlen(pS) + 1;
    pString = new char[len];
    // String umkopieren
    strcpy_s(pString, len, pS);
}
// Legt den über die String-Referenz übergebenen String ab
void CString::SetString(const CString& source)
{
    // Gleicher Ablauf wie bei der vorherigen Memberfunktion
    delete [] pString;
    auto len = strlen(source.pString) + 1;
    pString = new char[len];
    strcpy_s(pString, len, source.pString);
}
// Fügt den über den char-Zeiger übergebenen String hinzu
void CString::AddString(const char *const pS)
{
    // Zuerst Speicher für neuen String reservieren
    auto bufSize = strlen(pString) + strlen(pS) + 1;
    auto pTemp = new char[bufSize];
    // Dann den ursprünglichen String umkopieren
    strcpy_s(pTemp, bufSize, pString);
    // und nun den neuen String hinzufügen
    strcat_s(pTemp, bufSize, pS);
    // Jetzt erst den ursprünglichen Speicher freigeben
    delete [] pString;
    // und Zeiger auf neuen Speicherbereich setzen
    pString = pTemp;
}
// Fügt den über die String-Referenz übergebenen String hinzu
void CString::AddString(const CString& add)
{
    // Gleicher Ablauf wie vorherige Memberfunktion
    auto bufSize = strlen(pString) + strlen(add.pString) + 1;
    auto pTemp = new char[bufSize];
    strcpy_s(pTemp, bufSize, pString);
    strcat_s(pTemp, bufSize, add.pString);
    // Jetzt erst den ursprünglichen Speicher freigeben
    delete [] pString;
    // und Zeiger auf neuen Speicherbereich setzen
    pString = pTemp;
}
