Download | Plain Text | No Line Numbers


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