aboutsummaryrefslogtreecommitdiff
path: root/common/xmlparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/xmlparser.cpp')
-rw-r--r--common/xmlparser.cpp122
1 files changed, 117 insertions, 5 deletions
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index 1c652fa19d..b53a9a33c2 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -27,10 +27,25 @@
#include "common/util.h"
#include "common/archive.h"
#include "common/fs.h"
+#include "common/memstream.h"
namespace Common {
-bool XMLParser::loadFile(const Common::String &filename) {
+XMLParser::~XMLParser() {
+ while (!_activeKey.empty())
+ freeNode(_activeKey.pop());
+
+ delete _XMLkeys;
+ delete _stream;
+
+ for (List<XMLKeyLayout*>::iterator i = _layoutList.begin();
+ i != _layoutList.end(); ++i)
+ delete *i;
+
+ _layoutList.clear();
+}
+
+bool XMLParser::loadFile(const String &filename) {
_stream = SearchMan.createReadStreamForMember(filename);
if (!_stream)
return false;
@@ -54,7 +69,7 @@ bool XMLParser::loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Fla
return true;
}
-bool XMLParser::loadStream(Common::SeekableReadStream *stream) {
+bool XMLParser::loadStream(SeekableReadStream *stream) {
_stream = stream;
_fileName = "File Stream";
return true;
@@ -158,10 +173,10 @@ bool XMLParser::parseActiveKey(bool closed) {
if (layout->children.contains(key->name)) {
key->layout = layout->children[key->name];
- Common::StringMap localMap = key->values;
+ StringMap localMap = key->values;
int keyCount = localMap.size();
- for (Common::List<XMLKeyLayout::XMLKeyProperty>::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) {
+ for (List<XMLKeyLayout::XMLKeyProperty>::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) {
if (i->required && !localMap.contains(i->name))
return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str());
else if (localMap.contains(i->name))
@@ -198,7 +213,7 @@ bool XMLParser::parseActiveKey(bool closed) {
return true;
}
-bool XMLParser::parseKeyValue(Common::String keyName) {
+bool XMLParser::parseKeyValue(String keyName) {
assert(_activeKey.empty() == false);
if (_activeKey.top()->values.contains(keyName))
@@ -229,6 +244,47 @@ bool XMLParser::parseKeyValue(Common::String keyName) {
return true;
}
+bool XMLParser::parseIntegerKey(const char *key, int count, ...) {
+ bool result;
+ va_list args;
+ va_start(args, count);
+ result = vparseIntegerKey(key, count, args);
+ va_end(args);
+ return result;
+}
+
+bool XMLParser::parseIntegerKey(const String &key, int count, ...) {
+ bool result;
+ va_list args;
+ va_start(args, count);
+ result = vparseIntegerKey(key.c_str(), count, args);
+ va_end(args);
+ return result;
+}
+
+bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
+ char *parseEnd;
+ int *num_ptr;
+
+ while (count--) {
+ while (isspace(*key))
+ key++;
+
+ num_ptr = va_arg(args, int*);
+ *num_ptr = strtol(key, &parseEnd, 10);
+
+ key = parseEnd;
+
+ while (isspace(*key))
+ key++;
+
+ if (count && *key++ != ',')
+ return false;
+ }
+
+ return (*key == 0);
+}
+
bool XMLParser::closeKey() {
bool ignore = false;
bool result = true;
@@ -410,5 +466,61 @@ bool XMLParser::parse() {
return true;
}
+bool XMLParser::skipSpaces() {
+ if (!isspace(_char))
+ return false;
+
+ while (_char && isspace(_char))
+ _char = _stream->readByte();
+
+ return true;
+}
+
+bool XMLParser::skipComments() {
+ if (_char == '<') {
+ _char = _stream->readByte();
+
+ if (_char != '!') {
+ _stream->seek(-1, SEEK_CUR);
+ _char = '<';
+ return false;
+ }
+
+ if (_stream->readByte() != '-' || _stream->readByte() != '-')
+ return parserError("Malformed comment syntax.");
+
+ _char = _stream->readByte();
+
+ while (_char) {
+ if (_char == '-') {
+ if (_stream->readByte() == '-') {
+
+ if (_stream->readByte() != '>')
+ return parserError("Malformed comment (double-hyphen inside comment body).");
+
+ _char = _stream->readByte();
+ return true;
+ }
+ }
+
+ _char = _stream->readByte();
+ }
+
+ return parserError("Comment has no closure.");
+ }
+
+ return false;
+}
+
+bool XMLParser::parseToken() {
+ _token.clear();
+
+ while (isValidNameChar(_char)) {
+ _token += _char;
+ _char = _stream->readByte();
+ }
+
+ return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
}
+} // End of namespace Common