[*_restore] Use a little wrapper class for the expat XML_Parser to ensure it gets destroyed.
This commit is contained in:
parent
a7c96c0e1e
commit
d17ad86a88
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <expat.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -10,6 +11,29 @@ using namespace std;
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace xml_utils {
|
namespace xml_utils {
|
||||||
|
// Simple wrapper to ensure the parser gets freed if an exception
|
||||||
|
// is thrown during parsing.
|
||||||
|
class xml_parser {
|
||||||
|
public:
|
||||||
|
xml_parser()
|
||||||
|
: parser_(XML_ParserCreate(NULL)) {
|
||||||
|
|
||||||
|
if (!parser_)
|
||||||
|
throw runtime_error("couldn't create xml parser");
|
||||||
|
}
|
||||||
|
|
||||||
|
~xml_parser() {
|
||||||
|
XML_ParserFree(parser_);
|
||||||
|
}
|
||||||
|
|
||||||
|
XML_Parser get_parser() {
|
||||||
|
return parser_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
XML_Parser parser_;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> attributes;
|
typedef std::map<std::string, std::string> attributes;
|
||||||
|
|
||||||
void build_attributes(attributes &a, char const **attr);
|
void build_attributes(attributes &a, char const **attr);
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "base/xml_utils.h"
|
#include "base/xml_utils.h"
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <expat.h>
|
|
||||||
|
|
||||||
using namespace caching;
|
using namespace caching;
|
||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
@ -239,12 +238,10 @@ caching::create_xml_emitter(ostream &out)
|
|||||||
void
|
void
|
||||||
caching::parse_xml(istream &in, emitter::ptr e)
|
caching::parse_xml(istream &in, emitter::ptr e)
|
||||||
{
|
{
|
||||||
XML_Parser parser = XML_ParserCreate(NULL);
|
xml_parser p;
|
||||||
if (!parser)
|
|
||||||
throw runtime_error("couldn't create xml parser");
|
|
||||||
|
|
||||||
XML_SetUserData(parser, e.get());
|
XML_SetUserData(p.get_parser(), e.get());
|
||||||
XML_SetElementHandler(parser, start_tag, end_tag);
|
XML_SetElementHandler(p.get_parser(), start_tag, end_tag);
|
||||||
|
|
||||||
while (!in.eof()) {
|
while (!in.eof()) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
@ -252,12 +249,12 @@ caching::parse_xml(istream &in, emitter::ptr e)
|
|||||||
size_t len = in.gcount();
|
size_t len = in.gcount();
|
||||||
int done = in.eof();
|
int done = in.eof();
|
||||||
|
|
||||||
if (!XML_Parse(parser, buffer, len, done)) {
|
if (!XML_Parse(p.get_parser(), buffer, len, done)) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << "Parse error at line "
|
out << "Parse error at line "
|
||||||
<< XML_GetCurrentLineNumber(parser)
|
<< XML_GetCurrentLineNumber(p.get_parser())
|
||||||
<< ":\n"
|
<< ":\n"
|
||||||
<< XML_ErrorString(XML_GetErrorCode(parser))
|
<< XML_ErrorString(XML_GetErrorCode(p.get_parser()))
|
||||||
<< endl;
|
<< endl;
|
||||||
throw runtime_error(out.str());
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include "base/indented_stream.h"
|
#include "base/indented_stream.h"
|
||||||
#include "base/xml_utils.h"
|
#include "base/xml_utils.h"
|
||||||
|
|
||||||
#include <expat.h>
|
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace era;
|
using namespace era;
|
||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
@ -163,12 +161,10 @@ era::create_xml_emitter(std::ostream &out)
|
|||||||
void
|
void
|
||||||
era::parse_xml(std::istream &in, emitter::ptr e)
|
era::parse_xml(std::istream &in, emitter::ptr e)
|
||||||
{
|
{
|
||||||
XML_Parser parser = XML_ParserCreate(NULL);
|
xml_parser p;
|
||||||
if (!parser)
|
|
||||||
throw runtime_error("couldn't create xml parser");
|
|
||||||
|
|
||||||
XML_SetUserData(parser, e.get());
|
XML_SetUserData(p.get_parser(), e.get());
|
||||||
XML_SetElementHandler(parser, start_tag, end_tag);
|
XML_SetElementHandler(p.get_parser(), start_tag, end_tag);
|
||||||
|
|
||||||
while (!in.eof()) {
|
while (!in.eof()) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
@ -176,12 +172,12 @@ era::parse_xml(std::istream &in, emitter::ptr e)
|
|||||||
size_t len = in.gcount();
|
size_t len = in.gcount();
|
||||||
int done = in.eof();
|
int done = in.eof();
|
||||||
|
|
||||||
if (!XML_Parse(parser, buffer, len, done)) {
|
if (!XML_Parse(p.get_parser(), buffer, len, done)) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << "Parse error at line "
|
out << "Parse error at line "
|
||||||
<< XML_GetCurrentLineNumber(parser)
|
<< XML_GetCurrentLineNumber(p.get_parser())
|
||||||
<< ":\n"
|
<< ":\n"
|
||||||
<< XML_ErrorString(XML_GetErrorCode(parser))
|
<< XML_ErrorString(XML_GetErrorCode(p.get_parser()))
|
||||||
<< endl;
|
<< endl;
|
||||||
throw runtime_error(out.str());
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <expat.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -221,12 +220,10 @@ void
|
|||||||
tp::parse_xml(std::istream &in, emitter::ptr e,
|
tp::parse_xml(std::istream &in, emitter::ptr e,
|
||||||
size_t input_length, base::progress_monitor::ptr monitor)
|
size_t input_length, base::progress_monitor::ptr monitor)
|
||||||
{
|
{
|
||||||
XML_Parser parser = XML_ParserCreate(NULL);
|
xml_parser p;
|
||||||
if (!parser)
|
|
||||||
throw runtime_error("couldn't create xml parser");
|
|
||||||
|
|
||||||
XML_SetUserData(parser, e.get());
|
XML_SetUserData(p.get_parser(), e.get());
|
||||||
XML_SetElementHandler(parser, start_tag, end_tag);
|
XML_SetElementHandler(p.get_parser(), start_tag, end_tag);
|
||||||
|
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
||||||
@ -236,12 +233,12 @@ tp::parse_xml(std::istream &in, emitter::ptr e,
|
|||||||
size_t len = in.gcount();
|
size_t len = in.gcount();
|
||||||
int done = in.eof();
|
int done = in.eof();
|
||||||
|
|
||||||
if (!XML_Parse(parser, buffer, len, done)) {
|
if (!XML_Parse(p.get_parser(), buffer, len, done)) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << "Parse error at line "
|
out << "Parse error at line "
|
||||||
<< XML_GetCurrentLineNumber(parser)
|
<< XML_GetCurrentLineNumber(p.get_parser())
|
||||||
<< ":\n"
|
<< ":\n"
|
||||||
<< XML_ErrorString(XML_GetErrorCode(parser))
|
<< XML_ErrorString(XML_GetErrorCode(p.get_parser()))
|
||||||
<< endl;
|
<< endl;
|
||||||
throw runtime_error(out.str());
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user