diff C++/XmlParser.cpp @ 200:617459270743

Add XML parser
author David Demelier <markand@malikania.fr>
date Sat, 28 Dec 2013 11:16:11 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/XmlParser.cpp	Sat Dec 28 11:16:11 2013 +0100
@@ -0,0 +1,79 @@
+/*
+ * XmlParser.h -- C++ wrapper around libexpat
+ *
+ * Copyright (c) 2013 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <fstream>
+
+#include "XmlParser.h"
+
+namespace {
+
+void xmlStartElementHandler(XmlParser *p, const XML_Char *name, const XML_Char **attrs)
+{
+	XmlParser::Attrs attributes;	
+
+	for (const XML_Char **p = attrs; *p != NULL; p += 2)
+		attributes[p[0]] = p[1];
+
+	p->startElementHandler(name, attributes);
+}
+
+void xmlEndElementHandler(XmlParser *p, const XML_Char *name)
+{
+	p->endElementHandler(name);
+}
+
+void xmlCharacterDataHandler(XmlParser *p, const XML_Char *data, int length)
+{
+	std::string str;
+
+	str.reserve(length);
+	str.insert(0, data, length);
+
+	p->characterDataHandler(str);
+}
+
+}
+
+XmlParser::XmlParser(const std::string &path)
+	: m_path(path)
+{
+	auto p = XML_ParserCreate(nullptr);
+
+	XML_SetUserData(p, this);
+	XML_SetElementHandler(p,
+	    reinterpret_cast<XML_StartElementHandler>(xmlStartElementHandler),
+	    reinterpret_cast<XML_EndElementHandler>(xmlEndElementHandler));
+	XML_SetCharacterDataHandler(p,
+	    reinterpret_cast<XML_CharacterDataHandler>(xmlCharacterDataHandler));
+
+	m_handle = Ptr(new XML_Parser(p));
+}
+
+void XmlParser::open()
+{
+	std::string line;
+	std::ifstream ifile(m_path);
+	int done = 0;
+
+	if (ifile.is_open() && !done) {
+		while (std::getline(ifile, line)) {
+			done = ifile.eof();
+			XML_Parse(*m_handle.get(), line.c_str(), line.length(), done);
+		}
+	}
+}