Download | Plain Text | No Line Numbers


  1. /**
  2.  * @module cscriptparser
  3.  * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
  4.  * @brief class for parsing simple scriptfiles
  5.  * @date 17.04.2009
  6.  */
  7.  
  8. #include <fstream>
  9. #include <boost/tokenizer.hpp>
  10. #include <boost/algorithm/string.hpp>
  11. #include "cscriptparser.h"
  12. #include "cwindowsbitmap.h"
  13. #include "cpixmap.h"
  14.  
  15. using namespace std;
  16. using namespace boost;
  17.  
  18. CScriptparser::CScriptparser(const std::string& scriptfile)
  19. : m_scriptfile(scriptfile), m_handler(NULL)
  20. {
  21. /* add our handlers */
  22. m_handlers.insert(new CWindowsBitmap);
  23. m_handlers.insert(new CPixmap);
  24. }
  25.  
  26. /*----------------------------------------------------------------------------*/
  27.  
  28. CScriptparser::~CScriptparser()
  29. {
  30. /* delete image handlers */
  31. set<CFile *>::iterator it;
  32. for (it = m_handlers.begin(); it != m_handlers.end(); it++)
  33. delete *it;
  34. m_handler = NULL;
  35. }
  36.  
  37. /*----------------------------------------------------------------------------*/
  38.  
  39. void CScriptparser::parse()
  40. {
  41. /* open and read file */
  42. ifstream file(m_scriptfile.c_str(), ios::in);
  43. if (!file)
  44. throw ParserError("Unable to open scriptfile '" + m_scriptfile + "'.");
  45.  
  46. while (!file.eof() && file.good())
  47. {
  48. /* read file pre line */
  49. getline(file, m_curline);
  50. if (m_curline.empty())
  51. continue;
  52.  
  53. trim(m_curline);
  54.  
  55. /* ignore comments */
  56. if (m_curline.find_first_of('#') == 0)
  57. continue;
  58.  
  59. /* line has no function call */
  60. size_t pos1 = m_curline.find_first_of('(');
  61. size_t pos2 = m_curline.find_last_of(')');
  62. if (pos1 == string::npos || pos2 == string::npos)
  63. throw ParserError("Invalid syntax. Not a function", m_curline);
  64.  
  65. /* first parse function name and tokenize all parameters */
  66. string func = m_curline.substr(0, pos1);
  67. string params = m_curline.substr(pos1 + 1, pos2 - pos1 - 1);
  68. list<string> funcparams;
  69. tokenizer< char_separator<char> > tokens(params, char_separator<char>(","));
  70. /* BOOST_FOREACH isn't available on OOP-servers... */
  71. for (tokenizer< char_separator<char> >::iterator it = tokens.begin();
  72. it != tokens.end();
  73. it++)
  74. {
  75. string tok(*it);
  76. trim(tok);
  77. if (tok.find_first_of(' ') != string::npos)
  78. {
  79. if (tok.find_first_of('"') == string::npos)
  80. throw ParserError("Invalid syntax", m_curline);
  81. }
  82. trim_if(tok, is_any_of("\""));
  83. funcparams.push_back(tok);
  84. }
  85.  
  86. /* then call the corresponding function */
  87. callFunc(func, funcparams);
  88. }
  89.  
  90. file.close();
  91. }
  92.  
  93. /*----------------------------------------------------------------------------*/
  94.  
  95. void CScriptparser::callFunc(const std::string& func, const std::list<std::string>& funcparams)
  96. {
  97. if (func.empty())
  98. throw ParserError("Function name is empty.", m_curline);
  99.  
  100. if (func == "read")
  101. read(funcparams);
  102. else if (func == "write")
  103. write(funcparams);
  104. else
  105. {
  106. if (m_handler == NULL)
  107. throw ParserError("No image is being processed.", m_curline);
  108.  
  109. /* call function from handler */
  110. try
  111. {
  112. m_handler->callFunc(func, funcparams);
  113. }
  114. catch(CFile::FileError& ex)
  115. {
  116. throw ParserError(ex.what(), m_curline);
  117. }
  118. }
  119. }
  120.  
  121. /*----------------------------------------------------------------------------*/
  122.  
  123. void CScriptparser::read(std::list<std::string> funcparams)
  124. {
  125. /* check prerequirements */
  126. if (funcparams.size() != 2)
  127. throw ParserError("Invalid number of function parameters (must be 2).", m_curline);
  128. if (m_handler != NULL)
  129. throw ParserError("An image is already being processed. Unable to open another.", m_curline);
  130.  
  131. string type = funcparams.front();
  132. to_upper(type);
  133. funcparams.pop_front();
  134. string filename = funcparams.front();
  135.  
  136. /* fetch image handler supporting requested filetype */
  137. m_handler = NULL;
  138. set<CFile *>::iterator it;
  139. for (it = m_handlers.begin(); it != m_handlers.end(); it++)
  140. {
  141. if ((*it)->supportsType(type))
  142. {
  143. m_handler = *it;
  144. break;
  145. }
  146. }
  147. if (m_handler == NULL)
  148. throw ParserError("Unknown filetype.", m_curline);
  149.  
  150. /* open file in binary mode */
  151. ifstream file(filename.c_str(), ios::in | ios::binary);
  152. if (!file)
  153. throw ParserError("Unable to read file.", m_curline);
  154.  
  155. /* let handlers read() parse the file */
  156. try
  157. {
  158. m_handler->read(file);
  159. if (!file.good())
  160. throw ParserError("Error while reading image file.", m_curline);
  161. file.close();
  162. }
  163. catch(CFile::FileError& ex)
  164. {
  165. file.close();
  166. throw ParserError(ex.what(), m_curline);
  167. }
  168. }
  169.  
  170. /*----------------------------------------------------------------------------*/
  171.  
  172. void CScriptparser::write(std::list<std::string> funcparams)
  173. {
  174. /* check prerequirements */
  175. if (funcparams.size() != 2)
  176. throw ParserError("Invalid number of function parameters (must be 2).", m_curline);
  177. if (m_handler == NULL)
  178. throw ParserError("No image is being processed.", m_curline);
  179.  
  180. string type = funcparams.front();
  181. to_upper(type);
  182. funcparams.pop_front();
  183. string filename = funcparams.front();
  184.  
  185. /* do we have an image handler supporting the filetype? */
  186. if (!m_handler->supportsType(type))
  187. throw ParserError("Unknown filetype.", m_curline);
  188.  
  189. /* open file in binary mode */
  190. ofstream file(filename.c_str(), ios::out | ios::binary);
  191. if (!file)
  192. throw ParserError("Unable to open file.", m_curline);
  193.  
  194. /* let handlers write() parse the file */
  195. try
  196. {
  197. m_handler->write(file);
  198. if (!file.good())
  199. throw ParserError("Error while writing image file.", m_curline);
  200. file.close();
  201. m_handler = NULL;
  202. }
  203. catch(CFile::FileError& ex)
  204. {
  205. file.close();
  206. m_handler = NULL;
  207. throw ParserError(ex.what(), m_curline);
  208. }
  209. }
  210.  
  211. /* vim: set et sw=2 ts=2: */
  212.