summaryrefslogtreecommitdiff
path: root/src/plugins/xml
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-03 00:04:05 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-03 00:04:05 +0100
commit59177921e8c81c1604e4154503a63190db66989c (patch)
tree4234e0d329791d45b69337e545499e3aa92c1bb2 /src/plugins/xml
parente579da493bc0b53d63cdd499c96ac181c1719068 (diff)
continued work on XML parser and underlying ParserStack class
Diffstat (limited to 'src/plugins/xml')
-rw-r--r--src/plugins/xml/XmlParser.cpp102
1 files changed, 69 insertions, 33 deletions
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp
index 42e0dd4..afc7f14 100644
--- a/src/plugins/xml/XmlParser.cpp
+++ b/src/plugins/xml/XmlParser.cpp
@@ -20,6 +20,7 @@
#include <expat.h>
+#include <core/Utils.hpp>
#include <core/parser/ParserStack.hpp>
#include "XmlParser.hpp"
@@ -44,30 +45,54 @@ static const State STATE_CONSTANT = 201;
static const State STATE_ENUM = 202;
static const State STATE_STRUCT = 203;
-static Handler* createTestHandler(const ParserContext &ctx,
- std::string name, State state,
- State parentState, bool isChild)
+class TestHandler : public Handler {
+public:
+ using Handler::Handler;
+
+ void start(const Variant &args) override
+ {
+ std::cout << this->name << ": start (isChild: " << (this->isChild)
+ << ", args: " << args << ")" << std::endl;
+ }
+
+ void end() override
+ {
+ // TODO
+ }
+
+ void data(const std::string &data, int field) override
+ {
+ std::cout << this->name << ": data \"" << data << "\"" << std::endl;
+ }
+
+ void child(std::shared_ptr<Handler> handler) override
+ {
+ // TODO
+ }
+};
+
+static Handler *createTestHandler(const ParserContext &ctx, std::string name,
+ State state, State parentState, bool isChild)
{
- return nullptr;
+ return new TestHandler{ctx, name, state, parentState, isChild};
}
static const std::multimap<std::string, HandlerDescriptor> XML_HANDLERS{
- /* Documents */
- {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}},
- {"head", {{STATE_DOCUMENT}, createTestHandler, STATE_HEAD}},
- {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}},
-
- /* Special commands */
- {"use", {{STATE_HEAD}, createTestHandler, STATE_USE}},
- {"include", {{STATE_ALL}, createTestHandler, STATE_INCLUDE}},
- {"inline", {{STATE_ALL}, createTestHandler, STATE_INLINE}},
-
- /* Typesystem definitions */
- {"types", {{STATE_NONE, STATE_HEAD}, createTestHandler, STATE_TYPES}},
- {"enum", {{STATE_TYPES}, createTestHandler, STATE_ENUM}},
- {"struct", {{STATE_TYPES}, createTestHandler, STATE_STRUCT}},
- {"constant", {{STATE_TYPES}, createTestHandler, STATE_CONSTANT}}
-};
+ /* Documents */
+ {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}},
+ {"head", {{STATE_DOCUMENT}, createTestHandler, STATE_HEAD}},
+ {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}},
+
+ /* Special commands */
+ {"use", {{STATE_HEAD}, createTestHandler, STATE_USE}},
+ {"include", {{STATE_ALL}, createTestHandler, STATE_INCLUDE}},
+ {"inline", {{STATE_ALL}, createTestHandler, STATE_INLINE}},
+
+ /* Typesystem definitions */
+ {"typesystem", {{STATE_NONE, STATE_HEAD}, createTestHandler, STATE_TYPES}},
+ {"enum", {{STATE_TYPES}, createTestHandler, STATE_ENUM}},
+ {"struct", {{STATE_TYPES}, createTestHandler, STATE_STRUCT}},
+ {"constant", {{STATE_TYPES}, createTestHandler, STATE_CONSTANT}}};
/**
* Wrapper class around the XML_Parser pointer which safely frees it whenever
@@ -89,8 +114,7 @@ public:
* @param encoding is the protocol-defined encoding passed to expat (or
* nullptr if expat should determine the encoding by itself).
*/
- ScopedExpatXmlParser(const XML_Char *encoding)
- : parser(nullptr)
+ ScopedExpatXmlParser(const XML_Char *encoding) : parser(nullptr)
{
parser = XML_ParserCreate(encoding);
if (!parser) {
@@ -116,28 +140,36 @@ public:
XML_Parser operator&() { return parser; }
};
+/* Adapter Expat -> ParserStack */
+
static void xmlStartElementHandler(void *userData, const XML_Char *name,
const XML_Char **attrs)
{
- std::cout << "start tag: " << name << std::endl;
+ Variant::mapType args;
const XML_Char **attr = attrs;
while (*attr) {
- std::cout << "\t" << *attr;
- attr++;
- std::cout << " -> " << *attr << std::endl;
- attr++;
+ const std::string key{*(attr++)};
+ args.emplace(std::make_pair(key, Variant{*(attr++)}));
}
+ (static_cast<ParserStack *>(userData))->start(std::string(name), args);
}
-static void xmlEndElementHandler(void *userData, const XML_Char *name) {
- std::cout << "end tag: " << name << std::endl;
+static void xmlEndElementHandler(void *userData, const XML_Char *name)
+{
+ (static_cast<ParserStack *>(userData))->end();
}
-
-static void xmlCharacterDataHandler(void *userData, const XML_Char *s, int len) {
- std::cout << "\tdata: " << std::string(s, len) << std::endl;
+static void xmlCharacterDataHandler(void *userData, const XML_Char *s, int len)
+{
+ const std::string data =
+ Utils::trim(std::string{s, static_cast<size_t>(len)});
+ if (!data.empty()) {
+ (static_cast<ParserStack *>(userData))->data(data);
+ }
}
+/* Class XmlParser */
+
std::set<std::string> XmlParser::mimetypes()
{
return std::set<std::string>{{"text/vnd.ousia.oxm", "text/vnd.ousia.oxd"}};
@@ -147,7 +179,11 @@ Rooted<Node> XmlParser::parse(std::istream &is, ParserContext &ctx)
{
// Create the parser object
ScopedExpatXmlParser p{"UTF-8"};
- XML_SetUserData(&p, &ctx);
+
+ // Create the parser stack instance and pass the reference to the state
+ // machine descriptor
+ ParserStack stack{ctx, XML_HANDLERS};
+ XML_SetUserData(&p, &stack);
// Set the callback functions
XML_SetStartElementHandler(&p, xmlStartElementHandler);