[era] parser for the XML format
This commit is contained in:
		@@ -411,7 +411,7 @@ ERA_DUMP_OBJECTS=$(subst .cc,.o,$(ERA_DUMP_SOURCE))
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
era_dump: $(ERA_DUMP_OBJECTS)  era/era_dump.o
 | 
					era_dump: $(ERA_DUMP_OBJECTS)  era/era_dump.o
 | 
				
			||||||
	@echo "    [LD]  $@"
 | 
						@echo "    [LD]  $@"
 | 
				
			||||||
	$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
 | 
						$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERA_INVALIDATE_SOURCE=\
 | 
					ERA_INVALIDATE_SOURCE=\
 | 
				
			||||||
	block-cache/block_cache.cc \
 | 
						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
 | 
					era_invalidate: $(ERA_INVALIDATE_OBJECTS)  era/era_invalidate.o
 | 
				
			||||||
	@echo "    [LD]  $@"
 | 
						@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 "era/xml_format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "base/indented_stream.h"
 | 
					#include "base/indented_stream.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;
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace xml_utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//----------------------------------------------------------------
 | 
					//----------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,6 +79,56 @@ namespace {
 | 
				
			|||||||
	private:
 | 
						private:
 | 
				
			||||||
		indented_stream out_;
 | 
							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));
 | 
						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());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//----------------------------------------------------------------
 | 
					//----------------------------------------------------------------
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user