// Serialization.cpp : Defines the entry point for the console application.
// with the help of Tomas Bujnak

#include "stdafx.h"
#include <iostream>
#include <fstream>

using namespace std;

class ISerializable		// I stands for Interface
{
public:
	virtual void WriteToStream(ostream *pStream) = 0;
	virtual void ReadFromStream(istream *pStream) = 0;
};


class MyClass : public ISerializable
{
public:
	int value1;
	int value2;

	void WriteToStream(ostream *pStream)
	{
		pStream->write((char*)&value1, sizeof(value1));
		pStream->write((char*)&value2, sizeof(value2));
	}
	
	void ReadFromStream(istream *pStream)
	{
		pStream->read((char*)&value1, sizeof(value1));
		pStream->read((char*)&value2, sizeof(value2));
	}
};

class MyClass2 : public ISerializable
{
	MyClass *pArray;
	int arraySize;
public:
	MyClass2()
	{
		pArray = NULL;
		arraySize = 0;
	}
	~MyClass2()
	{
		delete [] pArray;
	}
	void WriteToStream(ostream *pStream)
	{
		pStream->write((char*)&arraySize, sizeof(arraySize));
		for (int i = 0; i < arraySize; i++)
		{
			pArray[i].WriteToStream(pStream);
		}
	}

	void ReadFromStream(istream *pStream)
	{
		pStream->read((char*)&arraySize, sizeof(arraySize));
		pArray = new MyClass[arraySize];
		for (int i = 0; i < arraySize; i++)
		{
			pArray[i].ReadFromStream(pStream);
		}
	}

	void DoSomeWork()
	{
		arraySize = 5;
		pArray = new MyClass[arraySize];
		for (int i = 0; i < arraySize;i++)
		{
			pArray[i].value1 = i;
			pArray[i].value2 = i*i;
		}
	}

	void PrintOut()
	{
		for (int i = 0; i < arraySize; i++)
		{
			cout << i << ": " << pArray[i].value1 << " | " << pArray[i].value2 << endl;
		}
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	MyClass2 mc;
	MyClass2 nc;
	mc.DoSomeWork();

	ofstream outfile("example.bin");
	mc.WriteToStream(& outfile);
	outfile.close();

	ifstream infile("example.bin");
	nc.ReadFromStream(& infile);
	infile.close();

	nc.PrintOut();
	
	system("pause");
	return 0;
}