1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
/**
* @module cscriptparser
* @author 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 "cbitmap.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 CBitmap);
}
/*----------------------------------------------------------------------------*/
CScriptparser::~CScriptparser()
{
/* delete image handlers */
set<CFile *>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); it++)
delete *it;
}
/*----------------------------------------------------------------------------*/
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)
continue;
/* 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: */
|