diff options
author | Stephen Kennedy | 2008-09-26 21:53:08 +0000 |
---|---|---|
committer | Stephen Kennedy | 2008-09-26 21:53:08 +0000 |
commit | a7bb113e83c88fad3a23d408caa99f918fdb610a (patch) | |
tree | 698dd9d85abaa6a20957bfb9c0e006e9dd1dc8b3 /common/xmlparser.h | |
parent | 11c0a3bdedcdf5eb2618b9db67b559663fb93320 (diff) | |
parent | c1385076cbc57f1a4a52946a46b3ea06ecf37f37 (diff) | |
download | scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.gz scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.bz2 scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.zip |
Merged revisions 33452-33453,33455-33459,33463-33464,33466-33471,33473-33474,33478,33490,33492,33495-33496,33509-33512,33518-33519,33522-33527,33529-33530,33537,33541,33544,33546,33550,33552-33554,33556,33558,33561-33562,33565,33568,33570,33574,33576,33578-33581,33584-33587,33590,33596,33604-33611,33614-33615,33617-33618,33620-33621,33623,33626-33627,33632-33633,33635,33637,33639-33640,33642-33645,33648,33654-33655,33664,33667-33670,33673-33674,33678,33682,33686-33691,33693,33696,33698,33700,33703,33708,33710,33712-33714,33716,33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766,33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919,33928,33930,33932-33936,33938-33940,33942-33943,33948,33950,33953,33967,33973,33976,33978,33980,33985,33991,33993,33999-34000,34006,34009,34011,34013,34015,34019,34021-34023,34025,34027-34028,34030,34032-34034,34036,34038-34039,34041,34046-34048,34050-34055,34057,34059-34065,34067,34072,34074,34076,34078-34081,34084,34086-34087,34089-34090,34093,34096-34102,34104,34107,34113,34116,34119,34122,34124,34126,34128,34131-34132,34135,34138,34141,34144,34146,34149,34152-34154,34156-34157,34160,34163-34164,34169,34173,34179-34194,34196-34198,34200-34201,34205-34206,34208-34217,34219-34225,34227-34228,34234-34237,34239-34249,34251-34279,34281-34284,34286-34288,34290-34320,34323-34324,34326,34328-34329,34332,34334,34336,34338-34340,34343-34353,34356-34357,34359-34371,34373,34375,34378,34381-34382,34384-34385,34389-34391,34393-34394,34396-34397,34399-34405,34407-34409,34411,34413,34415,34417-34420,34423-34426,34428-34438,34440-34454,34456-34458,34460,34462-34469,34472,34474,34479-34481,34483-34498,34501-34505,34508,34511-34518,34520-34524,34526-34563,34566-34569,34571-34590,34592,34595-34599,34602-34603,34605,34613-34615,34617,34619-34624,34627-34628,34630-34639,34642-34649 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
svn-id: r34654
Diffstat (limited to 'common/xmlparser.h')
-rw-r--r-- | common/xmlparser.h | 240 |
1 files changed, 46 insertions, 194 deletions
diff --git a/common/xmlparser.h b/common/xmlparser.h index 4d1c8fc85d..dcbfc60c2f 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -40,145 +40,12 @@ namespace Common { -/*********************************************** - **** XMLParser.cpp/h -- Generic XML Parser **** - *********************************************** +/* + XMLParser.cpp/h -- Generic XML Parser + ===================================== - This is a simple implementation of a generic parser which is able to - interpret a subset of the XML language. - - The XMLParser class is virtual, and must be derived into a child class, - called a Custom Parser Class, which will manage the parsed data for your - specific needs. - - Custom Parser Classes have two basic requirements: - They must inherit directly the XMLParser class, and they must define the - parsing layout of the XML file. - - Declaring the XML layout is done with the help of the CUSTOM_XML_PARSER() - macro: this macro must appear once inside the Custom Parser Class - declaration, and takes a single parameter, the name of the Custom Parser - Class. - - The macro must be followed by the actual layout of the XML files to be - parsed, and closed with the PARSER_END() macro. The layout of XML files - is defined by the use of 3 helper macros: XML_KEY(), KEY_END() and - XML_PROP(). - - Here's a sample of its usage: - - =========== =========== =========== =========== =========== =========== - - CUSTOM_XML_PARSER(ThemeParser) { - XML_KEY(render_info) - XML_KEY(palette) - XML_KEY(color) - XML_PROP(name, true) - XML_PROP(rgb, true) - KEY_END() - KEY_END() - - XML_KEY(fonts) - XML_KEY(font) - XML_PROP(id, true) - XML_PROP(type, true) - XML_PROP(color, true) - KEY_END() - KEY_END() - - XML_KEY(defaults) - XML_PROP(stroke, false) - XML_PROP(shadow, false) - XML_PROP(factor, false) - XML_PROP(fg_color, false) - XML_PROP(bg_color, false) - XML_PROP(gradient_start, false) - XML_PROP(gradient_end, false) - XML_PROP(gradient_factor, false) - XML_PROP(fill, false) - KEY_END() - KEY_END() - } PARSER_END() - - =========== =========== =========== =========== =========== =========== - - The XML_KEY() macro takes a single argument, the name of the expected key. - Inside the scope of each key, you may define properties for the given key - with the XML_PROP() macro, which takes as parameters the name of the - property and whether it's optional or required. You might also define the - contained children keys, using the XML_KEY() macro again. - The scope of a XML key is closed with the KEY_END() macro. - - Keys which may contain any kind of Property names may be defined with the - XML_PROP_ANY() macro instead of the XML_PROP() macro. This macro takes no - arguments. - - As an example, the following XML layout: - - XML_KEY(palette) - XML_KEY(color) - XML_PROP(name, true) - XML_PROP(rgb, true) - XML_PROP(optional_param, false) - KEY_END() - KEY_END() - - will expect to parse a syntax like this: - - <palette> - <color name = "red" rgb = "255, 0, 0" /> - <color name = "blue" rgb = "0, 0, 255" optional_param = "565" /> - </palette> - - Once a layout has been defined, everytime a XML node (that is, a key and - all its properties) has been parsed, a specific callback funcion is called, - which should take care of managing the parsed data for the node. - - Callback functions must be explicitly declared with the following syntax: - - bool parserCallback_KEYNAME(ParserNode *node); - - A callback function is needed for each key that can be parsed, since they - are called automatically; the function will receive a pointer to the XML - Node that has been parsed. This XML Node has the following properties: - - - It's assured to be expected in the layout of the XML file (i.e. - has the proper position and depth in the XML tree). - - - It's assured to contain all the required Properties that have - been declared in the XML layout. - - - It's assured to contain NO unexpected properties (i.e. properties - which haven't been declared in the XML layout). - - Further validation of the Node's data may be performed inside the callback - function. Once the node has been validated and its data has been parsed/ - managed, the callback function is expected to return true. - - If the data in the XML Node is corrupted or there was a problem when - parsing it, the callback function is expected to return false or, - preferably, to throw a parserError() using the following syntax: - - return parserError("There was a problem in key '%s'.", arg1, ...); - - Also, note that the XML parser doesn't take into account the actual order - of the keys and properties in the XML layout definition, only its layout - and relationships. - - Lastly, when defining your own Custom XML Parser, further customization - may be accomplished _optionally_ by overloading several virtual functions - of the XMLParser class. - - Check the API documentation of the following functions for more info: - - virtual bool closedKeyCallback(ParserNode *node); - virtual bool skipComments(); - virtual bool isValidNameChar(char c); - virtual void cleanup(); - - Check the sample implementation of the GUI::ThemeParser custom parser - for a working sample of a Custom XML Parser. - + External documentation available at: + http://www.smartlikearoboc.com/scummvm_doc/xmlparser_doc.html */ #define XML_KEY(keyName) {\ @@ -226,43 +93,6 @@ namespace Common { #define PARSER_END() layout.clear(); } -class XMLStream { -protected: - SeekableReadStream *_stream; - int _pos; - -public: - XMLStream() : _stream(0), _pos(0) {} - - ~XMLStream() { - delete _stream; - } - - SeekableReadStream *stream() { - return _stream; - } - - char operator [](int idx) { - assert(_stream && idx >= 0); - - if (_pos + 1 != idx) - _stream->seek(idx, SEEK_SET); - - _pos = idx; - - return _stream->readByte(); - } - - void loadStream(SeekableReadStream *s) { - delete _stream; - _stream = s; - } - - bool ready() { - return _stream != 0; - } -}; - /** * The base XMLParser class implements generic functionality for parsing * XML-like files. @@ -278,13 +108,14 @@ public: /** * Parser constructor. */ - XMLParser() : _XMLkeys(0) {} + XMLParser() : _XMLkeys(0), _stream(0) {} virtual ~XMLParser() { while (!_activeKey.empty()) delete _activeKey.pop(); delete _XMLkeys; + delete _stream; for (Common::List<XMLKeyLayout*>::iterator i = _layoutList.begin(); i != _layoutList.end(); ++i) @@ -352,7 +183,7 @@ public: } _fileName = filename; - _text.loadStream(f); + _stream = f; return true; } @@ -365,7 +196,7 @@ public: } _fileName = node.getName(); - _text.loadStream(f); + _stream = f; return true; } @@ -381,13 +212,13 @@ public: * no longer needed by the parser. */ bool loadBuffer(const byte *buffer, uint32 size, bool disposable = false) { - _text.loadStream(new MemoryReadStream(buffer, size, disposable)); + _stream = new MemoryReadStream(buffer, size, disposable); _fileName = "Memory Stream"; return true; } - bool loadStream(MemoryReadStream *stream) { - _text.loadStream(stream); + bool loadStream(SeekableReadStream *stream) { + _stream = stream; _fileName = "Compressed File Stream"; return true; } @@ -492,11 +323,11 @@ protected: * Skips spaces/whitelines etc. Returns true if any spaces were skipped. */ bool skipSpaces() { - if (!isspace(_text[_pos])) + if (!isspace(_char)) return false; - while (_text[_pos] && isspace(_text[_pos])) - _pos++; + while (_char && isspace(_char)) + _char = _stream->readByte(); return true; } @@ -508,14 +339,31 @@ protected: * or to change the commenting syntax. */ virtual bool skipComments() { - if (_text[_pos] == '/' && _text[_pos + 1] == '*') { - _pos += 2; - while (_text[_pos++]) { - if (_text[_pos - 2] == '*' && _text[_pos - 1] == '/') + char endComment1 = 0, endComment2 = 0; + + if (_char == '/') { + _char = _stream->readByte(); + + if (_char != '*') { + _stream->seek(-1, SEEK_CUR); + _char = '/'; + return false; + } + + _char = _stream->readByte(); + + while (_char) { + endComment1 = endComment2; + endComment2 = _char; + _char = _stream->readByte(); + + if (endComment1 == '*' && endComment2 == '/') break; - if (_text[_pos] == 0) + + if (_char == 0) parserError("Comment has no closure."); } + _char = _stream->readByte(); return true; } @@ -527,7 +375,7 @@ protected: * Overload this if you want to support keys with strange characters * in their name. */ - virtual bool isValidNameChar(char c) { + virtual inline bool isValidNameChar(char c) { return isalnum(c) || c == '_'; } @@ -537,10 +385,13 @@ protected: */ bool parseToken() { _token.clear(); - while (isValidNameChar(_text[_pos])) - _token += _text[_pos++]; - return isspace(_text[_pos]) != 0 || _text[_pos] == '>' || _text[_pos] == '=' || _text[_pos] == '/'; + while (isValidNameChar(_char)) { + _token += _char; + _char = _stream->readByte(); + } + + return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/'; } /** @@ -599,7 +450,8 @@ protected: private: int _pos; /** Current position on the XML buffer. */ - XMLStream _text; /** Buffer with the text being parsed */ + char _char; + SeekableReadStream *_stream; Common::String _fileName; ParserState _state; /** Internal state of the parser */ |