3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2007
 
     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 Item reader bits for lemon input.
 
    23 #ifndef LEMON_BITS_ITEM_READER_H
 
    24 #define LEMON_BITS_ITEM_READER_H
 
    35 #include <lemon/error.h>
 
    39   template <typename Value>
 
    44   /// \brief Reader class for unformatted strings.
 
    46   /// Reader class for unformatted strings. This class want to be
 
    47   /// a general reader type which can read the most 
 
    49   /// \author Balazs Dezso
 
    50   class UnformattedReader {
 
    52     /// \brief The value type of reader.
 
    54     /// The value type of reader.
 
    55     typedef std::string Value;
 
    57     /// \brief Constructor for the reader.
 
    59     /// Constructor for the reader.
 
    60     UnformattedReader() {} 
 
    62     /// \brief Reads an unformatted string from the given stream.
 
    64     /// Reads an unformatted string from the given stream.
 
    65     void read(std::istream& is, std::string& value) const {
 
    69       while (is.get(c) && !whiteSpace(c)) {
 
    70         processChar(c, is, value);
 
    76     void processChar(char c, std::istream& is, Value& value) const {
 
    80         readParsed('(', ')', is, value);
 
    84         readParsed('[', ']', is, value);
 
    88         readParsed('{', '}', is, value);
 
    92         readParsed('/', '/', is, value);
 
    96         readQuoted('\"', is, value);
 
   100         readQuoted('\'', is, value);
 
   108     void readParsed(char open, char close, 
 
   109                     std::istream& is, Value& value) const {
 
   111       if (!is.get(c) || c != open)
 
   112 	throw DataFormatError("Unformatted string format error");
 
   114       while (is.get(c) && c != close) {
 
   115         processChar(c, is, value);
 
   118         throw DataFormatError("Unformatted string format error");
 
   122     void readQuoted(char quote, std::istream& is, Value& value) const {
 
   125       if (!is.get(c) || c != quote)
 
   126 	throw DataFormatError("Unformatted string format error");
 
   128       while (is.get(c) && (c != quote || esc)) {
 
   129         if (c == '\\') esc = !esc;
 
   134         throw DataFormatError("Unformatted string format error");
 
   140     static bool whiteSpace(char c) {
 
   141       return c == ' ' || c == '\t' || c == '\v' || 
 
   142         c == '\n' || c == '\r' || c == '\f'; 
 
   150   /// \brief Reader class for quoted strings.
 
   152   /// Reader class for quoted strings. It can process the escape
 
   153   /// sequences in the string.
 
   155   /// \author Balazs Dezso
 
   156   class QuotedStringReader {
 
   157     friend class QuotedCharReader;
 
   159     /// \brief The value type of reader.
 
   161     /// The value type of reader.
 
   162     typedef std::string Value;
 
   164     /// \brief Constructor for the reader.
 
   166     /// Constructor for the reader. If the given parameter is true
 
   167     /// the reader processes the escape sequences.
 
   168     QuotedStringReader(bool _escaped = true) 
 
   169       : escaped(_escaped) {}
 
   171     /// \brief Reads a quoted string from the given stream.
 
   173     /// Reads a quoted string from the given stream.
 
   174     void read(std::istream& is, std::string& value) const {
 
   178       if (!is.get(c) || (c != '\"' && c != '\'')) 
 
   179 	throw DataFormatError("Quoted format error");
 
   181       while (is.get(c) && c != quote) {
 
   182 	if (escaped && c == '\\') {
 
   183 	  value += readEscape(is);
 
   188       if (!is) throw DataFormatError("Quoted format error");
 
   193     static char readEscape(std::istream& is) {
 
   195       switch (is.get(c), c) {
 
   221 	  if (!is.get(c) || !isHex(c)) 
 
   222 	    throw DataFormatError("Escape format error");
 
   223 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
 
   224 	  else code = code * 16 + valueHex(c);
 
   231 	    throw DataFormatError("Escape format error");
 
   232 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
 
   234 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
 
   236 	  else code = code * 8 + valueOct(c);
 
   242     static bool isOct(char c) {
 
   243       return '0' <= c && c <='7'; 
 
   246     static int valueOct(char c) {
 
   250    static bool isHex(char c) {
 
   251       return ('0' <= c && c <= '9') || 
 
   252 	('a' <= c && c <= 'z') || 
 
   253 	('A' <= c && c <= 'Z'); 
 
   256     static int valueHex(char c) {
 
   257       if ('0' <= c && c <= '9') return c - '0';
 
   258       if ('a' <= c && c <= 'z') return c - 'a' + 10;
 
   267   /// \brief Reader class for quoted strings.
 
   269   /// Reader class for quoted strings. It can process the escape
 
   270   /// sequences in the string.
 
   272   /// \author Balazs Dezso
 
   273   class QuotedCharReader {
 
   275     /// \brief The value type of reader.
 
   277     /// The value type of reader.
 
   280     /// \brief Constructor for the reader.
 
   282     /// Constructor for the reader. If the given parameter is true
 
   283     /// the reader processes the escape sequences.
 
   284     QuotedCharReader(bool _escaped = true) 
 
   285       : escaped(_escaped) {}
 
   287     /// \brief Reads a quoted string from the given stream.
 
   289     /// Reads a quoted string from the given stream.
 
   290     void read(std::istream& is, char& value) const {
 
   293       if (!is.get(c) || c != '\'') 
 
   294 	throw DataFormatError("Quoted format error");
 
   296         throw DataFormatError("Quoted format error");
 
   297       if (escaped && c == '\\') {
 
   298         value = QuotedStringReader::readEscape(is);
 
   302       if (!is.get(c) || c != '\'') 
 
   303 	throw DataFormatError("Quoted format error");
 
   311   /// \brief Reader for standard containers.
 
   313   /// Reader for back insertable standard containers. The representation
 
   314   /// of the container is the values enumerated between an open and a
 
   317   /// \author Balazs Dezso
 
   320     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   322   class PushBackReader {
 
   324     typedef _Container Value;
 
   325     typedef _ItemReader ItemReader;
 
   329     ItemReader item_reader;
 
   333     /// \brief Constructor for InsertReader
 
   335     /// Constructor for InsertReader
 
   336     PushBackReader(const ItemReader& _item_reader = ItemReader())
 
   337       : item_reader(_item_reader) {}
 
   339     /// \brief Reads the values into the container from the given stream.
 
   341     /// Reads the values into the container from the given stream.
 
   342     void read(std::istream& is, Value& value) const {
 
   344       if (!(is >> c) || c != '(') 
 
   345 	throw DataFormatError("PushBackReader format error");
 
   346       while (is >> c && c != ')') {
 
   348 	typename ItemReader::Value item;
 
   349 	item_reader.read(is, item);
 
   350 	value.push_back(item);
 
   352       if (!is) throw DataFormatError("PushBackReader format error");
 
   359   /// \brief Reader for standard containers.
 
   361   /// Reader for insertable standard containers. The representation
 
   362   /// of the container is the values enumerated between an open and a
 
   365   /// \author Balazs Dezso
 
   368     typename _ItemReader = DefaultReader<typename _Container::value_type> 
 
   372     typedef _Container Value;
 
   373     typedef _ItemReader ItemReader;
 
   377     ItemReader item_reader;
 
   381     /// \brief Constructor for InsertReader
 
   383     /// Constructor for InsertReader
 
   384     InsertReader(const ItemReader& _item_reader = ItemReader())
 
   385       : item_reader(_item_reader) {}
 
   387     /// \brief Reads the values into the container from the given stream.
 
   389     /// Reads the values into the container from the given stream.
 
   390     void read(std::istream& is, Value& value) const {
 
   392       if (!(is >> c) || c != '(') 
 
   393 	throw DataFormatError("InsertReader format error");
 
   394       while (is >> c && c != ')') {
 
   396 	typename ItemReader::Value item;
 
   397 	item_reader.read(is, item);
 
   400       if (!is) throw DataFormatError("PushBackReader format error");
 
   406   /// \brief Reader for parsed string.
 
   408   /// Reader for parsed strings. You can define the open and close
 
   409   /// parse characters. It reads from the input a character sequence
 
   410   /// which is right parsed.
 
   412   /// \author Balazs Dezso
 
   413   class ParsedStringReader {
 
   415     typedef std::string Value;
 
   417     /// \brief Constructor.
 
   419     /// Constructor for ParsedStringReader. You can give as parameter
 
   420     /// the open and close parse characters.
 
   421     ParsedStringReader(char _open = '(', char _close = ')')
 
   422       : open(_open), close(_close) {}
 
   425     /// \brief Reads the parsed string from the given stream.
 
   427     /// Reads the parsed string from the given stream.
 
   428     void read(std::istream& is, Value& value) const {
 
   431       if (!(is >> c) || c != open) {
 
   432 	throw DataFormatError("ParsedStringReader format error");
 
   436       while (counter > 0 && is >> c) {
 
   439 	} else if (c == open) {
 
   445 	throw DataFormatError("ParsedStrinReader format error");
 
   455   /// \brief Reader for read the whole line.
 
   457   /// Reader for read the whole line.
 
   459   /// \author Balazs Dezso
 
   462     typedef std::string Value;
 
   464     /// \brief Constructor.
 
   466     /// Constructor for the LineReader. If the given parameter is
 
   467     /// true then the spaces before the first not space character are
 
   469     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
 
   471     /// \brief Reads the line from the given stream.
 
   473     /// Reads the line from the given stream.
 
   474     void read(std::istream& is, Value& value) const {
 
   475       if (skipSpaces) is >> std::ws;
 
   476       if (!getline(is, value)) {
 
   477 	throw DataFormatError("LineReader format error");
 
   485   /// \brief Reader for std::pair.
 
   487   /// Reader for std::pair.
 
   489   /// \author Balazs Dezso
 
   490   template <typename _Pair, 
 
   491 	    typename _FirstReader = 
 
   492 	    DefaultReader<typename _Pair::first_type>,
 
   493 	    typename _SecondReader = 
 
   494 	    DefaultReader<typename _Pair::second_type> >
 
   499     typedef _FirstReader FirstReader;
 
   500     typedef _SecondReader SecondReader;
 
   504     FirstReader first_reader;
 
   505     SecondReader second_reader;
 
   509     /// \brief Constructor.
 
   511     /// Constructor for the PairReader.
 
   512     PairReader(const FirstReader& _first_reader = FirstReader(), 
 
   513 	       const SecondReader& _second_reader = SecondReader()) 
 
   514       : first_reader(_first_reader), second_reader(_second_reader) {}
 
   516     /// \brief Reads the pair from the given stream.
 
   518     /// Reads the pair from the given stream.
 
   519     void read(std::istream& is, Value& value) const {
 
   521       if (!(is >> c) || c != '(') {
 
   522 	throw DataFormatError("PairReader format error");
 
   524       first_reader.read(is, value.first);
 
   525       if (!(is >> c) || c != '=') {
 
   526 	throw DataFormatError("PairReader format error");
 
   528       if (!(is >> c) || c != '>') {
 
   529 	throw DataFormatError("PairReader format error");
 
   531       second_reader.read(is, value.second);
 
   532       if (!(is >> c) || c != ')') {
 
   533 	throw DataFormatError("PairReader format error");
 
   540   /// \brief The default item reader template class.
 
   542   /// The default item reader template class. If some section reader
 
   543   /// needs to read a value from a stream it will give the default way for it.
 
   545   /// \author Balazs Dezso
 
   546   template <typename _Value>
 
   547   class DefaultReader {
 
   550     typedef _Value Value;
 
   551     /// \brief Reads a value from the given stream.
 
   553     /// Reads a value from the given stream.
 
   554     void read(std::istream& is, Value& value) const {
 
   556 	throw DataFormatError("DefaultReader format error");
 
   561   class DefaultReader<std::string> {
 
   563     typedef std::string Value;
 
   565     void read(std::istream& is, Value& value) const {
 
   567       if (!(is >> std::ws >> c)) 
 
   568         throw DataFormatError("DefaultReader<string> format error");
 
   572 	QuotedStringReader().read(is, value);
 
   575         UnformattedReader().read(is, value);
 
   583   class DefaultReader<char> {
 
   587     void read(std::istream& is, Value& value) const {
 
   589       if (!(is >> std::ws >> c))
 
   590         throw DataFormatError("DefaultReader<char> format error");
 
   594 	QuotedCharReader().read(is, value);
 
   600             throw DataFormatError("DefaultReader<char> format error");
 
   601           value = static_cast<char>(temp);
 
   609   class DefaultReader<bool> {
 
   613     void read(std::istream& is, Value& value) const {
 
   616         throw DataFormatError("DefaultReader<bool> format error");
 
   617       if (rep == "true" || rep == "t" || rep == "1") {
 
   619       } else if (rep == "false" || rep == "f" || rep == "0") {
 
   621       } else throw DataFormatError("DefaultReader<bool> format error");
 
   625   template <typename Item>
 
   626   class DefaultReader<std::vector<Item> > 
 
   627     : public PushBackReader<std::vector<Item> > {};
 
   629   template <typename Item>
 
   630   class DefaultReader<std::deque<Item> > 
 
   631     : public PushBackReader<std::deque<Item> > {};
 
   633   template <typename Item>
 
   634   class DefaultReader<std::list<Item> > 
 
   635     : public PushBackReader<std::list<Item> > {};
 
   637   template <typename Item>
 
   638   class DefaultReader<std::set<Item> > 
 
   639     : public InsertReader<std::set<Item> > {};
 
   641   template <typename Key, typename Value>
 
   642   class DefaultReader<std::map<Key, Value> > 
 
   643     : public InsertReader<std::map<Key, Value>,
 
   644 			  DefaultReader<std::pair<Key, Value> > > {};
 
   646   template <typename Item>
 
   647   class DefaultReader<std::multiset<Item> > 
 
   648     : public InsertReader<std::multiset<Item> > {};
 
   650   template <typename Key, typename Value>
 
   651   class DefaultReader<std::multimap<Key, Value> > 
 
   652     : public InsertReader<std::multimap<Key, Value>,
 
   653 			  DefaultReader<std::pair<Key, Value> > > {};
 
   655   template <typename First, typename Second>
 
   656   class DefaultReader<std::pair<First, Second> > 
 
   657     : public PairReader<std::pair<First, Second> > {};
 
   661   /// \brief The default item reader for skipping a value in the stream.
 
   663   /// The default item reader for skipping a value in the stream.
 
   665   /// \author Balazs Dezso
 
   666   class DefaultSkipper : public UnformattedReader {};
 
   669   /// \brief Standard ReaderTraits for the GraphReader class.
 
   671   /// Standard ReaderTraits for the GraphReader class.
 
   672   /// It defines standard reading method for all type of value. 
 
   673   /// \author Balazs Dezso
 
   674   struct DefaultReaderTraits {
 
   676     template <typename _Value>
 
   677     struct Reader : DefaultReader<_Value> {};
 
   679     typedef DefaultSkipper Skipper;