// implementation file: FileCoder.cpp
// description:         Template methods for coding using a source and a target file.
// variant:             2 with flexible composition
// author:              Karlheinz Hug
// creation date:       2012-07-05
// last update:         2012-08-06

#include <cassert>
#include <typeinfo>

#include "FileCoder.hpp"
#include "FileIO.hpp"

	FileCoder::FileCoder (Coder * const new_coder) :
		coder (new_coder)
	{
		assert(new_coder); // precondition
		assert(coder);     // implementation invariant
	};

	FileCoder::~FileCoder ()
	{
		delete coder;
	}

	std::string FileCoder::coder_name () const
	{
		return coder->name();
	}

	void FileCoder::encode (const std::string & source_filename, const std::string & target_filename)
	{
		code(source_filename, target_filename, &Coder::encode);
	};

	void FileCoder::decode (const std::string & source_filename, const std::string & target_filename)
	{
		code(source_filename, target_filename, &Coder::decode);
	};

	void FileCoder::code
		(const std::string & source_filename, const std::string & target_filename,
		 void (Coder::*method)(const std::vector<char> &, std::vector<char> &))
	{
		assert(source_filename.size() > 0);                    // precondition
		assert(target_filename.size() > 0);                    // precondition
		assert(source_filename.compare(target_filename) != 0); // precondition
		assert(method);                                        // precondition
		assert(coder);                                       // invariant

		std::vector<char> source_buffer;
		FileIO::read_from_file_to_buffer(source_filename, source_buffer);
		a_result = FileIO::result();
		if (a_result != done) return;

		std::vector<char> target_buffer;
		(coder->*method)(source_buffer, target_buffer);
		a_result = coder->result();
		if (a_result != done) return;

		FileIO::write_from_buffer_to_file(target_buffer, target_filename);
		a_result = FileIO::result();
	};

