/** * @module cscriptparser * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) * @brief class for parsing simple scriptfiles * @date 17.04.2009 */ #include #include #include #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::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 funcparams; tokenizer< char_separator > tokens(params, char_separator(",")); /* BOOST_FOREACH isn't available on OOP-servers... */ for (tokenizer< char_separator >::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& 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 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::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 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: */