[era] parser for the XML format
This commit is contained in:
parent
3e5c02459c
commit
8f73241119
@ -411,7 +411,7 @@ ERA_DUMP_OBJECTS=$(subst .cc,.o,$(ERA_DUMP_SOURCE))
|
||||
|
||||
era_dump: $(ERA_DUMP_OBJECTS) era/era_dump.o
|
||||
@echo " [LD] $@"
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT)
|
||||
|
||||
ERA_INVALIDATE_SOURCE=\
|
||||
block-cache/block_cache.cc \
|
||||
@ -445,7 +445,7 @@ ERA_INVALIDATE_OBJECTS=$(subst .cc,.o,$(ERA_INVALIDATE_SOURCE))
|
||||
|
||||
era_invalidate: $(ERA_INVALIDATE_OBJECTS) era/era_invalidate.o
|
||||
@echo " [LD] $@"
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
#include "era/xml_format.h"
|
||||
|
||||
#include "base/indented_stream.h"
|
||||
#include "base/xml_utils.h"
|
||||
|
||||
#include <expat.h>
|
||||
|
||||
using namespace boost;
|
||||
using namespace era;
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
using namespace xml_utils;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
@ -75,6 +79,56 @@ namespace {
|
||||
private:
|
||||
indented_stream out_;
|
||||
};
|
||||
|
||||
//--------------------------------
|
||||
// Parser
|
||||
//--------------------------------
|
||||
void start_tag(void *data, char const *el, char const **attr) {
|
||||
emitter *e = static_cast<emitter *>(data);
|
||||
attributes a;
|
||||
|
||||
build_attributes(a, attr);
|
||||
|
||||
if (!strcmp(el, "superblock"))
|
||||
e->begin_superblock(get_attr<string>(a, "uuid"),
|
||||
get_attr<uint32_t>(a, "block_size"),
|
||||
get_attr<pd::block_address>(a, "nr_blocks"),
|
||||
get_attr<uint32_t>(a, "current_era"));
|
||||
|
||||
else if (!strcmp(el, "writeset"))
|
||||
e->begin_writeset(get_attr<uint32_t>(a, "era"),
|
||||
get_attr<uint32_t>(a, "nr_bits"));
|
||||
|
||||
else if (!strcmp(el, "bit"))
|
||||
e->writeset_bit(get_attr<uint32_t>(a, "bit"),
|
||||
get_attr<bool>(a, "value"));
|
||||
|
||||
else if (!strcmp(el, "era_array"))
|
||||
e->begin_era_array();
|
||||
|
||||
else if (!strcmp(el, "era"))
|
||||
e->era(get_attr<pd::block_address>(a, "block"),
|
||||
get_attr<uint32_t>(a, "era"));
|
||||
|
||||
else
|
||||
throw runtime_error("unknown tag type");
|
||||
}
|
||||
|
||||
void end_tag(void *data, const char *el) {
|
||||
emitter *e = static_cast<emitter *>(data);
|
||||
|
||||
if (!strcmp(el, "superblock"))
|
||||
e->end_superblock();
|
||||
|
||||
else if (!strcmp(el, "writeset"))
|
||||
e->end_writeset();
|
||||
|
||||
else if (!strcmp(el, "era_array"))
|
||||
e->end_era_array();
|
||||
|
||||
else
|
||||
throw runtime_error("unknown tag type");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@ -85,4 +139,32 @@ era::create_xml_emitter(std::ostream &out)
|
||||
return emitter::ptr(new xml_emitter(out));
|
||||
}
|
||||
|
||||
void
|
||||
era::parse_xml(std::istream &in, emitter::ptr e)
|
||||
{
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
if (!parser)
|
||||
throw runtime_error("couldn't create xml parser");
|
||||
|
||||
XML_SetUserData(parser, e.get());
|
||||
XML_SetElementHandler(parser, start_tag, end_tag);
|
||||
|
||||
while (!in.eof()) {
|
||||
char buffer[4096];
|
||||
in.read(buffer, sizeof(buffer));
|
||||
size_t len = in.gcount();
|
||||
int done = in.eof();
|
||||
|
||||
if (!XML_Parse(parser, buffer, len, done)) {
|
||||
ostringstream out;
|
||||
out << "Parse error at line "
|
||||
<< XML_GetCurrentLineNumber(parser)
|
||||
<< ":\n"
|
||||
<< XML_ErrorString(XML_GetErrorCode(parser))
|
||||
<< endl;
|
||||
throw runtime_error(out.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user