cfl_tokenreader.h

Go to the documentation of this file.
00001 /** @file cfl_tokenreader.h @brief Class TokenReader */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2006  Bernd Opitz
00006 Exclusive copyright is granted to Klaus Schmidt
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021 
00022 
00023 
00024 #ifndef FAUDES_TOKENREADER_H
00025 
00026 #include <vector>
00027 
00028 #include "cfl_definitions.h"
00029 #include "cfl_exception.h"
00030 #include "cfl_token.h"
00031 
00032 namespace faudes {
00033 
00034 /**
00035  * A TokenReader reads sequential tokens from a file or string. It can get or peek
00036  * the next token and it will track line numbers for informative diagnosis output.
00037  *
00038  * The class also implements nested sections. That is, you may search for a
00039  * (sub-)section within the current section and, hence, implement file formats that 
00040  * do not insist in a particular ordering of the sections (e.g. a Generator
00041  * consists of states, transitions and events, no matter in which order).
00042  *
00043  * Convenience functions are provided to read a token of a particular type and
00044  * throws faudes::Exception on token mismatch. You may catch the exception 
00045  * as follows:
00046  * \code 
00047  * try {
00048  *   some tokenreader operations
00049  * }
00050  * catch (faudes::Exception& ex) {
00051  *   cerr << "Error reading file (details: " << ex.What() << ")" << endl;
00052  * }
00053  * \endcode
00054  * Note that in addition to the documented execeptions all TokenReader functions 
00055  * do pass on faudes ios errors from the Token class.
00056  * 
00057  * @ingroup TokenIO
00058  */
00059 
00060 class TokenReader {
00061 public:
00062 
00063   /**
00064    * Mode of operation: read from file, stdin or string
00065    */
00066   enum Mode {File, Stdin, String};
00067 
00068   /**
00069    * TokenReader constructor
00070    *
00071    * @param mode
00072    *   select source: File, Stdin or String
00073    * @param rInString
00074    *   string to read from or filename
00075    *
00076    * @exception Exception
00077    *   - faudes::Exception ios error opening file (id 1)
00078    *   - faudes::Exception invalid mode (Stdin not implemented) (id 1)
00079    */
00080   TokenReader(Mode mode, const std::string& rInString="");
00081 
00082   /**
00083    * Creates a TokenReader for reading a file.
00084    *
00085    * @param rFilename
00086    *   File to read
00087    *
00088    * @exception Exception
00089    *   - faudes::Exception ios error opening file (id 1)
00090    */
00091   TokenReader(const std::string& rFilename);
00092 
00093 
00094   /**
00095    * Destruct
00096    */
00097   ~TokenReader(void);
00098 
00099   /** 
00100    * Access C++ stream
00101    *
00102    */
00103   std::istream* Streamp(void);
00104 
00105   /**
00106    * Get state of TokenReader stream
00107    *
00108    * @return
00109    *   std::stream.good()
00110    */
00111   bool Good(void) const;
00112 
00113   /**
00114    * Get the filename.
00115    * Returns dummy values for console or string mode.
00116    * 
00117    * @return 
00118    *   Filename
00119    */
00120   std::string FileName(void) const;
00121 
00122   /**
00123    * Get file mode.
00124    * 
00125    * @return 
00126    *   Mode
00127    */
00128   Mode SourceMode(void) const { return mMode;};
00129 
00130   /**
00131    * Peek next token. False indicates eof.
00132    *
00133    * @param token
00134    *   Reference to token
00135    * 
00136    * @exception Exception
00137    *   - faudes::Exception ios error reading file (id 1)
00138    *
00139    * @return
00140    *   True for a valid token, false for eof
00141    */
00142   bool Peek(Token& token);
00143 
00144   /**
00145    * Get next token. False indicates eof.
00146    *
00147    * @param token
00148    *   Reference to token
00149    * 
00150    * @exception Exception
00151    *   faudes exception ios (id 1)
00152    *
00153    * @return
00154    *   True for a valid token, false for eof
00155    */
00156   bool Get(Token& token);
00157 
00158   /**
00159    * Rewind stream (must be a seekable stream)
00160    *
00161    * @exception Exception
00162    *   - faudes::Exception ios error reading file (id 1)
00163    */
00164   void Rewind(void);
00165 
00166   /**
00167    * This function searches for the specified section on the current level, 
00168    * it skips any sections on levels below, and it will wrap to the begin 
00169    * of the current section. In the case of success, it returns true, else
00170    * false. In contrast to other token i/o methodes, this method will not throw
00171    * any execptions.
00172    *
00173    * @param rLabel
00174    *   Token label to specify section
00175    *
00176    * @return
00177    *   True if sectiob exists
00178    *
00179    */
00180   bool ExistsBegin(const std::string& rLabel);
00181 
00182   /**
00183    * Open a section by specified label. This function searches
00184    * for the section on this level, it skips any sections on levels
00185    * below this level, and it will wrap to the begin of the current 
00186    * section. In the case of success, the matching begin token is the 
00187    * last token read. After processing the section, a matching ReadEnd(label) 
00188    * must be called.
00189    *
00190    * @param rLabel
00191    *   Token label to specify section
00192    *
00193    * @exception Exception
00194    *   Section begin label not found (id 51)
00195    *
00196    */
00197   void ReadBegin(const std::string& rLabel);
00198 
00199   /**
00200    * Open a section by specified label. 
00201    *
00202    * This version ReadBegin(const std::string&) will return the actual
00203    * begin tag in its second argument.
00204    *
00205    * @param rLabel
00206    *   Token label to specify section
00207    * @param rToken
00208    *   Begin tag as found in token stream.
00209    *
00210    * @exception Exception
00211    *   Section begin label not found (id 51)
00212    *
00213    */
00214   void ReadBegin(const std::string& rLabel, Token& rToken);
00215 
00216   /**
00217    * Close the current section by matching the previous ReadBegin(). 
00218    * Reads all tokens up to and including end of current section.
00219    *
00220    * @param rLabel
00221    *   Token label to specify section
00222    *
00223    * @exception Exception
00224    *   Section end label not found (id 51)
00225    *
00226    */
00227   void ReadEnd(const std::string& rLabel);
00228 
00229   /**
00230    * Find specified begin label.
00231    * This function searches
00232    * for the section on this level and any descending level. 
00233    * It does not read the specified section tag, but stops just
00234    * one token before.
00235    *
00236    * Technical note:
00237    * Former versions of libFAUDES also read the actual begin token and
00238    * required a matching call of SeekEnd(). As of version 2.18a, this is not
00239    * supported anymore. The previous behaviour was rarely needed and can be
00240    * mimiqued by an ordinary ReadEnd() with a subsequent Recover(level).
00241    *
00242    * @param rLabel
00243    *   Label to specify section
00244    *
00245    * @exception Exception
00246    *   Section begin not found (id 51)
00247    *
00248    */
00249   void SeekBegin(const std::string& rLabel);
00250 
00251   /**
00252    * Find specified begin label.
00253    *
00254    * This version SeekBegin(const std::string&) will return the actual
00255    * begin tag in its second argument.
00256    *
00257    * @param rLabel
00258    *   Token label to specify section
00259    * @param rToken
00260    *   Begin tag as found in token stream.
00261    *
00262    * @exception Exception
00263    *   Section begin label not found (id 51)
00264    *
00265    */
00266   void SeekBegin(const std::string& rLabel, Token& rToken);
00267 
00268   /**
00269    * Peek a token and check whether it ends the specified section.
00270    * This function is meant for scanning a section with a while- construct.
00271    * \code
00272    * SeekBegin("MySec"); 
00273    * while(!Eos("MySec")) { 
00274    *   ... 
00275    * }; 
00276    * SeekEnd("MySec");
00277    * \endcode
00278    *
00279    * @param rLabel
00280    *   Token label to specify section
00281    *
00282    * @exception Exception
00283    *   Unexpected eof (id 51)
00284    *
00285    * @return
00286    *   True at end of section
00287    */
00288   bool Eos(const std::string& rLabel);
00289 
00290   /**
00291    * Read integer  token
00292    *      
00293    * @exception Exception
00294    *   Token mismatch (id 50)
00295    *
00296    * @return
00297    *   value of index token
00298    */
00299   long int ReadInteger(void);
00300 
00301   /**
00302    * Read float token
00303    *      
00304    * @exception Exception
00305    *   Token mismatch (id 50)
00306    *
00307    * @return
00308    *   value of index token
00309    */
00310   double ReadFloat(void);
00311 
00312   /**
00313    * Read string token
00314    *      
00315    * @exception Exception
00316    *   Token mismatch (id 50)
00317    *
00318    * @return
00319    *   value of name token
00320    */
00321   const std::string& ReadString(void);
00322 
00323   /**
00324    * Read option token
00325    *      
00326    * @exception Exception
00327    *   Token mismatch (id 50)
00328    *
00329    * @return
00330    *   value of name token
00331    */
00332   const std::string& ReadOption(void);
00333 
00334   /**
00335    * Read binary token. You can access the binary array
00336    * via StringValue();
00337    *      
00338    * @return
00339    *   Binary data as std::string
00340    * @exception Exception
00341    *   Token mismatch (id 50)
00342    *
00343    */
00344   const std::string& ReadBinary(void);
00345 
00346 
00347   /**
00348    * Read plain text
00349    *      
00350    * Read all text until and excluding the next markup.
00351    * This method interprets known enteties and swallows
00352    * beginning and ending white space. Effetively, ot is used
00353    * to read ASCII compatible text.
00354    *
00355    * @exception Exception
00356    *   Stream mismatch (id 50)
00357    *
00358    * @return
00359    *   Text read.
00360    */
00361   const std::string& ReadText(void);
00362 
00363 
00364   /**
00365    * Read plain text
00366    *      
00367    * Read all text until and excluding the next markup.
00368    * This method does no interpretation whatever. It can be used
00369    * to implement carbon copy of text sections.
00370    *
00371    * @exception Exception
00372    *   Stream mismatch (id 50)
00373    *
00374    * @return
00375    *   Text read.
00376    */
00377   const std::string& ReadCharacterData(void);
00378 
00379   /**
00380    * Read XML section
00381    *      
00382    * Reads the current section, including all character data and markup, 
00383    * until and excluding the matching end tag. This method does no interpretation whatever.
00384    * the result is a string that represents
00385    * the respective section in XML format.
00386    *
00387    * @exception Exception
00388    *   Stream mismatch (id 50)
00389    * @return
00390    *   Text read.
00391    */
00392   const std::string& ReadSection(void);
00393 
00394 
00395   /** Operator for get */
00396   bool operator >> (Token& token) {
00397     return Get(token);
00398   }
00399 
00400   /**
00401    * Return number of lines read
00402    * 
00403    * @return
00404    *   Number of lines read
00405    */ 
00406   int Line(void) const;
00407 
00408   /**
00409    * Return current level of section nesting
00410    * 
00411    * @return
00412    *   Number of lines read
00413    */ 
00414   int Level(void) const { return mLevel;};
00415 
00416   /**
00417    * Recover to specified section nesting
00418    *
00419    * The current implementation will mess up the Seek-stack. Thus,
00420    * Recover() only works when no Seekbegin() was used.
00421    * 
00422    * @return
00423    *   True on success
00424    */ 
00425   bool Recover(int level);
00426 
00427   /**
00428    * Return "filename:line"
00429    */
00430   std::string FileLine(void) const;
00431 
00432  private:
00433 
00434   /** input mode */
00435   Mode mMode;
00436 
00437   /** istream object pointer */
00438   std::istream* mpStream;
00439 
00440   /** actual stream object, file input  */
00441   std::ifstream mFStream;
00442 
00443   /** actual stream object on heap, string input  */
00444   std::istringstream* mpSStream;
00445 
00446   /** Filename */
00447   std::string mFileName;
00448 
00449   /** Line counter */
00450   int mLineCount;
00451 
00452   /** file position */
00453   long int mFilePos;
00454 
00455   /** Level (of nested sections)*/
00456   int mLevel;
00457 
00458   /** label of sections */
00459   std::vector<std::string> mLevelLabel;
00460 
00461   /** file positions of sections */
00462   std::vector<long int> mLevelPos;
00463 
00464   /** file line of sections */
00465   std::vector<long int> mLevelLine;
00466 
00467   /** level of recent seek */
00468   std::vector<int> mSeekLevel;
00469 
00470   /** recent string buffer */
00471   std::string mLastString;
00472 
00473   /** peek buffer */
00474   Token mPeekToken;
00475 };
00476 
00477 } // namespace faudes
00478 
00479 #define FAUDES_TOKENREADER_H
00480 #endif 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen