Download | Plain Text | Line Numbers
/**
* @module cscriptparser
* @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
* @brief class for parsing simple scriptfiles
* @date 17.04.2009
*/
#include <fstream>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
#include "cscriptparser.h"
#include "cwindowsbitmap.h"
#include "cpixmap.h"
using namespace std;
using namespace boost;
CScriptparser::CScriptparser(const std::string& scriptfile)
: m_scriptfile(scriptfile), m_handler(NULL)
{
/* add our handlers */
m_handlers.insert(new CWindowsBitmap);
m_handlers.insert(new CPixmap);
}
/*----------------------------------------------------------------------------*/
CScriptparser::~CScriptparser()
{
/* delete image handlers */
set<CFile *>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); it++)
delete *it;
m_handler = NULL;
}
/*----------------------------------------------------------------------------*/
void CScriptparser::parse()
{
/* open and read file */
ifstream file(m_scriptfile.c_str(), ios::in);
if (!file)
throw ParserError("Unable to open scriptfile '" + m_scriptfile + "'.");
while (!file.eof() && file.good())
{
/* read file pre line */
getline(file, m_curline);
if (m_curline.empty())
continue;
trim(m_curline);
/* ignore comments */
if (m_curline.find_first_of('#') == 0)
continue;
/* line has no function call */
size_t pos1 = m_curline.find_first_of('(');
size_t pos2 = m_curline.find_last_of(')');
if (pos1 == string::npos || pos2 == string::npos)
throw ParserError("Invalid syntax. Not a function", m_curline);
/* first parse function name and tokenize all parameters */
string func = m_curline.substr(0, pos1);
string params = m_curline.substr(pos1 + 1, pos2 - pos1 - 1);
list<string> funcparams;
tokenizer< char_separator<char> > tokens(params, char_separator<char>(","));
/* BOOST_FOREACH isn't available on OOP-servers... */
for (tokenizer< char_separator<char> >::iterator it = tokens.begin();
it != tokens.end();
it++)
{
string tok(*it);
trim(tok);
if (tok.find_first_of(' ') != string::npos)
{
if (tok.find_first_of('"') == string::npos)
throw ParserError("Invalid syntax", m_curline);
}
trim_if(tok, is_any_of("\""));
funcparams.push_back(tok);
}
/* then call the corresponding function */
callFunc(func, funcparams);
}
file.close();
}
/*----------------------------------------------------------------------------*/
void CScriptparser::callFunc(const std::string& func, const std::list<std::string>& funcparams)
{
if (func.empty())
throw ParserError("Function name is empty.", m_curline);
if (func == "read")
read(funcparams);
else if (func == "write")
write(funcparams);
else
{
if (m_handler == NULL)
throw ParserError("No image is being processed.", m_curline);
/* call function from handler */
try
{
m_handler->callFunc(func, funcparams);
}
catch(CFile::FileError& ex)
{
throw ParserError(ex.what(), m_curline);
}
}
}
/*----------------------------------------------------------------------------*/
void CScriptparser::read(std::list<std::string> funcparams)
{
/* check prerequirements */
if (funcparams.size() != 2)
throw ParserError("Invalid number of function parameters (must be 2).", m_curline);
if (m_handler != NULL)
throw ParserError("An image is already being processed. Unable to open another.", m_curline);
string type = funcparams.front();
to_upper(type);
funcparams.pop_front();
string filename = funcparams.front();
/* fetch image handler supporting requested filetype */
m_handler = NULL;
set<CFile *>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); it++)
{
if ((*it)->supportsType(type))
{
m_handler = *it;
break;
}
}
if (m_handler == NULL)
throw ParserError("Unknown filetype.", m_curline);
/* open file in binary mode */
ifstream file(filename.c_str(), ios::in | ios::binary);
if (!file)
throw ParserError("Unable to read file.", m_curline);
/* let handlers read() parse the file */
try
{
m_handler->read(file);
if (!file.good())
throw ParserError("Error while reading image file.", m_curline);
file.close();
}
catch(CFile::FileError& ex)
{
file.close();
throw ParserError(ex.what(), m_curline);
}
}
/*----------------------------------------------------------------------------*/
void CScriptparser::write(std::list<std::string> funcparams)
{
/* check prerequirements */
if (funcparams.size() != 2)
throw ParserError("Invalid number of function parameters (must be 2).", m_curline);
if (m_handler == NULL)
throw ParserError("No image is being processed.", m_curline);
string type = funcparams.front();
to_upper(type);
funcparams.pop_front();
string filename = funcparams.front();
/* do we have an image handler supporting the filetype? */
if (!m_handler->supportsType(type))
throw ParserError("Unknown filetype.", m_curline);
/* open file in binary mode */
ofstream file(filename.c_str(), ios::out | ios::binary);
if (!file)
throw ParserError("Unable to open file.", m_curline);
/* let handlers write() parse the file */
try
{
m_handler->write(file);
if (!file.good())
throw ParserError("Error while writing image file.", m_curline);
file.close();
m_handler = NULL;
}
catch(CFile::FileError& ex)
{
file.close();
m_handler = NULL;
throw ParserError(ex.what(), m_curline);
}
}
/* vim: set et sw=2 ts=2: */