31#include "AISDatabaseParser.h"
39static const not_used
char *states[] =
64 state->state = PARSER_START;
65 state->unknown_depth = 0;
66 state->prev_state = PARSER_UNKNOWN;
67 state->error_msg =
"";
69 DBG2(cerr <<
"Parser state: " << states[state->state] << endl);
77 DBG2(cerr <<
"Ending state == " << states[state->state] << endl);
79 if (state->unknown_depth != 0) {
82 DBG(cerr <<
"unknown_depth != 0 (" << state->unknown_depth <<
")"
99 switch (state->state) {
101 if (strcmp(name,
"ais") != 0) {
102 DBG(cerr <<
"Expecting ais. Got " << name << endl);
111 if (strcmp(name,
"entry") == 0) {
112 state->prev_state = state->state;
113 state->state = ENTRY;
116 state->prev_state = state->state;
117 state->state = PARSER_UNKNOWN;
118 state->unknown_depth++;
123 if (strcmp(name,
"primary") == 0) {
124 state->prev_state = state->state;
125 state->state = PRIMARY;
128 if (strcmp(attrs[0],
"url") == 0) {
129 state->regexp =
false;
130 state->primary = attrs[1];
132 else if (strcmp(attrs[0],
"regexp") == 0) {
133 state->regexp =
true;
134 state->primary = attrs[1];
142 else if (strcmp(name,
"ancillary") == 0) {
143 state->prev_state = state->state;
144 state->state = ANCILLARY;
147 string rule =
"overwrite";
148 for (
int i = 0; attrs && attrs[i] != 0; i = i + 2) {
149 if (strcmp(attrs[i],
"url") == 0)
151 else if (strcmp(attrs[i],
"rule") == 0)
162 if (rule !=
"overwrite" && rule !=
"replace" && rule !=
"fallback") {
163 string msg = string(
"Optional attribute 'rule' in element 'ancillary' has a bad value: ") + rule +
"\nIt should be one of 'overwrite', 'replace' or 'fallback'.";
169 state->rv.push_back(r);
172 state->prev_state = state->state;
173 state->state = PARSER_UNKNOWN;
174 state->unknown_depth++;
185 state->unknown_depth++;
192 DBG2(cerr <<
"Start element " << name <<
" (state "
193 << states[state->state] <<
")" << endl);
206 DBG2(cerr <<
"End element: state " << states[state->state] << endl);
208 switch (state->state) {
210 state->prev_state = state->state;
211 state->state = PARSER_FINISH;
215 state->prev_state = state->state;
225 state->rv.erase(state->rv.begin(), state->rv.end());
229 state->prev_state = state->state;
230 state->state = ENTRY;
234 state->prev_state = state->state;
235 state->state = ENTRY;
240 state->unknown_depth--;
257 return xmlGetPredefinedEntity(name);
269 state->state = PARSER_ERROR;
273 vsnprintf(str, 1024, msg, args);
278 int line = xmlSAX2GetLineNumber(state->ctxt);
280 int line = getLineNumber(state->ctxt);
282 state->error_msg +=
"At line: " + long_to_string(line) +
": ";
283 state->error_msg += string(str) + string(
"\n");
295 state->state = PARSER_ERROR;
299 vsnprintf(str, 1024, msg, args);
304 int line = xmlSAX2GetLineNumber(state->ctxt);
306 int line = getLineNumber(state->ctxt);
308 state->error_msg +=
"At line: " + long_to_string(line) +
": ";
309 state->error_msg += string(str) + string(
"\n");
320 state->state = PARSER_ERROR;
324 vsnprintf(str, 1024, msg, args);
329 int line = xmlSAX2GetLineNumber(state->ctxt);
331 int line = getLineNumber(state->ctxt);
333 state->error_msg +=
"At line: " + long_to_string(line) +
": ";
334 state->error_msg += string(str) + string(
"\n");
341static xmlSAXHandler aisSAXParser =
390 xmlParserCtxtPtr ctxt;
391 AISParserState state;
393 ctxt = xmlCreateFileParserCtxt(database.c_str());
400 ctxt->sax = &aisSAXParser;
401 ctxt->userData = &state;
402 ctxt->validate =
true;
404 xmlParseDocument(ctxt);
407 if (!ctxt->wellFormed) {
409 xmlFreeParserCtxt(ctxt);
410 throw AISDatabaseReadFailed(
string(
"\nThe database is not a well formed XML document.\n") + state.error_msg);
415 xmlFreeParserCtxt(ctxt);
419 if (state.state == PARSER_ERROR) {
421 xmlFreeParserCtxt(ctxt);
426 xmlFreeParserCtxt(ctxt);
static void aisWarning(AISParserState *state, const char *msg,...)
static void aisStartElement(AISParserState *state, const char *name, const char **attrs)
static xmlEntityPtr aisGetEntity(AISParserState *state, const xmlChar *name)
static void aisStartDocument(AISParserState *state)
void intern(const string &database, AISResources *ais)
static void aisEndElement(AISParserState *state, const char *name)
static void aisEndDocument(AISParserState *state)
static void aisFatalError(AISParserState *state, const char *msg,...)
static void aisError(AISParserState *state, const char *msg,...)
virtual void add_regexp_resource(const string ®exp, const Resource &ancillary)
virtual void add_url_resource(const string &url, const Resource &ancillary)
Associate a rule with an ancillary resource.
top level DAP object to house generic methods