lemon/lgf_reader.h
changeset 296 9768e60aa4e1
parent 293 47fbc814aa31
parent 291 d901321d6555
child 295 7c796c1cf1b0
equal deleted inserted replaced
29:d5b4b3f0353d 30:3194d204de78
    46     template <typename Value>
    46     template <typename Value>
    47     struct DefaultConverter {
    47     struct DefaultConverter {
    48       Value operator()(const std::string& str) {
    48       Value operator()(const std::string& str) {
    49         std::istringstream is(str);
    49         std::istringstream is(str);
    50         Value value;
    50         Value value;
    51         is >> value;
    51         if (!(is >> value)) {
       
    52           throw FormatError("Cannot read token");
       
    53         }
    52 
    54 
    53         char c;
    55         char c;
    54         if (is >> std::ws >> c) {
    56         if (is >> std::ws >> c) {
    55           throw DataFormatError("Remaining characters in token");
    57           throw FormatError("Remaining characters in token");
    56         }
    58         }
    57         return value;
    59         return value;
    58       }
    60       }
    59     };
    61     };
    60 
    62 
   164         typename std::map<std::string, Value>::const_iterator it =
   166         typename std::map<std::string, Value>::const_iterator it =
   165           _map.find(str);
   167           _map.find(str);
   166         if (it == _map.end()) {
   168         if (it == _map.end()) {
   167           std::ostringstream msg;
   169           std::ostringstream msg;
   168           msg << "Item not found: " << str;
   170           msg << "Item not found: " << str;
   169           throw DataFormatError(msg.str().c_str());
   171           throw FormatError(msg.str());
   170         }
   172         }
   171         return it->second;
   173         return it->second;
   172       }
   174       }
   173     };
   175     };
   174 
   176 
   182                                              typename Graph::Edge>& map)
   184                                              typename Graph::Edge>& map)
   183         : _graph(graph), _map(map) {}
   185         : _graph(graph), _map(map) {}
   184 
   186 
   185       typename Graph::Arc operator()(const std::string& str) {
   187       typename Graph::Arc operator()(const std::string& str) {
   186         if (str.empty() || (str[0] != '+' && str[0] != '-')) {
   188         if (str.empty() || (str[0] != '+' && str[0] != '-')) {
   187           throw DataFormatError("Item must start with '+' or '-'");
   189           throw FormatError("Item must start with '+' or '-'");
   188         }
   190         }
   189         typename std::map<std::string, typename Graph::Edge>
   191         typename std::map<std::string, typename Graph::Edge>
   190           ::const_iterator it = _map.find(str.substr(1));
   192           ::const_iterator it = _map.find(str.substr(1));
   191         if (it == _map.end()) {
   193         if (it == _map.end()) {
   192           throw DataFormatError("Item not found");
   194           throw FormatError("Item not found");
   193         }
   195         }
   194         return _graph.direct(it->second, str[0] == '+');
   196         return _graph.direct(it->second, str[0] == '+');
   195       }
   197       }
   196     };
   198     };
   197 
   199 
   233     }
   235     }
   234 
   236 
   235     inline char readEscape(std::istream& is) {
   237     inline char readEscape(std::istream& is) {
   236       char c;
   238       char c;
   237       if (!is.get(c))
   239       if (!is.get(c))
   238         throw DataFormatError("Escape format error");
   240         throw FormatError("Escape format error");
   239 
   241 
   240       switch (c) {
   242       switch (c) {
   241       case '\\':
   243       case '\\':
   242         return '\\';
   244         return '\\';
   243       case '\"':
   245       case '\"':
   262         return '\v';
   264         return '\v';
   263       case 'x':
   265       case 'x':
   264         {
   266         {
   265           int code;
   267           int code;
   266           if (!is.get(c) || !isHex(c))
   268           if (!is.get(c) || !isHex(c))
   267             throw DataFormatError("Escape format error");
   269             throw FormatError("Escape format error");
   268           else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   270           else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   269           else code = code * 16 + valueHex(c);
   271           else code = code * 16 + valueHex(c);
   270           return code;
   272           return code;
   271         }
   273         }
   272       default:
   274       default:
   273         {
   275         {
   274           int code;
   276           int code;
   275           if (!isOct(c))
   277           if (!isOct(c))
   276             throw DataFormatError("Escape format error");
   278             throw FormatError("Escape format error");
   277           else if (code = valueOct(c), !is.get(c) || !isOct(c))
   279           else if (code = valueOct(c), !is.get(c) || !isOct(c))
   278             is.putback(c);
   280             is.putback(c);
   279           else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
   281           else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
   280             is.putback(c);
   282             is.putback(c);
   281           else code = code * 8 + valueOct(c);
   283           else code = code * 8 + valueOct(c);
   298           if (c == '\\')
   300           if (c == '\\')
   299             c = readEscape(is);
   301             c = readEscape(is);
   300           os << c;
   302           os << c;
   301         }
   303         }
   302         if (!is)
   304         if (!is)
   303           throw DataFormatError("Quoted format error");
   305           throw FormatError("Quoted format error");
   304       } else {
   306       } else {
   305         is.putback(c);
   307         is.putback(c);
   306         while (is.get(c) && !isWhiteSpace(c)) {
   308         while (is.get(c) && !isWhiteSpace(c)) {
   307           if (c == '\\')
   309           if (c == '\\')
   308             c = readEscape(is);
   310             c = readEscape(is);
   459   private:
   461   private:
   460 
   462 
   461 
   463 
   462     std::istream* _is;
   464     std::istream* _is;
   463     bool local_is;
   465     bool local_is;
       
   466     std::string _filename;
   464 
   467 
   465     Digraph& _digraph;
   468     Digraph& _digraph;
   466 
   469 
   467     std::string _nodes_caption;
   470     std::string _nodes_caption;
   468     std::string _arcs_caption;
   471     std::string _arcs_caption;
   508     /// \brief Constructor
   511     /// \brief Constructor
   509     ///
   512     ///
   510     /// Construct a directed graph reader, which reads from the given
   513     /// Construct a directed graph reader, which reads from the given
   511     /// file.
   514     /// file.
   512     DigraphReader(Digraph& digraph, const std::string& fn)
   515     DigraphReader(Digraph& digraph, const std::string& fn)
   513       : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   516       : _is(new std::ifstream(fn.c_str())), local_is(true),
       
   517         _filename(fn), _digraph(digraph),
   514         _use_nodes(false), _use_arcs(false),
   518         _use_nodes(false), _use_arcs(false),
   515         _skip_nodes(false), _skip_arcs(false) {}
   519         _skip_nodes(false), _skip_arcs(false) {
       
   520       if (!(*_is)) throw IoError("Cannot open file", fn);
       
   521     }
   516 
   522 
   517     /// \brief Constructor
   523     /// \brief Constructor
   518     ///
   524     ///
   519     /// Construct a directed graph reader, which reads from the given
   525     /// Construct a directed graph reader, which reads from the given
   520     /// file.
   526     /// file.
   521     DigraphReader(Digraph& digraph, const char* fn)
   527     DigraphReader(Digraph& digraph, const char* fn)
   522       : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   528       : _is(new std::ifstream(fn)), local_is(true),
       
   529         _filename(fn), _digraph(digraph),
   523         _use_nodes(false), _use_arcs(false),
   530         _use_nodes(false), _use_arcs(false),
   524         _skip_nodes(false), _skip_arcs(false) {}
   531         _skip_nodes(false), _skip_arcs(false) {
       
   532       if (!(*_is)) throw IoError("Cannot open file", fn);
       
   533     }
   525 
   534 
   526     /// \brief Destructor
   535     /// \brief Destructor
   527     ~DigraphReader() {
   536     ~DigraphReader() {
   528       for (typename NodeMaps::iterator it = _node_maps.begin();
   537       for (typename NodeMaps::iterator it = _node_maps.begin();
   529            it != _node_maps.end(); ++it) {
   538            it != _node_maps.end(); ++it) {
   844 
   853 
   845       char c;
   854       char c;
   846       if (!readLine() || !(line >> c) || c == '@') {
   855       if (!readLine() || !(line >> c) || c == '@') {
   847         if (readSuccess() && line) line.putback(c);
   856         if (readSuccess() && line) line.putback(c);
   848         if (!_node_maps.empty())
   857         if (!_node_maps.empty())
   849           throw DataFormatError("Cannot find map names");
   858           throw FormatError("Cannot find map names");
   850         return;
   859         return;
   851       }
   860       }
   852       line.putback(c);
   861       line.putback(c);
   853 
   862 
   854       {
   863       {
   858         int index = 0;
   867         int index = 0;
   859         while (_reader_bits::readToken(line, map)) {
   868         while (_reader_bits::readToken(line, map)) {
   860           if (maps.find(map) != maps.end()) {
   869           if (maps.find(map) != maps.end()) {
   861             std::ostringstream msg;
   870             std::ostringstream msg;
   862             msg << "Multiple occurence of node map: " << map;
   871             msg << "Multiple occurence of node map: " << map;
   863             throw DataFormatError(msg.str().c_str());
   872             throw FormatError(msg.str());
   864           }
   873           }
   865           maps.insert(std::make_pair(map, index));
   874           maps.insert(std::make_pair(map, index));
   866           ++index;
   875           ++index;
   867         }
   876         }
   868 
   877 
   869         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   878         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   870           std::map<std::string, int>::iterator jt =
   879           std::map<std::string, int>::iterator jt =
   871             maps.find(_node_maps[i].first);
   880             maps.find(_node_maps[i].first);
   872           if (jt == maps.end()) {
   881           if (jt == maps.end()) {
   873             std::ostringstream msg;
   882             std::ostringstream msg;
   874             msg << "Map not found in file: " << _node_maps[i].first;
   883             msg << "Map not found: " << _node_maps[i].first;
   875             throw DataFormatError(msg.str().c_str());
   884             throw FormatError(msg.str());
   876           }
   885           }
   877           map_index[i] = jt->second;
   886           map_index[i] = jt->second;
   878         }
   887         }
   879 
   888 
   880         {
   889         {
   894         std::vector<std::string> tokens(map_num);
   903         std::vector<std::string> tokens(map_num);
   895         for (int i = 0; i < map_num; ++i) {
   904         for (int i = 0; i < map_num; ++i) {
   896           if (!_reader_bits::readToken(line, tokens[i])) {
   905           if (!_reader_bits::readToken(line, tokens[i])) {
   897             std::ostringstream msg;
   906             std::ostringstream msg;
   898             msg << "Column not found (" << i + 1 << ")";
   907             msg << "Column not found (" << i + 1 << ")";
   899             throw DataFormatError(msg.str().c_str());
   908             throw FormatError(msg.str());
   900           }
   909           }
   901         }
   910         }
   902         if (line >> std::ws >> c)
   911         if (line >> std::ws >> c)
   903           throw DataFormatError("Extra character on the end of line");
   912           throw FormatError("Extra character at the end of line");
   904 
   913 
   905         Node n;
   914         Node n;
   906         if (!_use_nodes) {
   915         if (!_use_nodes) {
   907           n = _digraph.addNode();
   916           n = _digraph.addNode();
   908           if (label_index != -1)
   917           if (label_index != -1)
   909             _node_index.insert(std::make_pair(tokens[label_index], n));
   918             _node_index.insert(std::make_pair(tokens[label_index], n));
   910         } else {
   919         } else {
   911           if (label_index == -1)
   920           if (label_index == -1)
   912             throw DataFormatError("Label map not found in file");
   921             throw FormatError("Label map not found");
   913           typename std::map<std::string, Node>::iterator it =
   922           typename std::map<std::string, Node>::iterator it =
   914             _node_index.find(tokens[label_index]);
   923             _node_index.find(tokens[label_index]);
   915           if (it == _node_index.end()) {
   924           if (it == _node_index.end()) {
   916             std::ostringstream msg;
   925             std::ostringstream msg;
   917             msg << "Node with label not found: " << tokens[label_index];
   926             msg << "Node with label not found: " << tokens[label_index];
   918             throw DataFormatError(msg.str().c_str());
   927             throw FormatError(msg.str());
   919           }
   928           }
   920           n = it->second;
   929           n = it->second;
   921         }
   930         }
   922 
   931 
   923         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   932         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   937 
   946 
   938       char c;
   947       char c;
   939       if (!readLine() || !(line >> c) || c == '@') {
   948       if (!readLine() || !(line >> c) || c == '@') {
   940         if (readSuccess() && line) line.putback(c);
   949         if (readSuccess() && line) line.putback(c);
   941         if (!_arc_maps.empty())
   950         if (!_arc_maps.empty())
   942           throw DataFormatError("Cannot find map names");
   951           throw FormatError("Cannot find map names");
   943         return;
   952         return;
   944       }
   953       }
   945       line.putback(c);
   954       line.putback(c);
   946 
   955 
   947       {
   956       {
   951         int index = 0;
   960         int index = 0;
   952         while (_reader_bits::readToken(line, map)) {
   961         while (_reader_bits::readToken(line, map)) {
   953           if (maps.find(map) != maps.end()) {
   962           if (maps.find(map) != maps.end()) {
   954             std::ostringstream msg;
   963             std::ostringstream msg;
   955             msg << "Multiple occurence of arc map: " << map;
   964             msg << "Multiple occurence of arc map: " << map;
   956             throw DataFormatError(msg.str().c_str());
   965             throw FormatError(msg.str());
   957           }
   966           }
   958           maps.insert(std::make_pair(map, index));
   967           maps.insert(std::make_pair(map, index));
   959           ++index;
   968           ++index;
   960         }
   969         }
   961 
   970 
   962         for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
   971         for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
   963           std::map<std::string, int>::iterator jt =
   972           std::map<std::string, int>::iterator jt =
   964             maps.find(_arc_maps[i].first);
   973             maps.find(_arc_maps[i].first);
   965           if (jt == maps.end()) {
   974           if (jt == maps.end()) {
   966             std::ostringstream msg;
   975             std::ostringstream msg;
   967             msg << "Map not found in file: " << _arc_maps[i].first;
   976             msg << "Map not found: " << _arc_maps[i].first;
   968             throw DataFormatError(msg.str().c_str());
   977             throw FormatError(msg.str());
   969           }
   978           }
   970           map_index[i] = jt->second;
   979           map_index[i] = jt->second;
   971         }
   980         }
   972 
   981 
   973         {
   982         {
   986 
   995 
   987         std::string source_token;
   996         std::string source_token;
   988         std::string target_token;
   997         std::string target_token;
   989 
   998 
   990         if (!_reader_bits::readToken(line, source_token))
   999         if (!_reader_bits::readToken(line, source_token))
   991           throw DataFormatError("Source not found");
  1000           throw FormatError("Source not found");
   992 
  1001 
   993         if (!_reader_bits::readToken(line, target_token))
  1002         if (!_reader_bits::readToken(line, target_token))
   994           throw DataFormatError("Target not found");
  1003           throw FormatError("Target not found");
   995 
  1004 
   996         std::vector<std::string> tokens(map_num);
  1005         std::vector<std::string> tokens(map_num);
   997         for (int i = 0; i < map_num; ++i) {
  1006         for (int i = 0; i < map_num; ++i) {
   998           if (!_reader_bits::readToken(line, tokens[i])) {
  1007           if (!_reader_bits::readToken(line, tokens[i])) {
   999             std::ostringstream msg;
  1008             std::ostringstream msg;
  1000             msg << "Column not found (" << i + 1 << ")";
  1009             msg << "Column not found (" << i + 1 << ")";
  1001             throw DataFormatError(msg.str().c_str());
  1010             throw FormatError(msg.str());
  1002           }
  1011           }
  1003         }
  1012         }
  1004         if (line >> std::ws >> c)
  1013         if (line >> std::ws >> c)
  1005           throw DataFormatError("Extra character on the end of line");
  1014           throw FormatError("Extra character at the end of line");
  1006 
  1015 
  1007         Arc a;
  1016         Arc a;
  1008         if (!_use_arcs) {
  1017         if (!_use_arcs) {
  1009 
  1018 
  1010           typename NodeIndex::iterator it;
  1019           typename NodeIndex::iterator it;
  1011 
  1020 
  1012           it = _node_index.find(source_token);
  1021           it = _node_index.find(source_token);
  1013           if (it == _node_index.end()) {
  1022           if (it == _node_index.end()) {
  1014             std::ostringstream msg;
  1023             std::ostringstream msg;
  1015             msg << "Item not found: " << source_token;
  1024             msg << "Item not found: " << source_token;
  1016             throw DataFormatError(msg.str().c_str());
  1025             throw FormatError(msg.str());
  1017           }
  1026           }
  1018           Node source = it->second;
  1027           Node source = it->second;
  1019 
  1028 
  1020           it = _node_index.find(target_token);
  1029           it = _node_index.find(target_token);
  1021           if (it == _node_index.end()) {
  1030           if (it == _node_index.end()) {
  1022             std::ostringstream msg;
  1031             std::ostringstream msg;
  1023             msg << "Item not found: " << target_token;
  1032             msg << "Item not found: " << target_token;
  1024             throw DataFormatError(msg.str().c_str());
  1033             throw FormatError(msg.str());
  1025           }
  1034           }
  1026           Node target = it->second;
  1035           Node target = it->second;
  1027 
  1036 
  1028           a = _digraph.addArc(source, target);
  1037           a = _digraph.addArc(source, target);
  1029           if (label_index != -1)
  1038           if (label_index != -1)
  1030             _arc_index.insert(std::make_pair(tokens[label_index], a));
  1039             _arc_index.insert(std::make_pair(tokens[label_index], a));
  1031         } else {
  1040         } else {
  1032           if (label_index == -1)
  1041           if (label_index == -1)
  1033             throw DataFormatError("Label map not found in file");
  1042             throw FormatError("Label map not found");
  1034           typename std::map<std::string, Arc>::iterator it =
  1043           typename std::map<std::string, Arc>::iterator it =
  1035             _arc_index.find(tokens[label_index]);
  1044             _arc_index.find(tokens[label_index]);
  1036           if (it == _arc_index.end()) {
  1045           if (it == _arc_index.end()) {
  1037             std::ostringstream msg;
  1046             std::ostringstream msg;
  1038             msg << "Arc with label not found: " << tokens[label_index];
  1047             msg << "Arc with label not found: " << tokens[label_index];
  1039             throw DataFormatError(msg.str().c_str());
  1048             throw FormatError(msg.str());
  1040           }
  1049           }
  1041           a = it->second;
  1050           a = it->second;
  1042         }
  1051         }
  1043 
  1052 
  1044         for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
  1053         for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
  1059       while (readLine() && line >> c && c != '@') {
  1068       while (readLine() && line >> c && c != '@') {
  1060         line.putback(c);
  1069         line.putback(c);
  1061 
  1070 
  1062         std::string attr, token;
  1071         std::string attr, token;
  1063         if (!_reader_bits::readToken(line, attr))
  1072         if (!_reader_bits::readToken(line, attr))
  1064           throw DataFormatError("Attribute name not found");
  1073           throw FormatError("Attribute name not found");
  1065         if (!_reader_bits::readToken(line, token))
  1074         if (!_reader_bits::readToken(line, token))
  1066           throw DataFormatError("Attribute value not found");
  1075           throw FormatError("Attribute value not found");
  1067         if (line >> c)
  1076         if (line >> c)
  1068           throw DataFormatError("Extra character on the end of line");
  1077           throw FormatError("Extra character at the end of line");
  1069 
  1078 
  1070         {
  1079         {
  1071           std::set<std::string>::iterator it = read_attr.find(attr);
  1080           std::set<std::string>::iterator it = read_attr.find(attr);
  1072           if (it != read_attr.end()) {
  1081           if (it != read_attr.end()) {
  1073             std::ostringstream msg;
  1082             std::ostringstream msg;
  1074             msg << "Multiple occurence of attribute " << attr;
  1083             msg << "Multiple occurence of attribute: " << attr;
  1075             throw DataFormatError(msg.str().c_str());
  1084             throw FormatError(msg.str());
  1076           }
  1085           }
  1077           read_attr.insert(attr);
  1086           read_attr.insert(attr);
  1078         }
  1087         }
  1079 
  1088 
  1080         {
  1089         {
  1091       }
  1100       }
  1092       for (typename Attributes::iterator it = _attributes.begin();
  1101       for (typename Attributes::iterator it = _attributes.begin();
  1093            it != _attributes.end(); ++it) {
  1102            it != _attributes.end(); ++it) {
  1094         if (read_attr.find(it->first) == read_attr.end()) {
  1103         if (read_attr.find(it->first) == read_attr.end()) {
  1095           std::ostringstream msg;
  1104           std::ostringstream msg;
  1096           msg << "Attribute not found in file: " << it->first;
  1105           msg << "Attribute not found: " << it->first;
  1097           throw DataFormatError(msg.str().c_str());
  1106           throw FormatError(msg.str());
  1098         }
  1107         }
  1099       }
  1108       }
  1100     }
  1109     }
  1101 
  1110 
  1102   public:
  1111   public:
  1107     /// \brief Start the batch processing
  1116     /// \brief Start the batch processing
  1108     ///
  1117     ///
  1109     /// This function starts the batch processing
  1118     /// This function starts the batch processing
  1110     void run() {
  1119     void run() {
  1111       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
  1120       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
  1112       if (!*_is) {
       
  1113         throw DataFormatError("Cannot find file");
       
  1114       }
       
  1115 
  1121 
  1116       bool nodes_done = _skip_nodes;
  1122       bool nodes_done = _skip_nodes;
  1117       bool arcs_done = _skip_arcs;
  1123       bool arcs_done = _skip_arcs;
  1118       bool attributes_done = false;
  1124       bool attributes_done = false;
  1119 
  1125 
  1128           line >> c;
  1134           line >> c;
  1129           _reader_bits::readToken(line, section);
  1135           _reader_bits::readToken(line, section);
  1130           _reader_bits::readToken(line, caption);
  1136           _reader_bits::readToken(line, caption);
  1131 
  1137 
  1132           if (line >> c)
  1138           if (line >> c)
  1133             throw DataFormatError("Extra character on the end of line");
  1139             throw FormatError("Extra character at the end of line");
  1134 
  1140 
  1135           if (section == "nodes" && !nodes_done) {
  1141           if (section == "nodes" && !nodes_done) {
  1136             if (_nodes_caption.empty() || _nodes_caption == caption) {
  1142             if (_nodes_caption.empty() || _nodes_caption == caption) {
  1137               readNodes();
  1143               readNodes();
  1138               nodes_done = true;
  1144               nodes_done = true;
  1150             }
  1156             }
  1151           } else {
  1157           } else {
  1152             readLine();
  1158             readLine();
  1153             skipSection();
  1159             skipSection();
  1154           }
  1160           }
  1155         } catch (DataFormatError& error) {
  1161         } catch (FormatError& error) {
  1156           error.line(line_num);
  1162           error.line(line_num);
       
  1163           error.file(_filename);
  1157           throw;
  1164           throw;
  1158         }
  1165         }
  1159       }
  1166       }
  1160 
  1167 
  1161       if (!nodes_done) {
  1168       if (!nodes_done) {
  1162         throw DataFormatError("Section @nodes not found");
  1169         throw FormatError("Section @nodes not found");
  1163       }
  1170       }
  1164 
  1171 
  1165       if (!arcs_done) {
  1172       if (!arcs_done) {
  1166         throw DataFormatError("Section @arcs not found");
  1173         throw FormatError("Section @arcs not found");
  1167       }
  1174       }
  1168 
  1175 
  1169       if (!attributes_done && !_attributes.empty()) {
  1176       if (!attributes_done && !_attributes.empty()) {
  1170         throw DataFormatError("Section @attributes not found");
  1177         throw FormatError("Section @attributes not found");
  1171       }
  1178       }
  1172 
  1179 
  1173     }
  1180     }
  1174 
  1181 
  1175     /// @}
  1182     /// @}
  1245 
  1252 
  1246   private:
  1253   private:
  1247 
  1254 
  1248     std::istream* _is;
  1255     std::istream* _is;
  1249     bool local_is;
  1256     bool local_is;
       
  1257     std::string _filename;
  1250 
  1258 
  1251     Graph& _graph;
  1259     Graph& _graph;
  1252 
  1260 
  1253     std::string _nodes_caption;
  1261     std::string _nodes_caption;
  1254     std::string _edges_caption;
  1262     std::string _edges_caption;
  1294     /// \brief Constructor
  1302     /// \brief Constructor
  1295     ///
  1303     ///
  1296     /// Construct an undirected graph reader, which reads from the given
  1304     /// Construct an undirected graph reader, which reads from the given
  1297     /// file.
  1305     /// file.
  1298     GraphReader(Graph& graph, const std::string& fn)
  1306     GraphReader(Graph& graph, const std::string& fn)
  1299       : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
  1307       : _is(new std::ifstream(fn.c_str())), local_is(true),
       
  1308         _filename(fn), _graph(graph),
  1300         _use_nodes(false), _use_edges(false),
  1309         _use_nodes(false), _use_edges(false),
  1301         _skip_nodes(false), _skip_edges(false) {}
  1310         _skip_nodes(false), _skip_edges(false) {
       
  1311       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  1312     }
  1302 
  1313 
  1303     /// \brief Constructor
  1314     /// \brief Constructor
  1304     ///
  1315     ///
  1305     /// Construct an undirected graph reader, which reads from the given
  1316     /// Construct an undirected graph reader, which reads from the given
  1306     /// file.
  1317     /// file.
  1307     GraphReader(Graph& graph, const char* fn)
  1318     GraphReader(Graph& graph, const char* fn)
  1308       : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
  1319       : _is(new std::ifstream(fn)), local_is(true),
       
  1320         _filename(fn), _graph(graph),
  1309         _use_nodes(false), _use_edges(false),
  1321         _use_nodes(false), _use_edges(false),
  1310         _skip_nodes(false), _skip_edges(false) {}
  1322         _skip_nodes(false), _skip_edges(false) {
       
  1323       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  1324     }
  1311 
  1325 
  1312     /// \brief Destructor
  1326     /// \brief Destructor
  1313     ~GraphReader() {
  1327     ~GraphReader() {
  1314       for (typename NodeMaps::iterator it = _node_maps.begin();
  1328       for (typename NodeMaps::iterator it = _node_maps.begin();
  1315            it != _node_maps.end(); ++it) {
  1329            it != _node_maps.end(); ++it) {
  1674 
  1688 
  1675       char c;
  1689       char c;
  1676       if (!readLine() || !(line >> c) || c == '@') {
  1690       if (!readLine() || !(line >> c) || c == '@') {
  1677         if (readSuccess() && line) line.putback(c);
  1691         if (readSuccess() && line) line.putback(c);
  1678         if (!_node_maps.empty())
  1692         if (!_node_maps.empty())
  1679           throw DataFormatError("Cannot find map names");
  1693           throw FormatError("Cannot find map names");
  1680         return;
  1694         return;
  1681       }
  1695       }
  1682       line.putback(c);
  1696       line.putback(c);
  1683 
  1697 
  1684       {
  1698       {
  1688         int index = 0;
  1702         int index = 0;
  1689         while (_reader_bits::readToken(line, map)) {
  1703         while (_reader_bits::readToken(line, map)) {
  1690           if (maps.find(map) != maps.end()) {
  1704           if (maps.find(map) != maps.end()) {
  1691             std::ostringstream msg;
  1705             std::ostringstream msg;
  1692             msg << "Multiple occurence of node map: " << map;
  1706             msg << "Multiple occurence of node map: " << map;
  1693             throw DataFormatError(msg.str().c_str());
  1707             throw FormatError(msg.str());
  1694           }
  1708           }
  1695           maps.insert(std::make_pair(map, index));
  1709           maps.insert(std::make_pair(map, index));
  1696           ++index;
  1710           ++index;
  1697         }
  1711         }
  1698 
  1712 
  1699         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1713         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1700           std::map<std::string, int>::iterator jt =
  1714           std::map<std::string, int>::iterator jt =
  1701             maps.find(_node_maps[i].first);
  1715             maps.find(_node_maps[i].first);
  1702           if (jt == maps.end()) {
  1716           if (jt == maps.end()) {
  1703             std::ostringstream msg;
  1717             std::ostringstream msg;
  1704             msg << "Map not found in file: " << _node_maps[i].first;
  1718             msg << "Map not found: " << _node_maps[i].first;
  1705             throw DataFormatError(msg.str().c_str());
  1719             throw FormatError(msg.str());
  1706           }
  1720           }
  1707           map_index[i] = jt->second;
  1721           map_index[i] = jt->second;
  1708         }
  1722         }
  1709 
  1723 
  1710         {
  1724         {
  1724         std::vector<std::string> tokens(map_num);
  1738         std::vector<std::string> tokens(map_num);
  1725         for (int i = 0; i < map_num; ++i) {
  1739         for (int i = 0; i < map_num; ++i) {
  1726           if (!_reader_bits::readToken(line, tokens[i])) {
  1740           if (!_reader_bits::readToken(line, tokens[i])) {
  1727             std::ostringstream msg;
  1741             std::ostringstream msg;
  1728             msg << "Column not found (" << i + 1 << ")";
  1742             msg << "Column not found (" << i + 1 << ")";
  1729             throw DataFormatError(msg.str().c_str());
  1743             throw FormatError(msg.str());
  1730           }
  1744           }
  1731         }
  1745         }
  1732         if (line >> std::ws >> c)
  1746         if (line >> std::ws >> c)
  1733           throw DataFormatError("Extra character on the end of line");
  1747           throw FormatError("Extra character at the end of line");
  1734 
  1748 
  1735         Node n;
  1749         Node n;
  1736         if (!_use_nodes) {
  1750         if (!_use_nodes) {
  1737           n = _graph.addNode();
  1751           n = _graph.addNode();
  1738           if (label_index != -1)
  1752           if (label_index != -1)
  1739             _node_index.insert(std::make_pair(tokens[label_index], n));
  1753             _node_index.insert(std::make_pair(tokens[label_index], n));
  1740         } else {
  1754         } else {
  1741           if (label_index == -1)
  1755           if (label_index == -1)
  1742             throw DataFormatError("Label map not found in file");
  1756             throw FormatError("Label map not found");
  1743           typename std::map<std::string, Node>::iterator it =
  1757           typename std::map<std::string, Node>::iterator it =
  1744             _node_index.find(tokens[label_index]);
  1758             _node_index.find(tokens[label_index]);
  1745           if (it == _node_index.end()) {
  1759           if (it == _node_index.end()) {
  1746             std::ostringstream msg;
  1760             std::ostringstream msg;
  1747             msg << "Node with label not found: " << tokens[label_index];
  1761             msg << "Node with label not found: " << tokens[label_index];
  1748             throw DataFormatError(msg.str().c_str());
  1762             throw FormatError(msg.str());
  1749           }
  1763           }
  1750           n = it->second;
  1764           n = it->second;
  1751         }
  1765         }
  1752 
  1766 
  1753         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1767         for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
  1767 
  1781 
  1768       char c;
  1782       char c;
  1769       if (!readLine() || !(line >> c) || c == '@') {
  1783       if (!readLine() || !(line >> c) || c == '@') {
  1770         if (readSuccess() && line) line.putback(c);
  1784         if (readSuccess() && line) line.putback(c);
  1771         if (!_edge_maps.empty())
  1785         if (!_edge_maps.empty())
  1772           throw DataFormatError("Cannot find map names");
  1786           throw FormatError("Cannot find map names");
  1773         return;
  1787         return;
  1774       }
  1788       }
  1775       line.putback(c);
  1789       line.putback(c);
  1776 
  1790 
  1777       {
  1791       {
  1781         int index = 0;
  1795         int index = 0;
  1782         while (_reader_bits::readToken(line, map)) {
  1796         while (_reader_bits::readToken(line, map)) {
  1783           if (maps.find(map) != maps.end()) {
  1797           if (maps.find(map) != maps.end()) {
  1784             std::ostringstream msg;
  1798             std::ostringstream msg;
  1785             msg << "Multiple occurence of edge map: " << map;
  1799             msg << "Multiple occurence of edge map: " << map;
  1786             throw DataFormatError(msg.str().c_str());
  1800             throw FormatError(msg.str());
  1787           }
  1801           }
  1788           maps.insert(std::make_pair(map, index));
  1802           maps.insert(std::make_pair(map, index));
  1789           ++index;
  1803           ++index;
  1790         }
  1804         }
  1791 
  1805 
  1792         for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  1806         for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  1793           std::map<std::string, int>::iterator jt =
  1807           std::map<std::string, int>::iterator jt =
  1794             maps.find(_edge_maps[i].first);
  1808             maps.find(_edge_maps[i].first);
  1795           if (jt == maps.end()) {
  1809           if (jt == maps.end()) {
  1796             std::ostringstream msg;
  1810             std::ostringstream msg;
  1797             msg << "Map not found in file: " << _edge_maps[i].first;
  1811             msg << "Map not found: " << _edge_maps[i].first;
  1798             throw DataFormatError(msg.str().c_str());
  1812             throw FormatError(msg.str());
  1799           }
  1813           }
  1800           map_index[i] = jt->second;
  1814           map_index[i] = jt->second;
  1801         }
  1815         }
  1802 
  1816 
  1803         {
  1817         {
  1816 
  1830 
  1817         std::string source_token;
  1831         std::string source_token;
  1818         std::string target_token;
  1832         std::string target_token;
  1819 
  1833 
  1820         if (!_reader_bits::readToken(line, source_token))
  1834         if (!_reader_bits::readToken(line, source_token))
  1821           throw DataFormatError("Node u not found");
  1835           throw FormatError("Node u not found");
  1822 
  1836 
  1823         if (!_reader_bits::readToken(line, target_token))
  1837         if (!_reader_bits::readToken(line, target_token))
  1824           throw DataFormatError("Node v not found");
  1838           throw FormatError("Node v not found");
  1825 
  1839 
  1826         std::vector<std::string> tokens(map_num);
  1840         std::vector<std::string> tokens(map_num);
  1827         for (int i = 0; i < map_num; ++i) {
  1841         for (int i = 0; i < map_num; ++i) {
  1828           if (!_reader_bits::readToken(line, tokens[i])) {
  1842           if (!_reader_bits::readToken(line, tokens[i])) {
  1829             std::ostringstream msg;
  1843             std::ostringstream msg;
  1830             msg << "Column not found (" << i + 1 << ")";
  1844             msg << "Column not found (" << i + 1 << ")";
  1831             throw DataFormatError(msg.str().c_str());
  1845             throw FormatError(msg.str());
  1832           }
  1846           }
  1833         }
  1847         }
  1834         if (line >> std::ws >> c)
  1848         if (line >> std::ws >> c)
  1835           throw DataFormatError("Extra character on the end of line");
  1849           throw FormatError("Extra character at the end of line");
  1836 
  1850 
  1837         Edge e;
  1851         Edge e;
  1838         if (!_use_edges) {
  1852         if (!_use_edges) {
  1839 
  1853 
  1840           typename NodeIndex::iterator it;
  1854           typename NodeIndex::iterator it;
  1841 
  1855 
  1842           it = _node_index.find(source_token);
  1856           it = _node_index.find(source_token);
  1843           if (it == _node_index.end()) {
  1857           if (it == _node_index.end()) {
  1844             std::ostringstream msg;
  1858             std::ostringstream msg;
  1845             msg << "Item not found: " << source_token;
  1859             msg << "Item not found: " << source_token;
  1846             throw DataFormatError(msg.str().c_str());
  1860             throw FormatError(msg.str());
  1847           }
  1861           }
  1848           Node source = it->second;
  1862           Node source = it->second;
  1849 
  1863 
  1850           it = _node_index.find(target_token);
  1864           it = _node_index.find(target_token);
  1851           if (it == _node_index.end()) {
  1865           if (it == _node_index.end()) {
  1852             std::ostringstream msg;
  1866             std::ostringstream msg;
  1853             msg << "Item not found: " << target_token;
  1867             msg << "Item not found: " << target_token;
  1854             throw DataFormatError(msg.str().c_str());
  1868             throw FormatError(msg.str());
  1855           }
  1869           }
  1856           Node target = it->second;
  1870           Node target = it->second;
  1857 
  1871 
  1858           e = _graph.addEdge(source, target);
  1872           e = _graph.addEdge(source, target);
  1859           if (label_index != -1)
  1873           if (label_index != -1)
  1860             _edge_index.insert(std::make_pair(tokens[label_index], e));
  1874             _edge_index.insert(std::make_pair(tokens[label_index], e));
  1861         } else {
  1875         } else {
  1862           if (label_index == -1)
  1876           if (label_index == -1)
  1863             throw DataFormatError("Label map not found in file");
  1877             throw FormatError("Label map not found");
  1864           typename std::map<std::string, Edge>::iterator it =
  1878           typename std::map<std::string, Edge>::iterator it =
  1865             _edge_index.find(tokens[label_index]);
  1879             _edge_index.find(tokens[label_index]);
  1866           if (it == _edge_index.end()) {
  1880           if (it == _edge_index.end()) {
  1867             std::ostringstream msg;
  1881             std::ostringstream msg;
  1868             msg << "Edge with label not found: " << tokens[label_index];
  1882             msg << "Edge with label not found: " << tokens[label_index];
  1869             throw DataFormatError(msg.str().c_str());
  1883             throw FormatError(msg.str());
  1870           }
  1884           }
  1871           e = it->second;
  1885           e = it->second;
  1872         }
  1886         }
  1873 
  1887 
  1874         for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  1888         for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
  1889       while (readLine() && line >> c && c != '@') {
  1903       while (readLine() && line >> c && c != '@') {
  1890         line.putback(c);
  1904         line.putback(c);
  1891 
  1905 
  1892         std::string attr, token;
  1906         std::string attr, token;
  1893         if (!_reader_bits::readToken(line, attr))
  1907         if (!_reader_bits::readToken(line, attr))
  1894           throw DataFormatError("Attribute name not found");
  1908           throw FormatError("Attribute name not found");
  1895         if (!_reader_bits::readToken(line, token))
  1909         if (!_reader_bits::readToken(line, token))
  1896           throw DataFormatError("Attribute value not found");
  1910           throw FormatError("Attribute value not found");
  1897         if (line >> c)
  1911         if (line >> c)
  1898           throw DataFormatError("Extra character on the end of line");
  1912           throw FormatError("Extra character at the end of line");
  1899 
  1913 
  1900         {
  1914         {
  1901           std::set<std::string>::iterator it = read_attr.find(attr);
  1915           std::set<std::string>::iterator it = read_attr.find(attr);
  1902           if (it != read_attr.end()) {
  1916           if (it != read_attr.end()) {
  1903             std::ostringstream msg;
  1917             std::ostringstream msg;
  1904             msg << "Multiple occurence of attribute " << attr;
  1918             msg << "Multiple occurence of attribute: " << attr;
  1905             throw DataFormatError(msg.str().c_str());
  1919             throw FormatError(msg.str());
  1906           }
  1920           }
  1907           read_attr.insert(attr);
  1921           read_attr.insert(attr);
  1908         }
  1922         }
  1909 
  1923 
  1910         {
  1924         {
  1921       }
  1935       }
  1922       for (typename Attributes::iterator it = _attributes.begin();
  1936       for (typename Attributes::iterator it = _attributes.begin();
  1923            it != _attributes.end(); ++it) {
  1937            it != _attributes.end(); ++it) {
  1924         if (read_attr.find(it->first) == read_attr.end()) {
  1938         if (read_attr.find(it->first) == read_attr.end()) {
  1925           std::ostringstream msg;
  1939           std::ostringstream msg;
  1926           msg << "Attribute not found in file: " << it->first;
  1940           msg << "Attribute not found: " << it->first;
  1927           throw DataFormatError(msg.str().c_str());
  1941           throw FormatError(msg.str());
  1928         }
  1942         }
  1929       }
  1943       }
  1930     }
  1944     }
  1931 
  1945 
  1932   public:
  1946   public:
  1956           line >> c;
  1970           line >> c;
  1957           _reader_bits::readToken(line, section);
  1971           _reader_bits::readToken(line, section);
  1958           _reader_bits::readToken(line, caption);
  1972           _reader_bits::readToken(line, caption);
  1959 
  1973 
  1960           if (line >> c)
  1974           if (line >> c)
  1961             throw DataFormatError("Extra character on the end of line");
  1975             throw FormatError("Extra character at the end of line");
  1962 
  1976 
  1963           if (section == "nodes" && !nodes_done) {
  1977           if (section == "nodes" && !nodes_done) {
  1964             if (_nodes_caption.empty() || _nodes_caption == caption) {
  1978             if (_nodes_caption.empty() || _nodes_caption == caption) {
  1965               readNodes();
  1979               readNodes();
  1966               nodes_done = true;
  1980               nodes_done = true;
  1978             }
  1992             }
  1979           } else {
  1993           } else {
  1980             readLine();
  1994             readLine();
  1981             skipSection();
  1995             skipSection();
  1982           }
  1996           }
  1983         } catch (DataFormatError& error) {
  1997         } catch (FormatError& error) {
  1984           error.line(line_num);
  1998           error.line(line_num);
       
  1999           error.file(_filename);
  1985           throw;
  2000           throw;
  1986         }
  2001         }
  1987       }
  2002       }
  1988 
  2003 
  1989       if (!nodes_done) {
  2004       if (!nodes_done) {
  1990         throw DataFormatError("Section @nodes not found");
  2005         throw FormatError("Section @nodes not found");
  1991       }
  2006       }
  1992 
  2007 
  1993       if (!edges_done) {
  2008       if (!edges_done) {
  1994         throw DataFormatError("Section @edges not found");
  2009         throw FormatError("Section @edges not found");
  1995       }
  2010       }
  1996 
  2011 
  1997       if (!attributes_done && !_attributes.empty()) {
  2012       if (!attributes_done && !_attributes.empty()) {
  1998         throw DataFormatError("Section @attributes not found");
  2013         throw FormatError("Section @attributes not found");
  1999       }
  2014       }
  2000 
  2015 
  2001     }
  2016     }
  2002 
  2017 
  2003     /// @}
  2018     /// @}
  2054   class SectionReader {
  2069   class SectionReader {
  2055   private:
  2070   private:
  2056 
  2071 
  2057     std::istream* _is;
  2072     std::istream* _is;
  2058     bool local_is;
  2073     bool local_is;
       
  2074     std::string _filename;
  2059 
  2075 
  2060     typedef std::map<std::string, _reader_bits::Section*> Sections;
  2076     typedef std::map<std::string, _reader_bits::Section*> Sections;
  2061     Sections _sections;
  2077     Sections _sections;
  2062 
  2078 
  2063     int line_num;
  2079     int line_num;
  2074 
  2090 
  2075     /// \brief Constructor
  2091     /// \brief Constructor
  2076     ///
  2092     ///
  2077     /// Construct a section reader, which reads from the given file.
  2093     /// Construct a section reader, which reads from the given file.
  2078     SectionReader(const std::string& fn)
  2094     SectionReader(const std::string& fn)
  2079       : _is(new std::ifstream(fn.c_str())), local_is(true) {}
  2095       : _is(new std::ifstream(fn.c_str())), local_is(true),
       
  2096         _filename(fn) {
       
  2097       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  2098     }
  2080 
  2099 
  2081     /// \brief Constructor
  2100     /// \brief Constructor
  2082     ///
  2101     ///
  2083     /// Construct a section reader, which reads from the given file.
  2102     /// Construct a section reader, which reads from the given file.
  2084     SectionReader(const char* fn)
  2103     SectionReader(const char* fn)
  2085       : _is(new std::ifstream(fn)), local_is(true) {}
  2104       : _is(new std::ifstream(fn)), local_is(true),
       
  2105         _filename(fn) {
       
  2106       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  2107     }
  2086 
  2108 
  2087     /// \brief Destructor
  2109     /// \brief Destructor
  2088     ~SectionReader() {
  2110     ~SectionReader() {
  2089       for (Sections::iterator it = _sections.begin();
  2111       for (Sections::iterator it = _sections.begin();
  2090            it != _sections.end(); ++it) {
  2112            it != _sections.end(); ++it) {
  2236           line >> c;
  2258           line >> c;
  2237           _reader_bits::readToken(line, section);
  2259           _reader_bits::readToken(line, section);
  2238           _reader_bits::readToken(line, caption);
  2260           _reader_bits::readToken(line, caption);
  2239 
  2261 
  2240           if (line >> c)
  2262           if (line >> c)
  2241             throw DataFormatError("Extra character on the end of line");
  2263             throw FormatError("Extra character at the end of line");
  2242 
  2264 
  2243           if (extra_sections.find(section) != extra_sections.end()) {
  2265           if (extra_sections.find(section) != extra_sections.end()) {
  2244             std::ostringstream msg;
  2266             std::ostringstream msg;
  2245             msg << "Multiple occurence of section " << section;
  2267             msg << "Multiple occurence of section: " << section;
  2246             throw DataFormatError(msg.str().c_str());
  2268             throw FormatError(msg.str());
  2247           }
  2269           }
  2248           Sections::iterator it = _sections.find(section);
  2270           Sections::iterator it = _sections.find(section);
  2249           if (it != _sections.end()) {
  2271           if (it != _sections.end()) {
  2250             extra_sections.insert(section);
  2272             extra_sections.insert(section);
  2251             it->second->process(*_is, line_num);
  2273             it->second->process(*_is, line_num);
  2252           }
  2274           }
  2253           readLine();
  2275           readLine();
  2254           skipSection();
  2276           skipSection();
  2255         } catch (DataFormatError& error) {
  2277         } catch (FormatError& error) {
  2256           error.line(line_num);
  2278           error.line(line_num);
       
  2279           error.file(_filename);
  2257           throw;
  2280           throw;
  2258         }
  2281         }
  2259       }
  2282       }
  2260       for (Sections::iterator it = _sections.begin();
  2283       for (Sections::iterator it = _sections.begin();
  2261            it != _sections.end(); ++it) {
  2284            it != _sections.end(); ++it) {
  2262         if (extra_sections.find(it->first) == extra_sections.end()) {
  2285         if (extra_sections.find(it->first) == extra_sections.end()) {
  2263           std::ostringstream os;
  2286           std::ostringstream os;
  2264           os << "Cannot find section: " << it->first;
  2287           os << "Cannot find section: " << it->first;
  2265           throw DataFormatError(os.str().c_str());
  2288           throw FormatError(os.str());
  2266         }
  2289         }
  2267       }
  2290       }
  2268     }
  2291     }
  2269 
  2292 
  2270     /// @}
  2293     /// @}
  2360     /// \brief Constructor
  2383     /// \brief Constructor
  2361     ///
  2384     ///
  2362     /// Construct an \e LGF contents reader, which reads from the given
  2385     /// Construct an \e LGF contents reader, which reads from the given
  2363     /// file.
  2386     /// file.
  2364     LgfContents(const std::string& fn)
  2387     LgfContents(const std::string& fn)
  2365       : _is(new std::ifstream(fn.c_str())), local_is(true) {}
  2388       : _is(new std::ifstream(fn.c_str())), local_is(true) {
       
  2389       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  2390     }
  2366 
  2391 
  2367     /// \brief Constructor
  2392     /// \brief Constructor
  2368     ///
  2393     ///
  2369     /// Construct an \e LGF contents reader, which reads from the given
  2394     /// Construct an \e LGF contents reader, which reads from the given
  2370     /// file.
  2395     /// file.
  2371     LgfContents(const char* fn)
  2396     LgfContents(const char* fn)
  2372       : _is(new std::ifstream(fn)), local_is(true) {}
  2397       : _is(new std::ifstream(fn)), local_is(true) {
       
  2398       if (!(*_is)) throw IoError("Cannot open file", fn);
       
  2399     }
  2373 
  2400 
  2374     /// \brief Destructor
  2401     /// \brief Destructor
  2375     ~LgfContents() {
  2402     ~LgfContents() {
  2376       if (local_is) delete _is;
  2403       if (local_is) delete _is;
  2377     }
  2404     }