cfl_tokenreader.h
Go to the documentation of this file.
1 /** @file cfl_tokenreader.h @brief Class TokenReader */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5 Copyright (C) 2006, 2010 Thomas Moor
6 Copyright (C) 2006 Bernd Opitz
7 Exclusive copyright is granted to Klaus Schmidt
8 
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13 
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18 
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 
24 
25 #ifndef FAUDES_TOKENREADER_H
26 #define FAUDES_TOKENREADER_H
27 
28 
29 #include <vector>
30 
31 #include "cfl_definitions.h"
32 #include "cfl_exception.h"
33 #include "cfl_token.h"
34 
35 namespace faudes {
36 
37 /**
38  * A TokenReader reads sequential tokens from a file or string. It can get or peek
39  * the next token and it will track line numbers for informative diagnosis output.
40  *
41  * The token stream is meant to be XML compliant, i.e., there are two dedicated
42  * token types that mark the begin and the end of XML elements while all other token
43  * types represent atomic data such as integers or strings that form the XML character data;
44  * see the documentation of the class Token for details.
45  *
46  * The TokenReader maintains a current position in the stream and implements searching
47  * within nested elements and for sequential access of the tokens within each element;
48  * e.g. ReadBegin(const std::string&) will search for the element with the specified name.
49  *
50  * Reading from the Tokenreader by a particular method encodes the type of the
51  * requested data, e.g. ReadInteger() to read an integer token. If the token at the
52  * current position does not match the requiested type, an exception is thrown.
53  * There are alose Get() and Peek() methods to retrieve and inspect the token at the current
54  * position.
55  *
56  * For convenience, the TokenReader also implements reading all contents of an alement
57  * and larger chunks of data formtated as CDATA markup within an element; e.g.
58  * ReadVerbatim(const std::string&, std::string&) reads the contents of the specified element
59  * en block as one string.
60  *
61  * @ingroup TokenIO
62  */
63 
65 public:
66 
67  /**
68  * Mode of operation: read from file, stdin, string or stream
69  */
70 enum Mode {File, Stdin, String, Stream};
71 
72  /**
73  * TokenReader constructor
74  *
75  * @param mode
76  * select source: File, Stdin or String
77  * @param rInString
78  * string to read from or filename, respectively.
79  *
80  * @exception Exception
81  * - faudes::Exception ios error opening file (id 1)
82  * - faudes::Exception invalid mode (Stdin not implemented) (id 1)
83  */
84  TokenReader(Mode mode, const std::string& rInString="");
85 
86  /**
87  * Creates a TokenReader for reading a file.
88  *
89  * This is a convenience wrapper for TokenReader(Mode, const std::string&).
90  *
91  * @param rFilename
92  * file to read
93  *
94  * @exception Exception
95  * - faudes::Exception ios error opening file (id 1)
96  */
97  TokenReader(const std::string& rFilename);
98 
99 
100  /**
101  * TokenReader constructor from anonymous stream
102  *
103  * @param rStream
104  * stream to read from
105  *
106  * @exception Exception
107  * - faudes::Exception ios error stream is bad (id 1)
108  */
109  TokenReader(std::istream& rStream);
110 
111  /**
112  * Destruct
113  */
114  ~TokenReader(void);
115 
116  /**
117  * Rewind stream
118  *
119  * Reset the internal state to its initial value, i.e., the
120  * current position is the beginning of the stream. This is
121  * not functional in console mode.
122  *
123  * @exception Exception
124  * - faudes::Exception ios error reading file (id 1)
125  */
126  void Rewind(void);
127 
128  /**
129  * Access C++ stream
130  *
131  * This method provides direct access to the underlying C++ stream.
132  * After any such access, the TokenReader must be Rewind() to reset
133  * its internal state.
134  *
135  * @return
136  * pointer to C++ input stream
137  */
138  std::istream* Streamp(void);
139 
140  /**
141  * Access stream mode.
142  *
143  * Returns mode from construction, i.e. file, string or console.
144  *
145  * @return
146  * Mode
147  */
148  Mode SourceMode(void) const { return mMode;};
149 
150  /**
151  * Access the filename.
152  *
153  * Returns the name of the attached file, if any. For string mode and
154  * console mode dummy values are returned.
155  *
156  * @return
157  * filename
158  */
159  std::string FileName(void) const;
160 
161  /**
162  * Peek next token.
163  *
164  * Copies the next token to the provided reference and returns
165  * true on success. The token remains in an internal buffer.
166  *
167  * Technical note: we should have used a const-ref as return
168  * in orde to avoid the copy. However, this will require a tedious
169  * rewrite.
170  *
171  * @param token
172  * reference to token
173  * @return
174  * true for a valid token, false for eof or other stream errors
175  *
176  * @exception Exception
177  * - faudes::Exception ios error reading file (id 1)
178  *
179  */
180  bool Peek(Token& token);
181 
182  /**
183  * Get next token.
184  *
185  * Same as Peek() except that the token is removed from the buffer.
186  *
187  * @param token
188  * Reference to token
189  *
190  * @exception Exception
191  * faudes exception ios (id 1)
192  *
193  * @return
194  * true for a valid token, false for eof or other stream errors
195  */
196  bool Get(Token& token);
197 
198 
199  /**
200  * Search for specified element
201  *
202  * This function searches for the specified section on the current level.
203  * It skips any sections on the levels below, and it will wrap to the begin
204  * of the current section once. In the case of success, it returns true, else
205  * false. In contrast to other token i/o methodes, this method will not throw
206  * any execptions.
207  *
208  * In the case of success, the next token is the begin-tag of the specified element,
209  * which can be read with ReadBegin().
210  *
211  * @param rLabel
212  * Token label to specify section
213  *
214  * @return
215  * True if sectiob exists
216  *
217  */
218  bool ExistsBegin(const std::string& rLabel);
219 
220  /**
221  * Open a section by specified label. This function searches
222  * for the section on this level, it skips any sections on levels
223  * below this level, and it will wrap once to the begin of the current
224  * section. In the case of success, the matching begin token is the
225  * last token read. After processing the section, a matching ReadEnd(label)
226  * must be called. If the specified element does not exist, an exception is thrown.
227  *
228  * @param rLabel
229  * Token label to specify section
230  *
231  * @exception Exception
232  * - faudes::Exception ios error reading file (id 1)
233  * - Section begin label not found (id 51)
234  *
235  */
236  void ReadBegin(const std::string& rLabel);
237 
238  /**
239  * Open a section by specified label.
240  *
241  * This wrapper ReadBegin(const std::string&) will return the actual
242  * begin tag in its second argument, e.g., to inspect XML attributes.
243  *
244  * @param rLabel
245  * Token label to specify section
246  * @param rToken
247  * Begin tag as found in token stream.
248  *
249  * @exception Exception
250  * - faudes::Exception ios error reading file (id 1)
251  * - Section begin label not found (id 51)
252  *
253  */
254  void ReadBegin(const std::string& rLabel, Token& rToken);
255 
256  /**
257  * Close the current section by matching the previous ReadBegin().
258  * Reads all tokens up to and including end of current section.
259  *
260  * @param rLabel
261  * Token label to specify section
262  *
263  * @exception Exception
264  * - faudes::Exception ios error reading file (id 1)
265  * - Section end label not found (id 51)
266  *
267  */
268  void ReadEnd(const std::string& rLabel);
269 
270  /**
271  * Find specified begin label.
272  *
273  * This function searches for the section on this level and any descending level.
274  * It does not read the specified section tag, but stops just
275  * one token before (and in this regard matches the behaviour of ExistsBegin()).
276  *
277  * Technical note:
278  * Former versions of libFAUDES also read the actual begin token and
279  * required a matching call of SeekEnd(). As of version 2.18a, this is not
280  * supported anymore. The previous behaviour was rarely needed and can be
281  * mimiqued by an ordinary ReadEnd() with a subsequent Recover(level).
282  *
283  * @param rLabel
284  * Label to specify section
285  *
286  * @exception Exception
287  * - faudes::Exception ios error reading file (id 1)
288  * - Section begin not found (id 51)
289  *
290  */
291  void SeekBegin(const std::string& rLabel);
292 
293  /**
294  * Find specified begin label.
295  *
296  * This version SeekBegin(const std::string&) will return the actual
297  * begin tag in its second argument.
298  *
299  * @param rLabel
300  * Token label to specify section
301  * @param rToken
302  * Begin tag as found in token stream.
303  *
304  * @exception Exception
305  * - faudes::Exception ios error reading file (id 1)
306  * - Section begin label not found (id 51)
307  *
308  */
309  void SeekBegin(const std::string& rLabel, Token& rToken);
310 
311  /**
312  * Peek a token and check whether it ends the specified section.
313  * This function is meant for scanning a section with a while- construct.
314  * \code
315  * ReadBegin("MySec");
316  * while(!Eos("MySec")) {
317  * ...
318  * };
319  * ReadEnd("MySec");
320  * \endcode
321  *
322  * @param rLabel
323  * Token label to specify section
324  *
325  * @exception Exception
326  * - faudes::Exception ios error reading file (id 1)
327  * - unexpected eof or section mismatch (id 51)
328  *
329  * @return
330  * True at end of section
331  */
332  bool Eos(const std::string& rLabel);
333 
334  /**
335  * Read integer token
336  *
337  * Reads the next token and interprets it as an non-negative integer.
338  *
339  * @exception Exception
340  * - faudes::Exception ios error reading file (id 1)
341  * - Token mismatch (id 50)
342  *
343  * @return
344  * value of integer token
345  */
346  long int ReadInteger(void);
347 
348  /**
349  * Read float token
350  *
351  * Reads the next token and interprets it as a float.
352  *
353  * @exception Exception
354  * - faudes::Exception ios error reading file (id 1)
355  * - Token mismatch (id 50)
356  *
357  * @return
358  * float value of token
359  */
360  double ReadFloat(void);
361 
362  /**
363  * Read string token
364  *
365  * Reads the next token and interprets it as a string.
366  *
367  * @exception Exception
368  * - faudes::Exception ios error reading file (id 1)
369  * - Token mismatch (id 50)
370  *
371  * @return
372  * value of name token
373  */
374  std::string ReadString(void);
375 
376  /**
377  * Read option token
378  *
379  * Reads the next token and interprets it as an option.
380  *
381  * @exception Exception
382  * - faudes::Exception ios error reading file (id 1)
383  * - Token mismatch (id 50)
384  *
385  * @return
386  * value of name token
387  */
388  std::string ReadOption(void);
389 
390  /**
391  * Read binary token.
392  *
393  * Reads the next token and interprets it as an base64
394  * encoded binary array.
395  *
396  * @param rData
397  * Buffer to read data
398  *
399  * @exception Exception
400  * - faudes::Exception ios error reading file (id 1)
401  * - Token mismatch (id 50)
402  *
403  */
404  void ReadBinary(std::string& rData);
405 
406 
407  /**
408  * Read plain text
409  *
410  * Interpret the specified section as plain charater data section, read
411  * the character data and interpret relevant entities. Leading and trailing
412  * whitespaces are ignored, other formating is maintained.
413  *
414  * This method facilitates the input of paragraphs of plain ASCII text with
415  * no other markup as the relevant entities (i.e. no HTML or RTF).
416  *
417  * @exception Exception
418  * - faudes::Exception ios error reading file (id 1)
419  * - Stream mismatch (id 50)
420  *
421  * @param rLabel
422  * Buffer to read Text
423  * @param rText
424  * Name of section to read text from
425  */
426  void ReadText(const std::string& rLabel, std::string& rText);
427 
428 
429  /**
430  * Read verbatim text
431  *
432  * Interpret the section as plain charater data section, read
433  * the character data from either one faudes string token or from consecutive CDATA markups.
434  * Leading and trailing whitespaces are ignored, other formating is maintained.
435  *
436  * This method facilitates the input of paragraphs of plain ASCII text with
437  * excessive use of special characters, e.g., program fragments.
438  *
439  * @exception Exception
440  * - faudes::Exception ios error reading file (id 1)
441  * - Stream mismatch (id 50)
442  *
443  * @param rLabel
444  * Buffer to read Text
445  * @param rText
446  * Name of section to read text from
447  */
448  void ReadVerbatim(const std::string& rLabel, std::string& rText);
449 
450 
451  /**
452  * Read plain text
453  *
454  * Read all text until and excluding the next markup tag. This method
455  * does no interpretation/substitution at all. It is meant to implemet carbon
456  * copy of text sections.
457  *
458  * @exception Exception
459  * - faudes::Exception ios error reading file (id 1)
460  * - Stream mismatch (id 50)
461  *
462  * @param rData
463  * Buffer to read characterdata
464  */
465  void ReadCharacterData(std::string& rData);
466 
467 
468  /**
469  * Read XML section
470  *
471  * Reads the current element, including all character data and markup,
472  * until and excluding the matching end tag. This method does no interpretation whatsoever.
473  * The result is a string that represents the respective section in plain XML format
474  * and can be used for expernal post-processing.
475  *
476  * @exception Exception
477  * - faudes::Exception ios error reading file (id 1)
478  * - Stream mismatch (id 50)
479  *
480  * @param rSectionString
481  * Buffer to read section
482  */
483  void ReadSection(std::string& rSectionString);
484 
485 
486  /** Operator for get */
487  bool operator >> (Token& token) {
488  return Get(token);
489  }
490 
491  /**
492  * Return number of lines read
493  *
494  * @return
495  * Number of lines read
496  */
497  int Line(void) const;
498 
499  /**
500  * Return current level of section nesting.
501  *
502  * @return
503  * Number of lines read
504  */
505  int Level(void) const { return mLevel;};
506 
507  /**
508  * Recover by skipping tokens until returning to the specified level of section nesting
509  *
510  * @return
511  * True on success
512  */
513  bool Recover(int level);
514 
515  /**
516  * Reset to the begining of the specified level of section nesting.
517  *
518  * @param level
519  * target level, defaults to current level
520  * @return
521  * True on success
522  */
523  bool Reset(int level=-1);
524 
525  /**
526  * Return "filename:line"
527  */
528  std::string FileLine(void) const;
529 
530  private:
531 
532  /** input mode */
534 
535  /** istream object pointer */
536  std::istream* mpStream;
537 
538  /** actual stream object, file input */
539  std::ifstream mFStream;
540 
541  /** actual stream object on heap, string input */
542  std::istringstream* mpSStream;
543 
544  /** Filename */
545  std::string mFileName;
546 
547  /** Line counter */
549 
550  /** file position */
551  long int mFilePos;
552 
553  /** flag to ignore faudes comments marked by '%' */
555 
556  /** Level (of nested sections) */
557  int mLevel;
558 
559  /** State on entry of respective level */
560  struct LState {
561  std::string mLabel;
562  long int mStartPosition;
563  long int mStartLine;
566  };
567  std::vector<LState> mLevelState;
568 
569  /** peek buffer */
571 };
572 
573 } // namespace faudes
574 
575 #endif
#define FAUDES_API
Definition: cfl_platform.h:80
Class Token.
int Level(void) const
std::istringstream * mpSStream
std::istream * mpStream
std::ifstream mFStream
std::vector< LState > mLevelState
Mode SourceMode(void) const

libFAUDES 2.33h --- 2025.06.18 --- c++ api documentaion by doxygen