#include #include #include "XMLParser.h" #include "Exception.h" #include "Parser.h" #include "TileData.h" using namespace std; XMLParser XMLParser::instance {}; XMLParser::XMLParser() { Parser::register_strategy(this); } unsigned int XMLParser::heuristic(FileStrategy & f) { const string content = f.read(); int open_backets = 0; int close_brackets = 0; for (char c : content) { if (c == '<') open_backets++; if (c == '>') close_brackets++; } int balance = abs(open_backets - close_brackets); int penalty = 1 + balance * 10; return (open_backets + close_brackets) / penalty; } void XMLParser::parse(FileStrategy & f, Deserializer & d) { using namespace pugi; const string content = f.read(); xml_document doc; xml_parse_result result = doc.load_string(content.c_str()); if (!result) throw Exception("parsing XML failed"); xml_node canvas = doc.child("canvas"); if (!canvas) throw Exception("missing "); d.set_canvas({ .rows = canvas.attribute("rows").as_uint(), .columns = canvas.attribute("cols").as_uint(), }); xml_node node_types = canvas.child("nodeTypes"); if (!node_types) throw Exception("missing "); for (xml_node node_type : node_types) { d.add_type( node_type.attribute("tag").as_string(), { .red = node_type.attribute("red").as_uint(), .green = node_type.attribute("green").as_uint(), .blue = node_type.attribute("blue").as_uint(), }, node_type.attribute("weight").as_int() ); } xml_node nodes = canvas.child("nodes"); if (!nodes) throw Exception("missing "); for (xml_node node : nodes) { d.set_tile({ .x = node.attribute("x").as_uint(), .y = node.attribute("y").as_uint(), .type = node.name(), }); } }