#ifndef CRASH_XML #define CRASH_XML #include #include #include #include #include #include #include "Strings.h" #include "Lexer.h" using namespace std; class XML { public : enum Type { Element = 256, Body, Data }; #ifdef CRASH_SIGNAL static Signal2 const &> onElementBegin; static Signal1 onElementEnd; static Signal2 onBody; static Signal2 onData; #endif class exception : public runtime_error { public : exception(string const &what, int line) : runtime_error(what.c_str()), _line(line) {} int line() const { return _line; } private : int _line; }; XML(); XML(char const *input); virtual ~XML(); void parse(char const *input); Type type() const { return _type; } string const &name() const { return _data; } string const &body() const { return _data; } string const &data() const { return _data; } vector const &child() const { return _child; } map const &attrib() const { return _attrib; } protected : XML(Type type, XML *parent, Lexer::iterator &token); void init(); void skip(Lexer::iterator &token); void next(Lexer::iterator &token); void parseElement(Lexer::iterator &token); void parseBody(Lexer::iterator &token); void parseData(Lexer::iterator &token); // Lexer constants enum { XmlDecl = 256, XmlCommentBegin, XmlBegin, XmlEnd, XmlDataBegin, XmlContent }; enum { ElementWS = 256, ElementValue, ElementKey, ElementAssignment, ElementTerminator}; enum { CommentEnd = 256, CommentBody }; enum { DataEnd = 256, DataBody }; enum { ProcessBegin = 256, ProcessBody, ProcessEnd }; static bool initialised; static Lexer xmlScan, tagScan, commentScan, dataScan, processScan; XML *_parent; Type _type; string _data; map _attrib; vector _child; }; #endif