COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/item_reader.h @ 1791:62e7d237e1fb

Last change on this file since 1791:62e7d237e1fb was 1744:51d5d41e15b1, checked in by Balazs Dezso, 14 years ago

Removing old input/output functions

File size: 10.4 KB
Line 
1/* -*- C++ -*-
2 * lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17/// @defgroup item_io Item Readers and Writers
18/// @ingroup io_group
19/// \brief Item Readers and Writers
20///
21/// The Input-Output classes can handle more data type by example
22/// as map or attribute value. Each of these should be written and
23/// read some way. The module make possible to do this. 
24
25/// \ingroup item_io
26/// \file
27/// \brief Item reader bits for lemon input.
28
29#ifndef LEMON_BITS_ITEM_READER_H
30#define LEMON_BITS_ITEM_READER_H
31
32#include <iostream>
33#include <string>
34
35#include <vector>
36#include <deque>
37#include <list>
38#include <set>
39
40namespace lemon {
41 
42  template <typename Value>
43  class DefaultReader;
44
45  /// \ingroup item_io
46  ///
47  /// \brief Reader class for quoted strings.
48  ///
49  /// Reader class for quoted strings. It can process the escape
50  /// sequences in the string.
51  ///
52  /// \author Balazs Dezso
53  class QuotedStringReader {
54  public:
55    /// \brief The value type of reader.
56    ///
57    /// The value type of reader.
58    typedef std::string Value;
59   
60    /// \brief Constructor for the reader.
61    ///
62    /// Constructor for the reader. If the given parameter is true
63    /// the reader processes the escape sequences.
64    QuotedStringReader(bool _escaped = true)
65      : escaped(_escaped) {}
66   
67    /// \brief Reads a quoted string from the given stream.
68    ///
69    /// Reads a quoted string from the given stream.
70    void read(std::istream& is, std::string& value) const {
71      char c;
72      value.clear();
73      is >> std::ws;
74      if (!is.get(c) || c != '\"')
75        throw DataFormatError("Quoted string format error");
76      while (is.get(c) && c != '\"') {
77        if (escaped && c == '\\') {
78          value += readEscape(is);
79        } else {
80          value += c;
81        }
82      }
83      if (!is) throw DataFormatError("Quoted string format error");
84    }
85
86  private:
87   
88    static char readEscape(std::istream& is) {
89      char c;
90      switch (is.get(c), c) {
91      case '\\':
92        return '\\';
93      case '\"':
94        return '\"';
95      case '\'':
96        return '\'';
97      case '\?':
98        return '\?';
99      case 'a':
100        return '\a';
101      case 'b':
102        return '\b';
103      case 'f':
104        return '\f';
105      case 'n':
106        return '\n';
107      case 'r':
108        return '\r';
109      case 't':
110        return '\t';
111      case 'v':
112        return '\v';
113      case 'x':
114        {
115          int code;
116          if (!is.get(c) || !isHex(c))
117            throw DataFormatError("Escape format error");
118          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
119          else code = code * 16 + valueHex(c);
120          return code;
121        }
122      default:
123        {
124          int code;
125          if (!isOct(c))
126            throw DataFormatError("Escape format error");
127          else if (code = valueOct(c), !is.get(c) || !isOct(c))
128            is.putback(c);
129          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
130            is.putback(c);
131          else code = code * 8 + valueOct(c);
132          return code;
133        }             
134      }
135    }
136
137    static bool isOct(char c) {
138      return '0' <= c && c <='7';
139    }
140   
141    static int valueOct(char c) {
142      return c - '0';
143    }
144
145   static bool isHex(char c) {
146      return ('0' <= c && c <= '9') ||
147        ('a' <= c && c <= 'z') ||
148        ('A' <= c && c <= 'Z');
149    }
150   
151    static int valueHex(char c) {
152      if ('0' <= c && c <= '9') return c - '0';
153      if ('a' <= c && c <= 'z') return c - 'a' + 10;
154      return c - 'A' + 10;
155    }
156
157    bool escaped;
158  };
159
160  /// \ingroup item_io
161  /// \brief Reader for standard containers.
162  ///
163  /// Reader for back insertable standard containers. The representation
164  /// of the container is the values enumerated between an open and a
165  /// close parse.
166  ///
167  /// \author Balazs Dezso
168  template <
169    typename _Container,
170    typename _ItemReader = DefaultReader<typename _Container::value_type>
171  >
172  class PushBackReader {
173  public:
174    typedef _Container Value;
175    typedef _ItemReader ItemReader;
176
177  private:
178
179    ItemReader item_reader;
180
181  public:
182
183    /// \brief Reads the values into the container from the given stream.
184    ///
185    /// Reads the values into the container from the given stream.
186    void read(std::istream& is, Value& value) const {
187      char c;
188      if (!(is >> c) || c != '(')
189        throw DataFormatError("PushBackReader format error");
190      while (is >> c && c != ')') {
191        is.putback(c);
192        typename ItemReader::Value item;
193        item_reader.read(is, item);
194        value.push_back(item);
195      }
196      if (!is) throw DataFormatError("PushBackReader format error");
197      is.putback(c);
198    }
199
200  };
201
202  /// \ingroup item_io
203  ///
204  /// \brief Reader for standard containers.
205  ///
206  /// Reader for insertable standard containers. The representation
207  /// of the container is the values enumerated between an open and a
208  /// close parse.
209  ///
210  /// \author Balazs Dezso
211  template <
212    typename _Container,
213    typename _ItemReader = DefaultReader<typename _Container::value_type>
214  >
215  class InsertReader {
216  public:
217    typedef _Container Value;
218    typedef _ItemReader ItemReader;
219
220  private:
221
222    ItemReader item_reader;
223
224  public:
225
226    /// \brief Reads the values into the container from the given stream.
227    ///
228    /// Reads the values into the container from the given stream.
229    void read(std::istream& is, Value& value) const {
230      char c;
231      if (!(is >> c) || c != '(')
232        throw DataFormatError("InsertReader format error");
233      while (is >> c && c != ')') {
234        is.putback(c);
235        typename ItemReader::Value item;
236        item_reader.read(is, item);
237        value.insert(item);
238      }
239      if (!is) throw DataFormatError("PushBackReader format error");
240      is.putback(c);
241    }
242
243  };
244
245  /// \ingroup item_io
246  /// \brief Reader for parsed string.
247  ///
248  /// Reader for parsed strings. You can define the open and close
249  /// parse characters. It reads from the input a character sequence
250  /// which is right parsed.
251  ///
252  /// \author Balazs Dezso
253  class ParsedStringReader {
254  public:
255    typedef std::string Value;
256
257    /// \brief Constructor.
258    ///
259    /// Constructor for ParsedStringReader. You can give as parameter
260    /// the open and close parse characters.
261    ParsedStringReader(char _open = '(', char _close = ')')
262      : open(_open), close(_close) {}
263   
264   
265    /// \brief Reads the parsed string from the given stream.
266    ///
267    /// Reads the parsed string from the given stream.
268    void read(std::istream& is, Value& value) const {
269      char c;
270      if (!(is >> c) || c != open) {
271        throw DataFormatError("ParsedStringReader format error");
272      }
273      value += c;
274      int counter = 1;
275      while (counter > 0 && is >> c) {
276        if (c == close) {
277          --counter;
278        } else if (c == open) {
279          ++counter;
280        }
281        value += c;
282      }
283      if (!is) {
284        throw DataFormatError("ParsedStrinReader format error");
285      }
286    }
287
288  private:
289    char open, close;
290
291  };
292
293  /// \ingroup item_io
294  /// \brief Reader for read the whole line.
295  ///
296  /// Reader for read the whole line.
297  ///
298  /// \author Balazs Dezso
299  class LineReader {
300  public:
301    typedef std::string Value;
302
303    /// \brief Constructor.
304    ///
305    /// Constructor for the LineReader. If the given parameter is
306    /// true then the spaces before the first not space character are
307    /// skipped.
308    LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
309   
310    /// \brief Reads the line from the given stream.
311    ///
312    /// Reads the line from the given stream.
313    void read(std::istream& is, Value& value) {
314      if (skipSpaces) is >> std::ws;
315      if (!getline(is, value)) {
316        throw DataFormatError("LineReader forma error");
317      }
318    }
319  private:
320    bool skipSpaces;
321  };
322
323  /// \ingroup item_io
324  ///
325  /// \brief The default item reader template class.
326  ///
327  /// The default item reader template class. If some section reader
328  /// needs to read a value from a stream it will give the default way for it.
329  ///
330  /// \author Balazs Dezso
331  template <typename _Value>
332  class DefaultReader {
333  public:
334    /// The value type.
335    typedef _Value Value;
336    /// \brief Reads a value from the given stream.
337    ///
338    /// Reads a value from the given stream.
339    void read(std::istream& is, Value& value) const {
340      if (!(is >> value))
341        throw DataFormatError("DefaultReader format error");
342    }
343  };
344
345  template <>
346  class DefaultReader<std::string> {
347  public:
348    typedef std::string Value;
349   
350    void read(std::istream& is, Value& value) const {
351      char c;
352      if (!(is >> std::ws >> c)) return;
353      is.putback(c);
354      switch (c) {
355      case '\"':
356        QuotedStringReader().read(is, value);
357        break;
358      case '(':
359        ParsedStringReader().read(is, value);
360        break;
361      case '[':
362        ParsedStringReader('[', ']').read(is, value);
363        break;
364      case '/':
365        ParsedStringReader('/', '/').read(is, value);
366        break;
367      default:
368        if (!(is >> value))
369          throw DataFormatError("DefaultReader format error");
370        break;
371      }
372    }
373   
374  };
375
376  template <typename Item>
377  class DefaultReader<std::vector<Item> >
378    : public PushBackReader<std::vector<Item> > {};
379
380  template <typename Item>
381  class DefaultReader<std::deque<Item> >
382    : public PushBackReader<std::deque<Item> > {};
383
384  template <typename Item>
385  class DefaultReader<std::list<Item> >
386    : public PushBackReader<std::list<Item> > {};
387
388  template <typename Item>
389  class DefaultReader<std::set<Item> >
390    : public InsertReader<std::set<Item> > {};
391
392  template <typename Item>
393  class DefaultReader<std::multiset<Item> >
394    : public InsertReader<std::multiset<Item> > {};
395
396  /// \ingroup item_io
397  ///
398  /// \brief The default item reader for skipping a value in the stream.
399  ///
400  /// The default item reader for skipping a value in the stream.
401  ///
402  /// \author Balazs Dezso
403  class DefaultSkipper : public DefaultReader<std::string> {};
404
405  /// \ingroup item_io 
406  /// \brief Standard ReaderTraits for the GraphReader class.
407  ///
408  /// Standard ReaderTraits for the GraphReader class.
409  /// It defines standard reading method for all type of value.
410  /// \author Balazs Dezso
411  struct DefaultReaderTraits {
412
413    template <typename _Value>
414    struct Reader : DefaultReader<_Value> {};
415
416    typedef DefaultSkipper Skipper;
417
418  };
419
420}
421
422#endif
Note: See TracBrowser for help on using the repository browser.