LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiIoHandler.h

00001 /*
00002  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiIoHandler.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 7.12.2000
00030  * revisions ..: $Id: ltiIoHandler.h,v 1.10 2006/02/08 12:09:29 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_IO_HANDLER_H_
00034 #define _LTI_IO_HANDLER_H_
00035 
00036 
00037 #include "ltiObject.h"
00038 #include "ltiTypes.h"
00039 #include <string>
00040 #include <iostream> // required for method use()
00041 
00042 namespace lti {
00043   /**
00044    * Input/output handlers.
00045    *
00046    * The ioHandler classes offer an abstract interface for the functor
00047    * parameters and other lti::ioObject classes to read() and write() them in
00048    * different formats.  
00049    *
00050    * The LTI-Lib standard ioHandler is the lti::lispStreamHandler, which uses
00051    * a LISP-similar syntax to write and read data from streams.  To save space
00052    * and time while serializing objects, you can use the
00053    * lti::binaryStreamHandler.
00054    *
00055    * All ioHandlers are used as wrappers for std::istreams or std::ostreams
00056    * objects.  Therefore, the abstract interface provides the virtual methods
00057    * use() to indicate which stream has to be used.
00058    *
00059    * @ingroup gStorable
00060    */
00061   class ioHandler : public object {
00062   public:
00063 
00064     /**
00065      * default constructor
00066      */
00067     ioHandler();
00068 
00069     /**
00070      * copy constructor
00071      */
00072     ioHandler(const ioHandler& other);
00073 
00074     /**
00075      * destructor
00076      */
00077     virtual ~ioHandler();
00078 
00079     /**
00080      * returns the name of this type ("ioHandler")
00081      */
00082     virtual const char* getTypeName() const;
00083 
00084     /**
00085      * copy data of "other" functor.
00086      * @param other the functor to be copied
00087      * @return a reference to this functor object
00088      */
00089     ioHandler& copy(const ioHandler& other);
00090 
00091     /**
00092      * returns a pointer to a clone of this functor.
00093      */
00094     virtual ioHandler* clone() const = 0;
00095 
00096     /**
00097      * indicate the output stream to be used
00098      *
00099      * Calling this method you will reinitialize the state of the
00100      * parser (see also clear()).
00101      */
00102     virtual void use(std::ostream& aStream) = 0;
00103 
00104     /**
00105      * indicate the input stream to be used
00106      *
00107      * Calling this method you will reinitialize the state of the
00108      * parser (see also clear()).
00109      */
00110     virtual void use(std::istream& aStream) = 0;
00111 
00112     /**
00113      * write the begin token or tokens
00114      */
00115     virtual bool writeBegin();
00116 
00117     /**
00118      * write the end token or tokens
00119      */
00120     virtual bool writeEnd();
00121 
00122     /**
00123      * read the begin token or tokens
00124      */
00125     virtual bool readBegin();
00126 
00127     /**
00128      * read the end token or tokens
00129      */
00130     virtual bool readEnd();
00131 
00132     /** @name write members
00133      */
00134     //@{
00135     /**
00136      * write member for the standard types
00137      */
00138     virtual bool write(const std::string& data) = 0;
00139     virtual bool write(const char* data) = 0;
00140     virtual bool write(const double& data) = 0;
00141     virtual bool write(const float& data) = 0;
00142     virtual bool write(const int& data) = 0;
00143     virtual bool write(const unsigned int& data) = 0;
00144     virtual bool write(const char& data) = 0;
00145     virtual bool write(const byte& data) = 0;
00146     virtual bool write(const ubyte& data) = 0;
00147     virtual bool write(const bool& data) = 0;
00148     virtual bool write(const long& data) = 0;
00149     virtual bool write(const unsigned long& data) = 0;
00150     virtual bool write(const short& data) = 0;
00151     virtual bool write(const unsigned short& data) = 0;
00152     //@}
00153 
00154     //@{
00155     /**
00156      * write member for symbol-data pairs
00157      */
00158     virtual bool write(const std::string& name,const std::string& data);
00159     virtual bool write(const std::string& name,const char* data);
00160     virtual bool write(const std::string& name,const double& data);
00161     virtual bool write(const std::string& name,const float& data);
00162     virtual bool write(const std::string& name,const int& data);
00163     virtual bool write(const std::string& name,const unsigned int& data);
00164     virtual bool write(const std::string& name,const char& data);
00165     virtual bool write(const std::string& name,const byte& data);
00166     virtual bool write(const std::string& name,const ubyte& data);
00167     virtual bool write(const std::string& name,const bool& data);
00168     virtual bool write(const std::string& name,const long& data);
00169     virtual bool write(const std::string& name,const unsigned long& data);
00170     virtual bool write(const std::string& name,const short& data);
00171     virtual bool write(const std::string& name,const unsigned short& data);
00172     //@}
00173 
00174     /** @name read members
00175      */
00176     //@{
00177     /**
00178      * read members for the standard types
00179      */
00180     virtual bool read(std::string& data) = 0;
00181     virtual bool read(double& data) = 0;
00182     virtual bool read(float& data) = 0;
00183     virtual bool read(int& data) = 0;
00184     virtual bool read(unsigned int& data) = 0;
00185     virtual bool read(char& data) = 0;
00186     virtual bool read(byte& data) = 0;
00187     virtual bool read(ubyte& data) = 0;
00188     virtual bool read(bool& data) = 0;
00189     virtual bool read(long& data) = 0;
00190     virtual bool read(unsigned long& data) = 0;
00191     virtual bool read(short& data) = 0;
00192     virtual bool read(unsigned short& data) = 0;
00193     //@}
00194 
00195     //@{
00196     /**
00197      * read members for symbol-data pairs
00198      */
00199     virtual bool read(const std::string& name, std::string& data);
00200     virtual bool read(const std::string& name, double& data);
00201     virtual bool read(const std::string& name, float& data);
00202     virtual bool read(const std::string& name, int& data);
00203     virtual bool read(const std::string& name, unsigned int& data);
00204     virtual bool read(const std::string& name, char& data);
00205     virtual bool read(const std::string& name, byte& data);
00206     virtual bool read(const std::string& name, ubyte& data);
00207     virtual bool read(const std::string& name, bool& data);
00208     virtual bool read(const std::string& name, long& data);
00209     virtual bool read(const std::string& name, unsigned long& data);
00210     virtual bool read(const std::string& name, short& data);
00211     virtual bool read(const std::string& name, unsigned short& data);
00212     //@}
00213 
00214     /**
00215      * write a std::string as a symbol token.
00216      *
00217      * A symbol must not contain special characters or spaces.  Only letters
00218      * and numbers are allowed, and the first character must be a letter.
00219      *
00220      * @param data The symbol to be written
00221      */
00222     virtual bool writeSymbol(const std::string& data) = 0;
00223 
00224     /**
00225      * write comment writes the input data without any preprocessing,
00226      * just ensuring that the comment format is given
00227      */
00228     virtual bool writeComment(const std::string& data) = 0;
00229 
00230     /**
00231      * write comment writes the input data without any preprocessing,
00232      * just ensuring that the comment format is given
00233      */
00234     virtual bool writeComment(const char* data) = 0;
00235 
00236     /**
00237      * read a std::string as a symbol token
00238      *
00239      * A symbol must not contain special characters or spaces.  Only letters
00240      * and numbers are allowed, and the first character must be a letter.
00241      *
00242      * @param data the symbol readed will be left here
00243      */
00244     virtual bool readSymbol(std::string& data) = 0;
00245 
00246     /**
00247      * try to read the given symbol from the handler.
00248      * If present, returns true and the token is removed from the
00249      * handler, if not present returns false and leaves the handle as
00250      * it was before calling this member...
00251      *
00252      * A symbol must not contain special characters or spaces.  Only letters
00253      * and numbers are allowed, and the first character must be a letter.
00254      *
00255      * @param data the symbol to be readed
00256      */
00257     virtual bool trySymbol(const std::string& data) = 0;
00258 
00259     /**
00260      * try to read the begin token from the handler.
00261      * If present, returns true and the token is removed from the
00262      * handler, if not present returns false and leaves the handle as
00263      * it was before calling this member...
00264      */
00265     virtual bool tryBegin() = 0;
00266 
00267     /**
00268      * try to read the end token from the handler.
00269      * If present, returns true and the token is removed from the
00270      * handler, if not present returns false and leaves the handle as
00271      * it was before calling this member...
00272      */
00273     virtual bool tryEnd() = 0;
00274 
00275     /**
00276      * write spaces (default value 1)
00277      * The spaces are tokes that will be ignored by reading
00278      * @param s the number of space-tokens to be written
00279      */
00280     virtual bool writeSpaces(const int& s=1) = 0;
00281 
00282     /**
00283      * write end-of-line token
00284      * The EOL are tokes that will be ignored by reading
00285      */
00286     virtual bool writeEOL() = 0;
00287 
00288     /**
00289      * write key/value separator.
00290      * The key/value separator is the token which will separate a symbol from
00291      * its value in a symbol-data-pair.
00292      */
00293     virtual bool writeKeyValueSeparator() = 0;
00294 
00295     /**
00296      * write inter-data separator.
00297      * The data-separator token separates data elements in a data list or array
00298      */
00299     virtual bool writeDataSeparator() = 0;
00300 
00301     /**
00302      * read key/value separator token.
00303      */
00304     virtual bool readKeyValueSeparator() = 0;
00305 
00306     /**
00307      * read inter-data separator token.
00308      */
00309     virtual bool readDataSeparator() = 0;
00310 
00311     /**
00312      * return the actual nesting level vor begins and ends
00313      * Example
00314      * \code
00315      * ioHandler_childClass h; // h is an ioHandler of a childClass
00316      *                         // this could be for example a lispStreamHandler
00317      * int i;
00318      * i = h.getLevel(); // returns 0;
00319      * h.writeBegin();
00320      * i = h.getLevel(); // returns 1;
00321      * h.writeBegin();
00322      * i = h.getLevel(); // returns 2;
00323      * h.writeEnd();
00324      * i = h.getLevel(); // returns 1;
00325      * h.writeEnd();
00326      * i = h.getLevel(); // returns 0;
00327      * \endcode
00328      */
00329     virtual const int& getLevel() const;
00330 
00331     /**
00332      * restore all the information in the handler taken in the actual
00333      * level.
00334      */
00335     virtual bool restoreLevel() = 0;
00336 
00337     /**
00338      * usually this member is needed by reinitialization routines to set
00339      * the begin/end nesting level to zero.
00340      */
00341     virtual void resetLevel(const int& theLevel = 0);
00342 
00343     /**
00344      * @name Error Report
00345      */
00346     //@{
00347     /**
00348      * return the last message set with setStatusString().  This will
00349      * never return 0.  If no status-string has been set yet an empty string
00350      * (pointer to a string with only the char(0)) will be returned.
00351      */
00352     virtual const char* getStatusString() const;
00353 
00354     /**
00355      * set a status string.
00356      *
00357      * @param msg the const string to be reported next time by
00358      * getStatusString(). The given string will be copied.
00359      * This message will be usually set within the apply methods to indicate
00360      * an error cause.
00361      *
00362      * Note that the change of the status string is not considered as
00363      * a change in the functor status.
00364      */
00365     virtual void setStatusString(const char* msg) const;
00366 
00367     /**
00368      * set a status string.
00369      *
00370      * @param msg the const string to be reported next time by
00371      * getStatusString(). The given string will be copied.
00372      * This message will be usually set within the apply methods to indicate
00373      * an error cause.
00374      *
00375      * Note that the change of the status string is not considered as
00376      * a change in the functor status.
00377      */
00378     virtual void setStatusString(const std::string& msg) const;
00379 
00380     /**
00381      * append a message to the current status string. Take care to
00382      * reset the status string by calling setStatusString() for each
00383      * call of an apply() or similar method. appendStatusString()
00384      * should only be used after setStatusString() has been called.
00385      *
00386      * @param msg message to be appended to the current status string.
00387      *
00388      * Note that the change of the status string is not considered as
00389      * a change in the functor status.
00390      */
00391 
00392     virtual void appendStatusString(const char* msg) const;
00393 
00394     /**
00395      * append a message to the current status string. Take care to
00396      * reset the status string by calling setStatusString() for each
00397      * call of an apply() or similar method. appendStatusString()
00398      * should only be used after setStatusString() has been called.
00399      *
00400      * @param msg message to be appended to the current status string.
00401      *
00402      * Note that the change of the status string is not considered as
00403      * a change in the functor status.
00404      */
00405 
00406     virtual void appendStatusString(const std::string& msg) const;
00407 
00408     /**
00409      * append an integer value to the current status string. Take care
00410      * to reset the status string by calling setStatusString() for
00411      * each call of an apply() or similar method. appendStatusString()
00412      * should only be used after setStatusString() has been called.
00413      *
00414      * @param msg integer value to be appended to the current status
00415      * string.
00416      *
00417      * Note that the change of the status string is not considered as
00418      * a change in the functor status.
00419      */
00420     virtual void appendStatusString(const int& msg) const;
00421 
00422     /**
00423      * append a double value to the current status string. Take care
00424      * to reset the status string by calling setStatusString() for
00425      * each call of an apply() or similar method. appendStatusString()
00426      * should only be used after setStatusString() has been called.
00427      *
00428      * @param msg double value to be appended to the current status
00429      * string.
00430      *
00431      * Note that the change of the status string is not considered as
00432      * a change in the functor status.
00433      */
00434     virtual void appendStatusString(const double&  msg) const;
00435 
00436     /**
00437      * Append contextual information
00438      * 
00439      * This function should help the users to find errors in their files.
00440      * It just inserts some contextual information into the status string
00441      * to help localizing wrong data.
00442      *
00443      * It is useful for streams that can be edited by hand, because the
00444      * users will make errors!
00445      *
00446      * The default behaviour does nothing.
00447      */
00448     virtual void appendContextStatus() const;
00449     
00450     //@}
00451   protected:
00452     /**
00453      * begin() nesting level
00454      */
00455     int level;
00456 
00457   private:
00458     /**
00459      * the status string written with setStatusString
00460      */
00461     mutable char* statusString;
00462 
00463     /**
00464      * the empty string returned if the statusString is empty
00465      */
00466     static const char *const emptyString;
00467 
00468   };
00469 
00470   //@{
00471   /**
00472    * read functions for standard types
00473    */
00474   bool read(ioHandler& handler,std::string& data);
00475   bool read(ioHandler& handler,double& data);
00476   bool read(ioHandler& handler,float& data);
00477   bool read(ioHandler& handler,int& data);
00478   bool read(ioHandler& handler,unsigned int& data);
00479   bool read(ioHandler& handler,char& data);
00480   bool read(ioHandler& handler,byte& data);
00481   bool read(ioHandler& handler,ubyte& data);
00482   bool read(ioHandler& handler,bool& data);
00483   bool read(ioHandler& handler,long& data);
00484   bool read(ioHandler& handler,unsigned long& data);
00485   bool read(ioHandler& handler,short& data);
00486   bool read(ioHandler& handler,unsigned short& data);
00487   //@}
00488 
00489   //@{
00490   /**
00491    * write functions for standard types
00492    */
00493   bool write(ioHandler& handler,const std::string& data);
00494   bool write(ioHandler& handler,const char* data);
00495   bool write(ioHandler& handler,const double& data);
00496   bool write(ioHandler& handler,const float& data);
00497   bool write(ioHandler& handler,const int& data);
00498   bool write(ioHandler& handler,const unsigned int& data);
00499   bool write(ioHandler& handler,const char& data);
00500   bool write(ioHandler& handler,const byte& data);
00501   bool write(ioHandler& handler,const ubyte& data);
00502   bool write(ioHandler& handler,const bool& data);
00503   bool write(ioHandler& handler,const long& data);
00504   bool write(ioHandler& handler,const unsigned long& data);
00505   bool write(ioHandler& handler,const short& data);
00506   bool write(ioHandler& handler,const unsigned short& data);
00507   //@}
00508 
00509   /**
00510    * handler functions with standard storable interface
00511    */
00512   template <class T>
00513   bool write(ioHandler& handler,const std::string& name,
00514              const T& data,const bool complete=true) {
00515 
00516     if (complete) {
00517       handler.writeBegin();
00518     }
00519     handler.writeSymbol(name);
00520     handler.writeKeyValueSeparator();
00521     write(handler,data);
00522     if (complete) {
00523       handler.writeEnd();
00524     }
00525     return handler.writeEOL();
00526   };
00527 
00528   /**
00529    * handler functions with standard storable interface
00530    */
00531   template <class T>
00532   bool read(ioHandler& handler,const std::string& name,
00533              T& data,const bool complete=true) {
00534     int level = handler.getLevel();
00535     bool result = true;
00536 
00537     if (complete) {
00538       result = handler.readBegin();
00539     }
00540 
00541     if (result && handler.trySymbol(name)) {
00542       result = result && handler.readKeyValueSeparator();
00543 
00544       result = result && read(handler,data);
00545 
00546       if (complete) {
00547         result = result && handler.readEnd();
00548       }
00549 
00550       while (result && (handler.getLevel() > level)) {
00551         result = result && handler.readEnd();
00552       }
00553 
00554     } else {
00555       result=false;
00556       handler.appendStatusString("\nSymbol " + name + " not found: ");
00557       handler.appendContextStatus();
00558       handler.restoreLevel();
00559     }
00560 
00561     return result;
00562   };
00563 
00564 }
00565 
00566 #endif

Generated on Sat Apr 10 15:25:40 2010 for LTI-Lib by Doxygen 1.6.1