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
5Copyright (C) 2006, 2010 Thomas Moor
6Copyright (C) 2006 Bernd Opitz
7Exclusive copyright is granted to Klaus Schmidt
8
9This library is free software; you can redistribute it and/or
10modify it under the terms of the GNU Lesser General Public
11License as published by the Free Software Foundation; either
12version 2.1 of the License, or (at your option) any later version.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public
20License along with this library; if not, write to the Free Software
21Foundation, 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
35namespace 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
65public:
66
67 /**
68 * Mode of operation: read from file, stdin, string or stream
69 */
70enum 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) */
558
559 /** State on entry of respective level */
560 struct LState {
561 std::string mLabel;
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
Class Token.
int Level(void) const
std::istringstream * mpSStream
std::istream * mpStream
std::vector< LState > mLevelState
Mode SourceMode(void) const

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen