Ticket #900: graphml.cpp.patch

File graphml.cpp.patch, 10.0 KB (added by Jeremiah Willcock, 13 years ago)
  • graphml.cpp

    old new  
    1212#include <boost/variant.hpp>
    1313#include <expat.h>
    1414#include <boost/graph/graphml.hpp>
    15 #include <string>
     15#include <boost/algorithm/string/replace.hpp>
    1616
    1717using namespace boost;
    1818
     
    2525    void run(std::istream& in)
    2626    {
    2727        const int buffer_size = 4096;
    28         XML_Parser parser = 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);
    3232        char buffer[buffer_size];
    3333
    3434        bool okay = true;
    3535        do
    3636        {
    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);
    4039        }
    4140        while (okay && in.good());
    4241
    4342        if (!okay)
    4443        {
    4544            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));
    5048            throw parse_error(s.str());
    5149        }
    52         XML_ParserFree(parser);
     50        XML_ParserFree(m_parser);
    5351    }
    5452
    5553private:
     
    7169        graphml_reader* self = static_cast<graphml_reader*>(user_data);
    7270
    7371        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")
    7975        {
    8076            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;
    8578            while (*atts)
    8679            {
    8780                std::string name = *atts++;
    8881                std::string value = *atts++;
    8982
    9083                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")
    9487                {
    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())
    10390                    {
    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();
    10595                    }
    10696                }
    10797            }
    10898
    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        }
    114102        else if (name == "node")
    115103        {
    116104            std::string id;
     
    126114            self->handle_vertex(id);
    127115            self->m_active_descriptor = id;
    128116        }
    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")
    130128        {
    131129            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
    133134            while (*atts)
    134135            {
    135136                std::string name = *atts++;
    136137                std::string value = *atts++;
    137138
    138139                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")
    142143                {
    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
    145152                    {
    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());
    150158                    }
    151159                }
    152160            }
    153161
    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;
    156166        }
    157167        else if (name == "graph")
    158168        {
     
    179189            }
    180190            self->m_active_descriptor = "";
    181191        }
    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         }
    192192
    193193        self->m_character_data.clear();
    194194    }
     
    199199        graphml_reader* self = static_cast<graphml_reader*>(user_data);
    200200
    201201        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|", "");
    205203
    206204        if (name == "data")
    207205        {           
     
    237235            }
    238236            catch (bad_lexical_cast)
    239237            {
    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());
    241243            }
    242244           
    243245            while(id >= m_canonical_vertex.size())
     
    310312
    311313    void handle_property(const std::string& key_id, const variant<std::string,size_t>& descriptor, const std::string& value)
    312314    {
    313         if (get<std::string>(&descriptor))
     315        try
    314316        {
    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            }
    317324            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            }
    319328        }
    320         else
     329        catch (parse_error &e)
    321330        {
    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());
    323336        }
    324337    }
    325338
     
    342355    std::string m_character_data;
    343356    bool m_canonical_vertices;
    344357    bool m_canonical_edges;
     358    XML_Parser m_parser;
    345359};
    346360
    347361namespace boost