src/work/deba/graph_reader.h
changeset 1139 f59038affc7e
parent 1115 444f69240539
equal deleted inserted replaced
3:1bc79fcb3372 4:f503f5ab3c9e
    71   private:
    71   private:
    72     int line_num;
    72     int line_num;
    73   };  
    73   };  
    74 
    74 
    75 
    75 
    76   // Readers and ReaderTraits
       
    77   /// \brief Standard ReaderTraits for the GraphReader class.
    76   /// \brief Standard ReaderTraits for the GraphReader class.
    78   ///
    77   ///
    79   /// 
    78   /// Standard ReaderTraits for the GraphReader class.
    80  
    79   /// It defines standard reading method for all type of value. 
    81   struct DefaultReaderTraits {
    80   struct DefaultReaderTraits {
    82 
    81 
       
    82     /// \brief Template class for reading an value.
       
    83     ///
       
    84     /// Template class for reading an value.
    83     template <typename _Value>
    85     template <typename _Value>
    84     struct Reader {
    86     struct Reader {
       
    87       /// The value type.
    85       typedef _Value Value;
    88       typedef _Value Value;
       
    89       /// \brief Reads a value from the given stream.
       
    90       ///
       
    91       /// Reads a value from the given stream.
    86       void read(std::istream& is, Value& value) {
    92       void read(std::istream& is, Value& value) {
    87 	if (!(is >> value)) 
    93 	if (!(is >> value)) 
    88 	  throw DataFormatException("Default Reader format exception");
    94 	  throw DataFormatException("Default Reader format exception");
    89       }
    95       }
    90     };
    96     };
    91 
    97 
       
    98     /// The reader class for the not needed maps.
    92     typedef Reader<std::string> DefaultReader;
    99     typedef Reader<std::string> DefaultReader;
    93 
   100 
    94   };
   101   };
    95 
   102 
       
   103   /// \brief Reader class for quoted strings.
       
   104   ///
       
   105   /// Reader class for quoted strings. It can process the escape
       
   106   /// sequences in the string.
    96   class QuotedStringReader {
   107   class QuotedStringReader {
    97   public:
   108   public:
    98     typedef std::string Value;
   109     typedef std::string Value;
    99 
   110     
       
   111     /// \brief Constructor for the reader.
       
   112     ///
       
   113     /// Constructor for the reader. If the given parameter is true
       
   114     /// the reader processes the escape sequences.
   100     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
   115     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
   101 
   116     
       
   117     /// \brief Reads a quoted string from the given stream.
       
   118     ///
       
   119     /// Reads a quoted string from the given stream.
   102     void read(std::istream& is, std::string& value) {
   120     void read(std::istream& is, std::string& value) {
   103       char c;
   121       char c;
   104       value.clear();
   122       value.clear();
   105       is >> ws;
   123       is >> ws;
   106       if (!is.get(c) || c != '\"') 
   124       if (!is.get(c) || c != '\"') 
   143       case 'v':
   161       case 'v':
   144 	return '\v';
   162 	return '\v';
   145       case 'x':
   163       case 'x':
   146 	{
   164 	{
   147 	  int code;
   165 	  int code;
   148 	  if (!is.get(c) || !isHex(c)) throw DataFormatException("Escape format exception");
   166 	  if (!is.get(c) || !isHex(c)) 
       
   167 	    throw DataFormatException("Escape format exception");
   149 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   168 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   150 	  else code = code * 16 + valueHex(c);
   169 	  else code = code * 16 + valueHex(c);
   151 	  return code;
   170 	  return code;
   152 	}
   171 	}
   153       default:
   172       default:
   154 	{
   173 	{
   155 	  int code;
   174 	  int code;
   156 	  if (!isOct(c)) throw DataFormatException("Escape format exception");
   175 	  if (!isOct(c)) 
   157 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
   176 	    throw DataFormatException("Escape format exception");
   158 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
   177 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
       
   178 	    is.putback(c);
       
   179 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
       
   180 	    is.putback(c);
   159 	  else code = code * 8 + valueOct(c);
   181 	  else code = code * 8 + valueOct(c);
   160 	  return code;
   182 	  return code;
   161 	}	      
   183 	}	      
   162       } 
   184       } 
   163     }
   185     }
   169     static int valueOct(char c) {
   191     static int valueOct(char c) {
   170       return c - '0';
   192       return c - '0';
   171     }
   193     }
   172 
   194 
   173    static bool isHex(char c) {
   195    static bool isHex(char c) {
   174       return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 
   196       return ('0' <= c && c <= '9') || 
       
   197 	('a' <= c && c <= 'z') || 
       
   198 	('A' <= c && c <= 'Z'); 
   175     }
   199     }
   176     
   200     
   177     static int valueHex(char c) {
   201     static int valueHex(char c) {
   178       if ('0' <= c && c <= '9') return c - '0';
   202       if ('0' <= c && c <= '9') return c - '0';
   179       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   203       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   181     }
   205     }
   182 
   206 
   183     bool escaped;
   207     bool escaped;
   184   };
   208   };
   185 
   209 
   186 
   210   /// \brief The graph reader class.
   187 
   211   ///
   188 
   212   /// The reader class for the graph input.
   189 
   213   /// \see graph-io-page
   190   // Graph reader
       
   191   
       
   192   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   214   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   193   class GraphReader {
   215   class GraphReader {
   194   public:
   216   public:
   195     
   217     
   196     typedef _Graph Graph;
   218     typedef _Graph Graph;
   198     typedef typename Graph::Edge Edge;
   220     typedef typename Graph::Edge Edge;
   199 
   221 
   200     typedef _ReaderTraits ReaderTraits;
   222     typedef _ReaderTraits ReaderTraits;
   201     typedef typename ReaderTraits::DefaultReader DefaultReader;
   223     typedef typename ReaderTraits::DefaultReader DefaultReader;
   202 
   224 
       
   225     /// \brief Construct a new GraphReader.
       
   226     ///
       
   227     /// Construct a new GraphReader. It reads from the given map,
       
   228     /// it constructs the given map and it use the given reader as the
       
   229     /// default skipper.
   203     GraphReader(std::istream& _is, Graph& _graph, 
   230     GraphReader(std::istream& _is, Graph& _graph, 
   204 		const DefaultReader& _reader = DefaultReader()) 
   231 		const DefaultReader& _reader = DefaultReader()) 
   205       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
   232       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
   206 
   233 
   207 
   234     /// \brief Destruct the graph reader.
       
   235     ///
       
   236     /// Destruct the graph reader.
   208     ~GraphReader() {
   237     ~GraphReader() {
   209 
   238 
   210       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   239       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   211 	   it != node_map_readers.end(); ++it) {
   240 	   it != node_map_readers.end(); ++it) {
   212 	delete it->second;
   241 	delete it->second;
   217 	delete it->second;
   246 	delete it->second;
   218       }
   247       }
   219 
   248 
   220     }
   249     }
   221 
   250 
   222     // Node map rules
   251     /// \brief Add a new node map reader command for the reader.
   223 
   252     ///
       
   253     /// Add a new node map reader command for the reader.
   224     template <typename Map>
   254     template <typename Map>
   225     GraphReader& addNodeMap(std::string name, Map& map) {
   255     GraphReader& addNodeMap(std::string name, Map& map) {
   226       return addNodeMap<typename ReaderTraits::template 
   256       return addNodeMap<typename ReaderTraits::template 
   227 	Reader<typename Map::Value>, Map>(name, map);
   257 	Reader<typename Map::Value>, Map>(name, map);
   228     }
   258     }
   229 
   259 
       
   260     /// \brief Add a new node map reader command for the reader.
       
   261     ///
       
   262     /// Add a new node map reader command for the reader.
   230     template <typename Reader, typename Map>
   263     template <typename Reader, typename Map>
   231     GraphReader& addNodeMap(std::string name, Map& map, 
   264     GraphReader& addNodeMap(std::string name, Map& map, 
   232 			     const Reader& reader = Reader()) {
   265 			     const Reader& reader = Reader()) {
   233       if (node_map_readers.find(name) != node_map_readers.end()) {
   266       if (node_map_readers.find(name) != node_map_readers.end()) {
   234 	throw Exception() << "Multiple read rule for node map: " << name;
   267 	throw Exception() << "Multiple read rule for node map: " << name;
   236       node_map_readers.insert(
   269       node_map_readers.insert(
   237         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   270         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   238       return *this;
   271       return *this;
   239     }
   272     }
   240 
   273 
       
   274     /// \brief Add a new node map skipper command for the reader.
       
   275     ///
       
   276     /// Add a new node map skipper command for the reader.
   241     template <typename Reader>
   277     template <typename Reader>
   242     GraphReader& skipNodeMap(std::string name, 
   278     GraphReader& skipNodeMap(std::string name, 
   243 			     const Reader& reader = Reader()) {
   279 			     const Reader& reader = Reader()) {
   244       if (node_map_readers.find(name) != node_map_readers.end()) {
   280       if (node_map_readers.find(name) != node_map_readers.end()) {
   245 	throw Exception() << "Multiple read rule for node map: " << name;
   281 	throw Exception() << "Multiple read rule for node map: " << name;
   247       node_map_readers.insert(
   283       node_map_readers.insert(
   248         make_pair(name, new SkipReader<Node, Reader>(reader)));
   284         make_pair(name, new SkipReader<Node, Reader>(reader)));
   249       return *this;
   285       return *this;
   250     }
   286     }
   251 
   287 
   252     // Edge map rules
   288     /// \brief Add a new edge map reader command for the reader.
   253 
   289     ///
       
   290     /// Add a new edge map reader command for the reader.
   254     template <typename Map>
   291     template <typename Map>
   255     GraphReader& addEdgeMap(std::string name, Map& map) { 
   292     GraphReader& addEdgeMap(std::string name, Map& map) { 
   256       return addEdgeMap<typename ReaderTraits::template
   293       return addEdgeMap<typename ReaderTraits::template
   257 	Reader<typename Map::Value>, Map>(name, map);
   294 	Reader<typename Map::Value>, Map>(name, map);
   258     }
   295     }
   259 
   296 
   260 
   297 
       
   298     /// \brief Add a new edge map reader command for the reader.
       
   299     ///
       
   300     /// Add a new edge map reader command for the reader.
   261     template <typename Reader, typename Map>
   301     template <typename Reader, typename Map>
   262     GraphReader& addEdgeMap(std::string name, Map& map,
   302     GraphReader& addEdgeMap(std::string name, Map& map,
   263 			     const Reader& reader = Reader()) {
   303 			     const Reader& reader = Reader()) {
   264       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   304       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   265 	throw Exception() << "Multiple read rule for edge map: " << name;
   305 	throw Exception() << "Multiple read rule for edge map: " << name;
   267       edge_map_readers.insert(
   307       edge_map_readers.insert(
   268         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   308         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   269       return *this;
   309       return *this;
   270     }
   310     }
   271 
   311 
       
   312     /// \brief Add a new edge map skipper command for the reader.
       
   313     ///
       
   314     /// Add a new edge map skipper command for the reader.
   272     template <typename Reader>
   315     template <typename Reader>
   273     GraphReader& skipEdgeMap(std::string name,
   316     GraphReader& skipEdgeMap(std::string name,
   274 			     const Reader& reader = Reader()) {
   317 			     const Reader& reader = Reader()) {
   275       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   318       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   276 	throw Exception() << "Multiple read rule for edge map: " << name;
   319 	throw Exception() << "Multiple read rule for edge map: " << name;
   278       edge_map_readers.insert(
   321       edge_map_readers.insert(
   279         make_pair(name, new SkipReader<Edge, Reader>(reader)));
   322         make_pair(name, new SkipReader<Edge, Reader>(reader)));
   280       return *this;
   323       return *this;
   281     }
   324     }
   282 
   325 
   283     // Node rules
   326     /// \brief Add a new labeled node reader for the reader.
       
   327     ///
       
   328     /// Add a new labeled node reader for the reader.
   284     GraphReader& addNode(std::string name, Node& node) {
   329     GraphReader& addNode(std::string name, Node& node) {
   285       if (node_readers.find(name) != node_readers.end()) {
   330       if (node_readers.find(name) != node_readers.end()) {
   286 	throw Exception() << "Multiple read rule for node";
   331 	throw Exception() << "Multiple read rule for node";
   287       }
   332       }
   288       node_readers.insert(make_pair(name, &node));
   333       node_readers.insert(make_pair(name, &node));
   289       return *this;
   334       return *this;
   290     }
   335     }
   291 
   336 
   292     // Edge rules
   337     /// \brief Add a new labeled edge reader for the reader.
   293 
   338     ///
       
   339     /// Add a new labeled edge reader for the reader.
   294     GraphReader& addEdge(std::string name, Edge& edge) {
   340     GraphReader& addEdge(std::string name, Edge& edge) {
   295       if (edge_readers.find(name) != edge_readers.end()) {
   341       if (edge_readers.find(name) != edge_readers.end()) {
   296 	throw Exception() << "Multiple read rule for edge";
   342 	throw Exception() << "Multiple read rule for edge";
   297       }
   343       }
   298       edge_readers.insert(make_pair(name, &edge));
   344       edge_readers.insert(make_pair(name, &edge));
   299       return *this;
   345       return *this;
   300     }
   346     }
   301 
   347 
   302     void read() {
   348     /// \brief Executes the reader commands.
       
   349     ///
       
   350     /// Executes the reader commands.
       
   351     void run() {
   303       int line_num = 0;
   352       int line_num = 0;
   304       std::auto_ptr<InverterBase<Node> > nodeInverter;
   353       std::auto_ptr<InverterBase<Node> > nodeInverter;
   305       std::auto_ptr<InverterBase<Edge> > edgeInverter;
   354       std::auto_ptr<InverterBase<Edge> > edgeInverter;
   306       try {
   355       try {
   307 	std::string line = readNotEmptyLine(is, line_num);
   356 	std::string line = readNotEmptyLine(is, line_num);