3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Graph Format reader.
24 #ifndef LEMON_LGF_READER_H
25 #define LEMON_LGF_READER_H
34 #include <lemon/assert.h>
35 #include <lemon/graph_utils.h>
37 #include <lemon/lgf_writer.h>
39 #include <lemon/concept_check.h>
40 #include <lemon/concepts/maps.h>
44 namespace _reader_bits {
46 template <typename Value>
47 struct DefaultConverter {
48 Value operator()(const std::string& str) {
49 std::istringstream is(str);
54 if (is >> std::ws >> c) {
55 throw DataFormatError("Remaining characters in token");
62 struct DefaultConverter<std::string> {
63 std::string operator()(const std::string& str) {
68 template <typename _Item>
69 class MapStorageBase {
75 virtual ~MapStorageBase() {}
77 virtual void set(const Item& item, const std::string& value) = 0;
81 template <typename _Item, typename _Map,
82 typename _Converter = DefaultConverter<typename _Map::Value> >
83 class MapStorage : public MapStorageBase<_Item> {
86 typedef _Converter Converter;
94 MapStorage(Map& map, const Converter& converter = Converter())
95 : _map(map), _converter(converter) {}
96 virtual ~MapStorage() {}
98 virtual void set(const Item& item ,const std::string& value) {
99 _map.set(item, _converter(value));
103 class ValueStorageBase {
105 ValueStorageBase() {}
106 virtual ~ValueStorageBase() {}
108 virtual void set(const std::string&) = 0;
111 template <typename _Value, typename _Converter = DefaultConverter<_Value> >
112 class ValueStorage : public ValueStorageBase {
114 typedef _Value Value;
115 typedef _Converter Converter;
119 Converter _converter;
122 ValueStorage(Value& value, const Converter& converter = Converter())
123 : _value(value), _converter(converter) {}
125 virtual void set(const std::string& value) {
126 _value = _converter(value);
130 template <typename Value>
131 struct MapLookUpConverter {
132 const std::map<std::string, Value>& _map;
134 MapLookUpConverter(const std::map<std::string, Value>& map)
137 Value operator()(const std::string& str) {
138 typename std::map<std::string, Value>::const_iterator it =
140 if (it == _map.end()) {
141 std::ostringstream msg;
142 msg << "Item not found: " << str;
143 throw DataFormatError(msg.str().c_str());
149 bool isWhiteSpace(char c) {
150 return c == ' ' || c == '\t' || c == '\v' ||
151 c == '\n' || c == '\r' || c == '\f';
155 return '0' <= c && c <='7';
158 int valueOct(char c) {
159 LEMON_ASSERT(isOct(c), "The character is not octal.");
164 return ('0' <= c && c <= '9') ||
165 ('a' <= c && c <= 'z') ||
166 ('A' <= c && c <= 'Z');
169 int valueHex(char c) {
170 LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
171 if ('0' <= c && c <= '9') return c - '0';
172 if ('a' <= c && c <= 'z') return c - 'a' + 10;
176 bool isIdentifierFirstChar(char c) {
177 return ('a' <= c && c <= 'z') ||
178 ('A' <= c && c <= 'Z') || c == '_';
181 bool isIdentifierChar(char c) {
182 return isIdentifierFirstChar(c) ||
183 ('0' <= c && c <= '9');
186 char readEscape(std::istream& is) {
189 throw DataFormatError("Escape format error");
217 if (!is.get(c) || !isHex(c))
218 throw DataFormatError("Escape format error");
219 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
220 else code = code * 16 + valueHex(c);
227 throw DataFormatError("Escape format error");
228 else if (code = valueOct(c), !is.get(c) || !isOct(c))
230 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
232 else code = code * 8 + valueOct(c);
238 std::istream& readToken(std::istream& is, std::string& str) {
239 std::ostringstream os;
248 while (is.get(c) && c != '\"') {
254 throw DataFormatError("Quoted format error");
257 while (is.get(c) && !isWhiteSpace(c)) {
272 std::istream& readIdentifier(std::istream& is, std::string& str) {
273 std::ostringstream os;
281 if (!isIdentifierFirstChar(c))
282 throw DataFormatError("Wrong char in identifier");
286 while (is.get(c) && !isWhiteSpace(c)) {
287 if (!isIdentifierChar(c))
288 throw DataFormatError("Wrong char in identifier");
300 template <typename _Digraph>
301 class DigraphReader {
304 typedef _Digraph Digraph;
305 GRAPH_TYPEDEFS(typename Digraph);
315 std::string _nodes_caption;
316 std::string _arcs_caption;
317 std::string _attributes_caption;
319 typedef std::map<std::string, Node> NodeIndex;
320 NodeIndex _node_index;
321 typedef std::map<std::string, Arc> ArcIndex;
324 typedef std::vector<std::pair<std::string,
325 _reader_bits::MapStorageBase<Node>*> > NodeMaps;
328 typedef std::vector<std::pair<std::string,
329 _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
332 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
334 Attributes _attributes;
340 std::istringstream line;
345 DigraphReader(std::istream& is, Digraph& digraph)
346 : _is(&is), local_is(false), _digraph(digraph),
347 _use_nodes(false), _use_arcs(false) {}
350 DigraphReader(const std::string& fn, Digraph& digraph)
351 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
352 _use_nodes(false), _use_arcs(false) {}
356 DigraphReader(const char* fn, Digraph& digraph)
357 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
358 _use_nodes(false), _use_arcs(false) {}
361 DigraphReader(DigraphReader& other)
362 : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
363 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
366 other.local_is = false;
368 _node_index.swap(other._node_index);
369 _arc_index.swap(other._arc_index);
371 _node_maps.swap(other._node_maps);
372 _arc_maps.swap(other._arc_maps);
373 _attributes.swap(other._attributes);
375 _nodes_caption = other._nodes_caption;
376 _arcs_caption = other._arcs_caption;
377 _attributes_caption = other._attributes_caption;
382 for (typename NodeMaps::iterator it = _node_maps.begin();
383 it != _node_maps.end(); ++it) {
387 for (typename ArcMaps::iterator it = _arc_maps.begin();
388 it != _arc_maps.end(); ++it) {
392 for (typename Attributes::iterator it = _attributes.begin();
393 it != _attributes.end(); ++it) {
405 DigraphReader& operator=(const DigraphReader&);
410 template <typename Map>
411 DigraphReader& nodeMap(const std::string& caption, Map& map) {
412 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
413 _reader_bits::MapStorageBase<Node>* storage =
414 new _reader_bits::MapStorage<Node, Map>(map);
415 _node_maps.push_back(std::make_pair(caption, storage));
420 template <typename Map, typename Converter>
421 DigraphReader& nodeMap(const std::string& caption, Map& map,
422 const Converter& converter = Converter()) {
423 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
424 _reader_bits::MapStorageBase<Node>* storage =
425 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
426 _node_maps.push_back(std::make_pair(caption, storage));
431 template <typename Map>
432 DigraphReader& arcMap(const std::string& caption, Map& map) {
433 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
434 _reader_bits::MapStorageBase<Arc>* storage =
435 new _reader_bits::MapStorage<Arc, Map>(map);
436 _arc_maps.push_back(std::make_pair(caption, storage));
441 template <typename Map, typename Converter>
442 DigraphReader& arcMap(const std::string& caption, Map& map,
443 const Converter& converter = Converter()) {
444 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
445 _reader_bits::MapStorageBase<Arc>* storage =
446 new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
447 _arc_maps.push_back(std::make_pair(caption, storage));
452 template <typename Value>
453 DigraphReader& attribute(const std::string& caption, Value& value) {
454 _reader_bits::ValueStorageBase* storage =
455 new _reader_bits::ValueStorage<Value>(value);
456 _attributes.insert(std::make_pair(caption, storage));
461 template <typename Value, typename Converter>
462 DigraphReader& attribute(const std::string& caption, Value& value,
463 const Converter& converter = Converter()) {
464 _reader_bits::ValueStorageBase* storage =
465 new _reader_bits::ValueStorage<Value, Converter>(value, converter);
466 _attributes.insert(std::make_pair(caption, storage));
471 DigraphReader& node(const std::string& caption, Node& node) {
472 typedef _reader_bits::MapLookUpConverter<Node> Converter;
473 Converter converter(_node_index);
474 _reader_bits::ValueStorageBase* storage =
475 new _reader_bits::ValueStorage<Node, Converter>(node, converter);
476 _attributes.insert(std::make_pair(caption, storage));
481 DigraphReader& arc(const std::string& caption, Arc& arc) {
482 typedef _reader_bits::MapLookUpConverter<Arc> Converter;
483 Converter converter(_arc_index);
484 _reader_bits::ValueStorageBase* storage =
485 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
486 _attributes.insert(std::make_pair(caption, storage));
491 DigraphReader& nodes(const std::string& caption) {
492 _nodes_caption = caption;
497 DigraphReader& arcs(const std::string& caption) {
498 _arcs_caption = caption;
503 DigraphReader& attributes(const std::string& caption) {
504 _attributes_caption = caption;
509 template <typename Map>
510 DigraphReader& useNodes(const Map& map) {
511 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
512 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
514 _writer_bits::DefaultConverter<typename Map::Value> converter;
515 for (NodeIt n(_digraph); n != INVALID; ++n) {
516 _node_index.insert(std::make_pair(converter(map[n]), n));
522 template <typename Map, typename Converter>
523 DigraphReader& useNodes(const Map& map,
524 const Converter& converter = Converter()) {
525 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
526 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
528 for (NodeIt n(_digraph); n != INVALID; ++n) {
529 _node_index.insert(std::make_pair(converter(map[n]), n));
535 template <typename Map>
536 DigraphReader& useArcs(const Map& map) {
537 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
538 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
540 _writer_bits::DefaultConverter<typename Map::Value> converter;
541 for (ArcIt a(_digraph); a != INVALID; ++a) {
542 _arc_index.insert(std::make_pair(converter(map[a]), a));
548 template <typename Map, typename Converter>
549 DigraphReader& useArcs(const Map& map,
550 const Converter& converter = Converter()) {
551 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
552 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
554 for (ArcIt a(_digraph); a != INVALID; ++a) {
555 _arc_index.insert(std::make_pair(converter(map[a]), a));
564 while(++line_num, std::getline(*_is, str)) {
565 line.clear(); line.str(str);
567 if (line >> std::ws >> c && c != '#') {
576 return static_cast<bool>(*_is);
581 while (readSuccess() && line >> c && c != '@') {
589 std::vector<int> map_index(_node_maps.size());
590 int map_num, label_index;
593 throw DataFormatError("Cannot find map captions");
596 std::map<std::string, int> maps;
600 while (_reader_bits::readIdentifier(line, map)) {
601 if (maps.find(map) != maps.end()) {
602 std::ostringstream msg;
603 msg << "Multiple occurence of node map: " << map;
604 throw DataFormatError(msg.str().c_str());
606 maps.insert(std::make_pair(map, index));
610 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
611 std::map<std::string, int>::iterator jt =
612 maps.find(_node_maps[i].first);
613 if (jt == maps.end()) {
614 std::ostringstream msg;
615 msg << "Map not found in file: " << _node_maps[i].first;
616 throw DataFormatError(msg.str().c_str());
618 map_index[i] = jt->second;
622 std::map<std::string, int>::iterator jt = maps.find("label");
623 if (jt == maps.end())
624 throw DataFormatError("Label map not found in file");
625 label_index = jt->second;
627 map_num = maps.size();
631 while (readLine() && line >> c && c != '@') {
634 std::vector<std::string> tokens(map_num);
635 for (int i = 0; i < map_num; ++i) {
636 if (!_reader_bits::readToken(line, tokens[i])) {
637 std::ostringstream msg;
638 msg << "Column not found (" << i + 1 << ")";
639 throw DataFormatError(msg.str().c_str());
642 if (line >> std::ws >> c)
643 throw DataFormatError("Extra character on the end of line");
647 n = _digraph.addNode();
648 _node_index.insert(std::make_pair(tokens[label_index], n));
650 typename std::map<std::string, Node>::iterator it =
651 _node_index.find(tokens[label_index]);
652 if (it == _node_index.end()) {
653 std::ostringstream msg;
654 msg << "Node with label not found: " << tokens[label_index];
655 throw DataFormatError(msg.str().c_str());
660 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
661 _node_maps[i].second->set(n, tokens[map_index[i]]);
672 std::vector<int> map_index(_arc_maps.size());
673 int map_num, label_index;
676 throw DataFormatError("Cannot find map captions");
679 std::map<std::string, int> maps;
683 while (_reader_bits::readIdentifier(line, map)) {
684 if (maps.find(map) != maps.end()) {
685 std::ostringstream msg;
686 msg << "Multiple occurence of arc map: " << map;
687 throw DataFormatError(msg.str().c_str());
689 maps.insert(std::make_pair(map, index));
693 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
694 std::map<std::string, int>::iterator jt =
695 maps.find(_arc_maps[i].first);
696 if (jt == maps.end()) {
697 std::ostringstream msg;
698 msg << "Map not found in file: " << _arc_maps[i].first;
699 throw DataFormatError(msg.str().c_str());
701 map_index[i] = jt->second;
705 std::map<std::string, int>::iterator jt = maps.find("label");
706 if (jt == maps.end())
707 throw DataFormatError("Label map not found in file");
708 label_index = jt->second;
710 map_num = maps.size();
714 while (readLine() && line >> c && c != '@') {
717 std::string source_token;
718 std::string target_token;
720 if (!_reader_bits::readToken(line, source_token))
721 throw DataFormatError("Source not found");
723 if (!_reader_bits::readToken(line, target_token))
724 throw DataFormatError("Source not found");
726 std::vector<std::string> tokens(map_num);
727 for (int i = 0; i < map_num; ++i) {
728 if (!_reader_bits::readToken(line, tokens[i])) {
729 std::ostringstream msg;
730 msg << "Column not found (" << i + 1 << ")";
731 throw DataFormatError(msg.str().c_str());
734 if (line >> std::ws >> c)
735 throw DataFormatError("Extra character on the end of line");
740 typename NodeIndex::iterator it;
742 it = _node_index.find(source_token);
743 if (it == _node_index.end()) {
744 std::ostringstream msg;
745 msg << "Item not found: " << source_token;
746 throw DataFormatError(msg.str().c_str());
748 Node source = it->second;
750 it = _node_index.find(target_token);
751 if (it == _node_index.end()) {
752 std::ostringstream msg;
753 msg << "Item not found: " << target_token;
754 throw DataFormatError(msg.str().c_str());
756 Node target = it->second;
758 a = _digraph.addArc(source, target);
759 _arc_index.insert(std::make_pair(tokens[label_index], a));
761 typename std::map<std::string, Arc>::iterator it =
762 _arc_index.find(tokens[label_index]);
763 if (it == _arc_index.end()) {
764 std::ostringstream msg;
765 msg << "Arc with label not found: " << tokens[label_index];
766 throw DataFormatError(msg.str().c_str());
771 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
772 _arc_maps[i].second->set(a, tokens[map_index[i]]);
781 void readAttributes() {
783 std::set<std::string> read_attr;
786 while (readLine() && line >> c && c != '@') {
789 std::string attr, token;
790 if (!_reader_bits::readIdentifier(line, attr))
791 throw DataFormatError("Attribute name not found");
792 if (!_reader_bits::readToken(line, token))
793 throw DataFormatError("Attribute value not found");
795 throw DataFormatError("Extra character on the end of line");
798 std::set<std::string>::iterator it = read_attr.find(attr);
799 if (it != read_attr.end()) {
800 std::ostringstream msg;
801 msg << "Multiple occurence of attribute " << attr;
802 throw DataFormatError(msg.str().c_str());
804 read_attr.insert(attr);
808 typename Attributes::iterator it = _attributes.lower_bound(attr);
809 while (it != _attributes.end() && it->first == attr) {
810 it->second->set(token);
819 for (typename Attributes::iterator it = _attributes.begin();
820 it != _attributes.end(); ++it) {
821 if (read_attr.find(it->first) == read_attr.end()) {
822 std::ostringstream msg;
823 msg << "Attribute not found in file: " << it->first;
824 throw DataFormatError(msg.str().c_str());
834 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
836 bool nodes_done = false;
837 bool arcs_done = false;
838 bool attributes_done = false;
843 while (readSuccess()) {
847 std::string section, caption;
849 _reader_bits::readIdentifier(line, section);
850 _reader_bits::readIdentifier(line, caption);
853 throw DataFormatError("Extra character on the end of line");
855 if (section == "nodes" && !nodes_done) {
856 if (_nodes_caption.empty() || _nodes_caption == caption) {
860 } else if ((section == "arcs" || section == "edges") &&
862 if (_arcs_caption.empty() || _arcs_caption == caption) {
866 } else if (section == "attributes" && !attributes_done) {
867 if (_attributes_caption.empty() || _attributes_caption == caption) {
869 attributes_done = true;
875 } catch (DataFormatError& error) {
876 error.line(line_num);
882 throw DataFormatError("Section @nodes not found");
886 throw DataFormatError("Section @arcs not found");
889 if (!attributes_done && !_attributes.empty()) {
890 throw DataFormatError("Section @attributes not found");
897 template <typename Digraph>
898 DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
899 return DigraphReader<Digraph>(is, digraph);
902 template <typename Digraph>
903 DigraphReader<Digraph> digraphReader(const std::string& fn,
905 return DigraphReader<Digraph>(fn, digraph);
908 template <typename Digraph>
909 DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
910 return DigraphReader<Digraph>(fn, digraph);