--- /home/count0/Desktop/graphml.cpp 2007-04-12 09:12:51.000000000 -0300 +++ graphml.cpp 2007-04-12 09:16:55.000000000 -0300 @@ -12,7 +12,7 @@ #include #include #include -#include +#include using namespace boost; @@ -25,31 +25,29 @@ void run(std::istream& in) { const int buffer_size = 4096; - XML_Parser parser = XML_ParserCreateNS(0,'|'); - XML_SetElementHandler(parser, &on_start_element, &on_end_element); - XML_SetCharacterDataHandler(parser, &on_character_data); - XML_SetUserData(parser, this); + m_parser = XML_ParserCreateNS(0,'|'); + XML_SetElementHandler(m_parser, &on_start_element, &on_end_element); + XML_SetCharacterDataHandler(m_parser, &on_character_data); + XML_SetUserData(m_parser, this); char buffer[buffer_size]; bool okay = true; do { - in.read(buffer, buffer_size); - - okay = XML_Parse(parser, buffer, in.gcount(), in.gcount() == 0); + in.read(buffer, buffer_size); + okay = XML_Parse(m_parser, buffer, in.gcount(), in.gcount() == 0); } while (okay && in.good()); if (!okay) { std::stringstream s; - s << "Parse error: " << XML_ErrorString(XML_GetErrorCode(parser)) - << " on line " << XML_GetCurrentLineNumber(parser) - <<", column " << XML_GetCurrentColumnNumber(parser); - XML_ParserFree(parser); + s << "on line " << XML_GetCurrentLineNumber(m_parser) + <<", column " << XML_GetCurrentColumnNumber(m_parser) + << ": " << XML_ErrorString(XML_GetErrorCode(m_parser)); throw parse_error(s.str()); } - XML_ParserFree(parser); + XML_ParserFree(m_parser); } private: @@ -71,46 +69,36 @@ graphml_reader* self = static_cast(user_data); std::string name(c_name); - std::string::size_type pos = name.find('|'); - if (pos != std::string::npos) - name.erase(0, pos+1); - - if (name == "key") + replace_first(name, "http://graphml.graphdrawing.org/xmlns|", ""); + + if (name == "edge") { std::string id; - std::string key_name; - std::string key_type; - key_kind kind = all_key; - + std::string source, target; while (*atts) { std::string name = *atts++; std::string value = *atts++; if (name == "id") id = value; - else if (name == "attr.name") key_name = value; - else if (name == "attr.type") key_type = value; - else if (name == "for") + else if (name == "source") source = value; + else if (name == "target") target = value; + else if (name == "directed") { - if (value == "graph") kind = graph_key; - else if (value == "node") kind = node_key; - else if (value == "edge") kind = edge_key; - else if (value == "hyperedge") kind = hyperedge_key; - else if (value == "port") kind = port_key; - else if (value == "endpoint") kind = endpoint_key; - else if (value == "all") kind = all_key; - else + bool edge_is_directed = (value == "directed"); + if (edge_is_directed != self->m_g.is_directed()) { - throw parse_error("unrecognized key kind '" + value + "'"); + if (edge_is_directed) + throw directed_graph_error(); + else + throw undirected_graph_error(); } } } - self->m_keys[id] = kind; - self->m_key_name[id] = key_name; - self->m_key_type[id] = key_type; - self->m_active_key = id; - } + self->m_active_descriptor = self->m_edge.size(); + self->handle_edge(source, target); + } else if (name == "node") { std::string id; @@ -126,33 +114,55 @@ self->handle_vertex(id); self->m_active_descriptor = id; } - else if (name == "edge") + else if (name == "data") + { + while (*atts) + { + std::string name = *atts++; + std::string value = *atts++; + + if (name == "key") self->m_active_key = value; + } + } + else if (name == "key") { std::string id; - std::string source, target; + std::string key_name; + std::string key_type; + key_kind kind = all_key; + while (*atts) { std::string name = *atts++; std::string value = *atts++; if (name == "id") id = value; - else if (name == "source") source = value; - else if (name == "target") target = value; - else if (name == "directed") + else if (name == "attr.name") key_name = value; + else if (name == "attr.type") key_type = value; + else if (name == "for") { - bool edge_is_directed = (value == "directed"); - if (edge_is_directed != self->m_g.is_directed()) + if (value == "graph") kind = graph_key; + else if (value == "node") kind = node_key; + else if (value == "edge") kind = edge_key; + else if (value == "hyperedge") kind = hyperedge_key; + else if (value == "port") kind = port_key; + else if (value == "endpoint") kind = endpoint_key; + else if (value == "all") kind = all_key; + else { - if (edge_is_directed) - throw directed_graph_error(); - else - throw undirected_graph_error(); + std::stringstream s; + s << "on line " << XML_GetCurrentLineNumber(self->m_parser) + << ", column " << XML_GetCurrentColumnNumber(self->m_parser) + << ": unrecognized key kind '" << value << "'"; + throw parse_error(s.str()); } } } - self->m_active_descriptor = self->m_edge.size(); - self->handle_edge(source, target); + self->m_keys[id] = kind; + self->m_key_name[id] = key_name; + self->m_key_type[id] = key_type; + self->m_active_key = id; } else if (name == "graph") { @@ -179,16 +189,6 @@ } self->m_active_descriptor = ""; } - else if (name == "data") - { - while (*atts) - { - std::string name = *atts++; - std::string value = *atts++; - - if (name == "key") self->m_active_key = value; - } - } self->m_character_data.clear(); } @@ -199,9 +199,7 @@ graphml_reader* self = static_cast(user_data); std::string name(c_name); - std::string::size_type pos = name.find('|'); - if (pos != std::string::npos) - name.erase(0, pos+1); + replace_first(name, "http://graphml.graphdrawing.org/xmlns|", ""); if (name == "data") { @@ -237,7 +235,11 @@ } catch (bad_lexical_cast) { - throw parse_error("invalid vertex: " + v); + std::stringstream s; + s << "on line " << XML_GetCurrentLineNumber(m_parser) + << ", column " << XML_GetCurrentColumnNumber(m_parser) + << ": invalid vertex: " << v; + throw parse_error(s.str()); } while(id >= m_canonical_vertex.size()) @@ -310,16 +312,27 @@ void handle_property(const std::string& key_id, const variant& descriptor, const std::string& value) { - if (get(&descriptor)) + try { - if (get(descriptor) == "") - m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); + if (get(&descriptor)) + { + if (get(descriptor) == "") + m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); + else + m_g.set_vertex_property(m_key_name[key_id], get_vertex_descriptor(get(descriptor)), value, m_key_type[key_id]); + } else - m_g.set_vertex_property(m_key_name[key_id], get_vertex_descriptor(get(descriptor)), value, m_key_type[key_id]); + { + m_g.set_edge_property(m_key_name[key_id], get_edge_descriptor(get(descriptor)), value, m_key_type[key_id]); + } } - else + catch (parse_error &e) { - m_g.set_edge_property(m_key_name[key_id], get_edge_descriptor(get(descriptor)), value, m_key_type[key_id]); + std::stringstream s; + s << "on line " << XML_GetCurrentLineNumber(m_parser) + << ", column " << XML_GetCurrentColumnNumber(m_parser) + << ": " << e.error; + throw parse_error(s.str()); } } @@ -342,6 +355,7 @@ std::string m_character_data; bool m_canonical_vertices; bool m_canonical_edges; + XML_Parser m_parser; }; namespace boost