3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2006
 
     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
 
    19 /// @defgroin item_io Item Readers and Writers
 
    21 /// \brief Item Readers and Writers
 
    23 /// The Input-Output classes can handle more data type by example
 
    24 /// as map or attribute value. Each of these should be written and
 
    25 /// read some way. The module make possible to do this.  
 
    29 /// \brief Item reader bits for lemon input.
 
    31 #ifndef LEMON_BITS_ITEM_READER_H
 
    32 #define LEMON_BITS_ITEM_READER_H
 
    44   template <typename Value>
 
    49   /// \brief Reader class for quoted strings.
 
    51   /// Reader class for quoted strings. It can process the escape
 
    52   /// sequences in the string.
 
    54   /// \author Balazs Dezso
 
    55   class QuotedStringReader {
 
    57     /// \brief The value type of reader.
 
    59     /// The value type of reader.
 
    60     typedef std::string Value;
 
    62     /// \brief Constructor for the reader.
 
    64     /// Constructor for the reader. If the given parameter is true
 
    65     /// the reader processes the escape sequences.
 
    66     QuotedStringReader(bool _escaped = true) 
 
    67       : escaped(_escaped) {}
 
    69     /// \brief Reads a quoted string from the given stream.
 
    71     /// Reads a quoted string from the given stream.
 
    72     void read(std::istream& is, std::string& value) const {
 
    76       if (!is.get(c) || c != '\"') 
 
    77 	throw DataFormatError("Quoted string format error");
 
    78       while (is.get(c) && c != '\"') {
 
    79 	if (escaped && c == '\\') {
 
    80 	  value += readEscape(is);
 
    85       if (!is) throw DataFormatError("Quoted string format error");
 
    90     static char readEscape(std::istream& is) {
 
    92       switch (is.get(c), c) {
 
   118 	  if (!is.get(c) || !isHex(c)) 
 
   119 	    throw DataFormatError("Escape format error");
 
   120 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
 
   121 	  else code = code * 16 + valueHex(c);
 
   128 	    throw DataFormatError("Escape format error");
 
   129 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
 
   131 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
 
   133 	  else code = code * 8 + valueOct(c);
 
   139     static bool isOct(char c) {
 
   140       return '0' <= c && c <='7'; 
 
   143     static int valueOct(char c) {
 
   147    static bool isHex(char c) {
 
   148       return ('0' <= c && c <= '9') || 
 
   149 	('a' <= c && c <= 'z') || 
 
   150 	('A' <= c && c <= 'Z'); 
 
   153     static int valueHex(char c) {
 
   154       if ('0' <= c && c <= '9') return c - '0';
 
   155       if ('a' <= c && c <= 'z') return c - 'a' + 10;
 
   163   /// \brief Reader for standard containers.
 
   165   /// Reader for back insertable standard containers. The representation
 
   166   /// of the container is the values enumerated between an open and a
 
   169   /// \author Balazs Dezso
 
   172     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   174   class PushBackReader {
 
   176     typedef _Container Value;
 
   177     typedef _ItemReader ItemReader;
 
   181     ItemReader item_reader;
 
   185     /// \brief Constructor for InsertReader
 
   187     /// Constructor for InsertReader
 
   188     PushBackReader(const ItemReader& _item_reader = ItemReader())
 
   189       : item_reader(_item_reader) {}
 
   191     /// \brief Reads the values into the container from the given stream.
 
   193     /// Reads the values into the container from the given stream.
 
   194     void read(std::istream& is, Value& value) const {
 
   196       if (!(is >> c) || c != '(') 
 
   197 	throw DataFormatError("PushBackReader format error");
 
   198       while (is >> c && c != ')') {
 
   200 	typename ItemReader::Value item;
 
   201 	item_reader.read(is, item);
 
   202 	value.push_back(item);
 
   204       if (!is) throw DataFormatError("PushBackReader format error");
 
   211   /// \brief Reader for standard containers.
 
   213   /// Reader for insertable standard containers. The representation
 
   214   /// of the container is the values enumerated between an open and a
 
   217   /// \author Balazs Dezso
 
   220     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   224     typedef _Container Value;
 
   225     typedef _ItemReader ItemReader;
 
   229     ItemReader item_reader;
 
   233     /// \brief Constructor for InsertReader
 
   235     /// Constructor for InsertReader
 
   236     InsertReader(const ItemReader& _item_reader = ItemReader())
 
   237       : item_reader(_item_reader) {}
 
   239     /// \brief Reads the values into the container from the given stream.
 
   241     /// Reads the values into the container from the given stream.
 
   242     void read(std::istream& is, Value& value) const {
 
   244       if (!(is >> c) || c != '(') 
 
   245 	throw DataFormatError("InsertReader format error");
 
   246       while (is >> c && c != ')') {
 
   248 	typename ItemReader::Value item;
 
   249 	item_reader.read(is, item);
 
   252       if (!is) throw DataFormatError("PushBackReader format error");
 
   258   /// \brief Reader for parsed string.
 
   260   /// Reader for parsed strings. You can define the open and close
 
   261   /// parse characters. It reads from the input a character sequence
 
   262   /// which is right parsed.
 
   264   /// \author Balazs Dezso
 
   265   class ParsedStringReader {
 
   267     typedef std::string Value;
 
   269     /// \brief Constructor.
 
   271     /// Constructor for ParsedStringReader. You can give as parameter
 
   272     /// the open and close parse characters.
 
   273     ParsedStringReader(char _open = '(', char _close = ')')
 
   274       : open(_open), close(_close) {}
 
   277     /// \brief Reads the parsed string from the given stream.
 
   279     /// Reads the parsed string from the given stream.
 
   280     void read(std::istream& is, Value& value) const {
 
   282       if (!(is >> c) || c != open) {
 
   283 	throw DataFormatError("ParsedStringReader format error");
 
   287       while (counter > 0 && is >> c) {
 
   290 	} else if (c == open) {
 
   296 	throw DataFormatError("ParsedStrinReader format error");
 
   306   /// \brief Reader for read the whole line.
 
   308   /// Reader for read the whole line.
 
   310   /// \author Balazs Dezso
 
   313     typedef std::string Value;
 
   315     /// \brief Constructor.
 
   317     /// Constructor for the LineReader. If the given parameter is
 
   318     /// true then the spaces before the first not space character are
 
   320     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
 
   322     /// \brief Reads the line from the given stream.
 
   324     /// Reads the line from the given stream.
 
   325     void read(std::istream& is, Value& value) const {
 
   326       if (skipSpaces) is >> std::ws;
 
   327       if (!getline(is, value)) {
 
   328 	throw DataFormatError("LineReader format error");
 
   336   /// \brief Reader for std::pair.
 
   338   /// Reader for std::pair.
 
   340   /// \author Balazs Dezso
 
   341   template <typename _Pair, 
 
   342 	    typename _FirstReader = 
 
   343 	    DefaultReader<typename _Pair::first_type>,
 
   344 	    typename _SecondReader = 
 
   345 	    DefaultReader<typename _Pair::second_type> >
 
   350     typedef _FirstReader FirstReader;
 
   351     typedef _SecondReader SecondReader;
 
   355     FirstReader first_reader;
 
   356     SecondReader second_reader;
 
   360     /// \brief Constructor.
 
   362     /// Constructor for the PairReader.
 
   363     PairReader(const FirstReader& _first_reader = FirstReader(), 
 
   364 	       const SecondReader& _second_reader = SecondReader()) 
 
   365       : first_reader(_first_reader), second_reader(_second_reader) {}
 
   367     /// \brief Reads the pair from the given stream.
 
   369     /// Reads the pair from the given stream.
 
   370     void read(std::istream& is, Value& value) const {
 
   372       if (!(is >> c) || c != '(') {
 
   373 	throw DataFormatError("PairReader format error");
 
   375       first_reader.read(is, value.first);
 
   376       if (!(is >> c) || c != '=') {
 
   377 	throw DataFormatError("PairReader format error");
 
   379       if (!(is >> c) || c != '>') {
 
   380 	throw DataFormatError("PairReader format error");
 
   382       second_reader.read(is, value.second);
 
   383       if (!(is >> c) || c != ')') {
 
   384 	throw DataFormatError("PairReader format error");
 
   391   /// \brief The default item reader template class.
 
   393   /// The default item reader template class. If some section reader
 
   394   /// needs to read a value from a stream it will give the default way for it.
 
   396   /// \author Balazs Dezso
 
   397   template <typename _Value>
 
   398   class DefaultReader {
 
   401     typedef _Value Value;
 
   402     /// \brief Reads a value from the given stream.
 
   404     /// Reads a value from the given stream.
 
   405     void read(std::istream& is, Value& value) const {
 
   407 	throw DataFormatError("DefaultReader format error");
 
   412   class DefaultReader<std::string> {
 
   414     typedef std::string Value;
 
   416     void read(std::istream& is, Value& value) const {
 
   418       if (!(is >> std::ws >> c)) return;
 
   422 	QuotedStringReader().read(is, value);
 
   425 	ParsedStringReader().read(is, value);
 
   428 	ParsedStringReader('[', ']').read(is, value);
 
   431 	ParsedStringReader('/', '/').read(is, value);
 
   435 	  throw DataFormatError("DefaultReader format error");
 
   442   template <typename Item>
 
   443   class DefaultReader<std::vector<Item> > 
 
   444     : public PushBackReader<std::vector<Item> > {};
 
   446   template <typename Item>
 
   447   class DefaultReader<std::deque<Item> > 
 
   448     : public PushBackReader<std::deque<Item> > {};
 
   450   template <typename Item>
 
   451   class DefaultReader<std::list<Item> > 
 
   452     : public PushBackReader<std::list<Item> > {};
 
   454   template <typename Item>
 
   455   class DefaultReader<std::set<Item> > 
 
   456     : public InsertReader<std::set<Item> > {};
 
   458   template <typename Key, typename Value>
 
   459   class DefaultReader<std::map<Key, Value> > 
 
   460     : public InsertReader<std::map<Key, Value>,
 
   461 			  DefaultReader<std::pair<Key, Value> > > {};
 
   463   template <typename Item>
 
   464   class DefaultReader<std::multiset<Item> > 
 
   465     : public InsertReader<std::multiset<Item> > {};
 
   467   template <typename Key, typename Value>
 
   468   class DefaultReader<std::multimap<Key, Value> > 
 
   469     : public InsertReader<std::multimap<Key, Value>,
 
   470 			  DefaultReader<std::pair<Key, Value> > > {};
 
   472   template <typename First, typename Second>
 
   473   class DefaultReader<std::pair<First, Second> > 
 
   474     : public PairReader<std::pair<First, Second> > {};
 
   478   /// \brief The default item reader for skipping a value in the stream.
 
   480   /// The default item reader for skipping a value in the stream.
 
   482   /// \author Balazs Dezso
 
   483   class DefaultSkipper : public DefaultReader<std::string> {};
 
   486   /// \brief Standard ReaderTraits for the GraphReader class.
 
   488   /// Standard ReaderTraits for the GraphReader class.
 
   489   /// It defines standard reading method for all type of value. 
 
   490   /// \author Balazs Dezso
 
   491   struct DefaultReaderTraits {
 
   493     template <typename _Value>
 
   494     struct Reader : DefaultReader<_Value> {};
 
   496     typedef DefaultSkipper Skipper;