//: C07:MemTest.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Testing the Mem class
//{L} Mem
#include "Mem.h"
#include <cstring>
#include <iostream>
using namespace std;

class MyString
{

Mem* buf;

public:

/* Questa classe prevede due costruttori : MyString() e MyString(char *) */

MyString();
MyString(char* str);
~MyString();
void concat(char* str);
void print(ostream& os);

};

MyString::MyString() { buf = 0; }

/* Questo costruttore associa a buf il puntatore alla classe Mem il cui costruttore viene invocato all'esecuzione della "new"; successivamente viene sovrascritta la vecchia parola se la nuova è più corta, altrimenti viene scritta in un nuovo spazio*/

MyString::MyString(char* str)
{

buf = new Mem(strlen(str) + 1);
strcpy((char*)buf->pointer(), str);

}

/* Il metodo concat realizza la concatenazione tra la vecchia parola memorizzata (se c'è) e quella nuova; viene utilizzata la funzione di libreria strcat dove in argomento ha i puntaori alle due stringhe */

void MyString::concat(char* str)
{

if(!buf) buf = new Mem;

strcat((char*)buf->pointer(buf->msize() + strlen(str) + 1), str);

}

/* Il metodo print preso in ingresso l'indirizzo del canale cout stampa su di esso (equivale a fare una cout) la stringa memorizzata. Infatti buf->pointer() restituisce un puntatore ad unsigned char */

void MyString::print(ostream& os)
{

if(!buf) return;

os << buf->pointer() << endl;

}

MyString::~MyString() { delete buf; }

int main()
{

MyString s("My test string");

/* Il metodo print ha in argomento l'indirizzo del canale cout che è un ostream& */

s.print(cout);
s.concat(" some additional stuff");
s.print(cout);
MyString s2;
s2.concat("Using default constructor");
s2.print(cout);

} ///:~