Ticket #900: graphml.cpp.patch
File graphml.cpp.patch, 10.0 KB (added by , 13 years ago) |
---|
-
graphml.cpp
old new 12 12 #include <boost/variant.hpp> 13 13 #include <expat.h> 14 14 #include <boost/graph/graphml.hpp> 15 #include < string>15 #include <boost/algorithm/string/replace.hpp> 16 16 17 17 using namespace boost; 18 18 … … 25 25 void run(std::istream& in) 26 26 { 27 27 const int buffer_size = 4096; 28 XML_Parserparser = XML_ParserCreateNS(0,'|');29 XML_SetElementHandler( parser, &on_start_element, &on_end_element);30 XML_SetCharacterDataHandler( parser, &on_character_data);31 XML_SetUserData( parser, this);28 m_parser = XML_ParserCreateNS(0,'|'); 29 XML_SetElementHandler(m_parser, &on_start_element, &on_end_element); 30 XML_SetCharacterDataHandler(m_parser, &on_character_data); 31 XML_SetUserData(m_parser, this); 32 32 char buffer[buffer_size]; 33 33 34 34 bool okay = true; 35 35 do 36 36 { 37 in.read(buffer, buffer_size); 38 39 okay = XML_Parse(parser, buffer, in.gcount(), in.gcount() == 0); 37 in.read(buffer, buffer_size); 38 okay = XML_Parse(m_parser, buffer, in.gcount(), in.gcount() == 0); 40 39 } 41 40 while (okay && in.good()); 42 41 43 42 if (!okay) 44 43 { 45 44 std::stringstream s; 46 s << "Parse error: " << XML_ErrorString(XML_GetErrorCode(parser)) 47 << " on line " << XML_GetCurrentLineNumber(parser) 48 <<", column " << XML_GetCurrentColumnNumber(parser); 49 XML_ParserFree(parser); 45 s << "on line " << XML_GetCurrentLineNumber(m_parser) 46 <<", column " << XML_GetCurrentColumnNumber(m_parser) 47 << ": " << XML_ErrorString(XML_GetErrorCode(m_parser)); 50 48 throw parse_error(s.str()); 51 49 } 52 XML_ParserFree( parser);50 XML_ParserFree(m_parser); 53 51 } 54 52 55 53 private: … … 71 69 graphml_reader* self = static_cast<graphml_reader*>(user_data); 72 70 73 71 std::string name(c_name); 74 std::string::size_type pos = name.find('|'); 75 if (pos != std::string::npos) 76 name.erase(0, pos+1); 77 78 if (name == "key") 72 replace_first(name, "http://graphml.graphdrawing.org/xmlns|", ""); 73 74 if (name == "edge") 79 75 { 80 76 std::string id; 81 std::string key_name; 82 std::string key_type; 83 key_kind kind = all_key; 84 77 std::string source, target; 85 78 while (*atts) 86 79 { 87 80 std::string name = *atts++; 88 81 std::string value = *atts++; 89 82 90 83 if (name == "id") id = value; 91 else if (name == " attr.name") key_name = value;92 else if (name == " attr.type") key_type= value;93 else if (name == " for")84 else if (name == "source") source = value; 85 else if (name == "target") target = value; 86 else if (name == "directed") 94 87 { 95 if (value == "graph") kind = graph_key; 96 else if (value == "node") kind = node_key; 97 else if (value == "edge") kind = edge_key; 98 else if (value == "hyperedge") kind = hyperedge_key; 99 else if (value == "port") kind = port_key; 100 else if (value == "endpoint") kind = endpoint_key; 101 else if (value == "all") kind = all_key; 102 else 88 bool edge_is_directed = (value == "directed"); 89 if (edge_is_directed != self->m_g.is_directed()) 103 90 { 104 throw parse_error("unrecognized key kind '" + value + "'"); 91 if (edge_is_directed) 92 throw directed_graph_error(); 93 else 94 throw undirected_graph_error(); 105 95 } 106 96 } 107 97 } 108 98 109 self->m_keys[id] = kind; 110 self->m_key_name[id] = key_name; 111 self->m_key_type[id] = key_type; 112 self->m_active_key = id; 113 } 99 self->m_active_descriptor = self->m_edge.size(); 100 self->handle_edge(source, target); 101 } 114 102 else if (name == "node") 115 103 { 116 104 std::string id; … … 126 114 self->handle_vertex(id); 127 115 self->m_active_descriptor = id; 128 116 } 129 else if (name == "edge") 117 else if (name == "data") 118 { 119 while (*atts) 120 { 121 std::string name = *atts++; 122 std::string value = *atts++; 123 124 if (name == "key") self->m_active_key = value; 125 } 126 } 127 else if (name == "key") 130 128 { 131 129 std::string id; 132 std::string source, target; 130 std::string key_name; 131 std::string key_type; 132 key_kind kind = all_key; 133 133 134 while (*atts) 134 135 { 135 136 std::string name = *atts++; 136 137 std::string value = *atts++; 137 138 138 139 if (name == "id") id = value; 139 else if (name == " source") source = value;140 else if (name == " target") target= value;141 else if (name == " directed")140 else if (name == "attr.name") key_name = value; 141 else if (name == "attr.type") key_type = value; 142 else if (name == "for") 142 143 { 143 bool edge_is_directed = (value == "directed"); 144 if (edge_is_directed != self->m_g.is_directed()) 144 if (value == "graph") kind = graph_key; 145 else if (value == "node") kind = node_key; 146 else if (value == "edge") kind = edge_key; 147 else if (value == "hyperedge") kind = hyperedge_key; 148 else if (value == "port") kind = port_key; 149 else if (value == "endpoint") kind = endpoint_key; 150 else if (value == "all") kind = all_key; 151 else 145 152 { 146 if (edge_is_directed) 147 throw directed_graph_error(); 148 else 149 throw undirected_graph_error(); 153 std::stringstream s; 154 s << "on line " << XML_GetCurrentLineNumber(self->m_parser) 155 << ", column " << XML_GetCurrentColumnNumber(self->m_parser) 156 << ": unrecognized key kind '" << value << "'"; 157 throw parse_error(s.str()); 150 158 } 151 159 } 152 160 } 153 161 154 self->m_active_descriptor = self->m_edge.size(); 155 self->handle_edge(source, target); 162 self->m_keys[id] = kind; 163 self->m_key_name[id] = key_name; 164 self->m_key_type[id] = key_type; 165 self->m_active_key = id; 156 166 } 157 167 else if (name == "graph") 158 168 { … … 179 189 } 180 190 self->m_active_descriptor = ""; 181 191 } 182 else if (name == "data")183 {184 while (*atts)185 {186 std::string name = *atts++;187 std::string value = *atts++;188 189 if (name == "key") self->m_active_key = value;190 }191 }192 192 193 193 self->m_character_data.clear(); 194 194 } … … 199 199 graphml_reader* self = static_cast<graphml_reader*>(user_data); 200 200 201 201 std::string name(c_name); 202 std::string::size_type pos = name.find('|'); 203 if (pos != std::string::npos) 204 name.erase(0, pos+1); 202 replace_first(name, "http://graphml.graphdrawing.org/xmlns|", ""); 205 203 206 204 if (name == "data") 207 205 { … … 237 235 } 238 236 catch (bad_lexical_cast) 239 237 { 240 throw parse_error("invalid vertex: " + v); 238 std::stringstream s; 239 s << "on line " << XML_GetCurrentLineNumber(m_parser) 240 << ", column " << XML_GetCurrentColumnNumber(m_parser) 241 << ": invalid vertex: " << v; 242 throw parse_error(s.str()); 241 243 } 242 244 243 245 while(id >= m_canonical_vertex.size()) … … 310 312 311 313 void handle_property(const std::string& key_id, const variant<std::string,size_t>& descriptor, const std::string& value) 312 314 { 313 if (get<std::string>(&descriptor))315 try 314 316 { 315 if (get<std::string>(descriptor) == "") 316 m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); 317 if (get<std::string>(&descriptor)) 318 { 319 if (get<std::string>(descriptor) == "") 320 m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); 321 else 322 m_g.set_vertex_property(m_key_name[key_id], get_vertex_descriptor(get<std::string>(descriptor)), value, m_key_type[key_id]); 323 } 317 324 else 318 m_g.set_vertex_property(m_key_name[key_id], get_vertex_descriptor(get<std::string>(descriptor)), value, m_key_type[key_id]); 325 { 326 m_g.set_edge_property(m_key_name[key_id], get_edge_descriptor(get<size_t>(descriptor)), value, m_key_type[key_id]); 327 } 319 328 } 320 else329 catch (parse_error &e) 321 330 { 322 m_g.set_edge_property(m_key_name[key_id], get_edge_descriptor(get<size_t>(descriptor)), value, m_key_type[key_id]); 331 std::stringstream s; 332 s << "on line " << XML_GetCurrentLineNumber(m_parser) 333 << ", column " << XML_GetCurrentColumnNumber(m_parser) 334 << ": " << e.error; 335 throw parse_error(s.str()); 323 336 } 324 337 } 325 338 … … 342 355 std::string m_character_data; 343 356 bool m_canonical_vertices; 344 357 bool m_canonical_edges; 358 XML_Parser m_parser; 345 359 }; 346 360 347 361 namespace boost