view 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 source

/*
 * 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);
		}
	}
}