thin-provisioning-tools/era/xml_format.cc

177 lines
3.9 KiB
C++
Raw Permalink Normal View History

2014-01-23 06:16:03 +05:30
#include "era/xml_format.h"
2014-01-31 19:13:39 +05:30
#include "base/indented_stream.h"
2014-08-06 21:00:38 +05:30
#include "base/xml_utils.h"
2014-01-23 06:16:03 +05:30
using namespace boost;
using namespace era;
using namespace persistent_data;
using namespace std;
2014-08-06 21:00:38 +05:30
using namespace xml_utils;
2014-01-23 06:16:03 +05:30
//----------------------------------------------------------------
namespace {
class xml_emitter : public emitter {
public:
xml_emitter(ostream &out)
2014-01-31 19:13:39 +05:30
: out_(out) {
2014-01-23 06:16:03 +05:30
}
void begin_superblock(std::string const &uuid,
uint32_t block_size,
pd::block_address nr_blocks,
uint32_t current_era) {
2014-01-31 19:13:39 +05:30
out_.indent();
2014-01-23 06:16:03 +05:30
out_ << "<superblock uuid=\"" << uuid << "\""
<< " block_size=\"" << block_size << "\""
<< " nr_blocks=\"" << nr_blocks << "\""
2014-01-31 19:13:39 +05:30
<< " current_era=\"" << current_era << "\">";
out_ << endl;
out_.inc();
2014-01-23 06:16:03 +05:30
}
void end_superblock() {
2014-01-31 19:13:39 +05:30
out_.dec();
out_.indent();
2014-01-23 06:16:03 +05:30
out_ << "</superblock>" << endl;
}
void begin_writeset(uint32_t era, uint32_t nr_bits) {
2014-01-31 19:13:39 +05:30
out_.indent();
out_ << "<writeset era=\"" << era << "\""
<< " nr_bits=\"" << nr_bits << "\">" << endl;
2014-01-31 19:13:39 +05:30
out_.inc();
2014-01-23 06:16:03 +05:30
}
void writeset_bit(uint32_t bit, bool value) {
2014-01-31 19:13:39 +05:30
out_.indent();
2014-01-23 06:16:03 +05:30
// FIXME: collect all the bits, then uuencode
out_ << "<bit block=\"" << bit << "\" value=\"" << truth_value(value) << "\"/>" << endl;
2014-01-23 06:16:03 +05:30
}
void end_writeset() {
2014-01-31 19:13:39 +05:30
out_.dec();
out_.indent();
out_ << "</writeset>" << endl;
2014-01-23 06:16:03 +05:30
}
void begin_era_array() {
2014-01-31 19:13:39 +05:30
out_.indent();
2014-01-23 06:16:03 +05:30
out_ << "<era_array>" << endl;
2014-01-31 19:13:39 +05:30
out_.inc();
2014-01-23 06:16:03 +05:30
}
void era(pd::block_address block, uint32_t era) {
2014-01-31 19:13:39 +05:30
out_.indent();
2014-01-23 06:16:03 +05:30
out_ << "<era block=\"" << block
<< "\" era=\"" << era << "\"/>" << endl;
2014-01-23 06:16:03 +05:30
}
void end_era_array() {
2014-01-31 19:13:39 +05:30
out_.dec();
out_.indent();
2014-01-23 06:16:03 +05:30
out_ << "</era_array>" << endl;
}
char const *truth_value(bool v) const {
return v ? "true" : "false";
}
2014-01-23 06:16:03 +05:30
private:
2014-01-31 19:13:39 +05:30
indented_stream out_;
2014-01-23 06:16:03 +05:30
};
2014-08-06 21:00:38 +05:30
//--------------------------------
// Parser
//--------------------------------
void parse_bit(attributes const &a, emitter *e) {
bool value;
string txt = get_attr<string>(a, "value");
if (txt == "true")
value = true;
else if (txt == "false")
value = false;
else
throw runtime_error("invalid boolean");
e->writeset_bit(get_attr<uint32_t>(a, "block"), value);
}
2014-08-06 21:00:38 +05:30
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"))
parse_bit(a, e);
2014-08-06 21:00:38 +05:30
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 if (!strcmp(el, "era"))
/* do nothing */
;
else if (!strcmp(el, "bit"))
/* do nothing */
;
2014-08-06 21:00:38 +05:30
else
throw runtime_error("unknown tag type");
}
2014-01-23 06:16:03 +05:30
}
//----------------------------------------------------------------
emitter::ptr
era::create_xml_emitter(std::ostream &out)
{
return emitter::ptr(new xml_emitter(out));
}
2014-08-06 21:00:38 +05:30
void
era::parse_xml(std::string const &backup_file, emitter::ptr e, bool quiet)
2014-08-06 21:00:38 +05:30
{
xml_parser p;
2014-08-06 21:00:38 +05:30
XML_SetUserData(p.get_parser(), e.get());
XML_SetElementHandler(p.get_parser(), start_tag, end_tag);
2014-08-06 21:00:38 +05:30
p.parse(backup_file, quiet);
2014-08-06 21:00:38 +05:30
}
2014-01-23 06:16:03 +05:30
//----------------------------------------------------------------