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

ltiConfigFileHandler.h

00001 /*
00002  * Copyright (C) 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 .......: ltiConfigFile.h
00027  * authors ....: Ruediger Weiler, Joerg Zieren
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 23.10.2001
00030  * revisions ..: $Id: ltiConfigFileHandler.h,v 1.10 2006/02/08 12:02:22 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_CONFIG_FILE_HANDLER_H_
00034 #define _LTI_CONFIG_FILE_HANDLER_H_
00035 
00036 #include "ltiObject.h"
00037 #include <list>
00038 #include <map>
00039 #include <string>
00040 #include "ltiIOFunctor.h"
00041 
00042 namespace lti {
00043   /**
00044    * Write and read config files, similar to windows ini files. These contain:
00045    * - sections
00046    * - keys
00047    * - values
00048    * - comments
00049    *
00050    * All entries will be written as specified, however
00051    * searching keys or values is case insensitive!
00052    *
00053    * Example config file:
00054    * \code
00055    *  # a global comment
00056    *
00057    *  *
00058    *  * comments in cvs style are alowed too
00059    *  *
00060    *
00061    *  [a section]
00062    *  # a section comment
00063    *  key = value ; a key comment
00064    *
00065    *  [another section] ;more comments
00066    *  key = value
00067    * \endcode
00068    *
00069    * Comments can be global, for sections or for single keys.
00070    * A section comment must be positioned before the first key
00071    * of this section. Comments for keys start with ';'
00072    *
00073    */
00074   class configFileHandler : public ioFunctor {
00075   public:
00076     /**
00077      * the parameters for the class configFileHandler
00078      */
00079     class parameters : public ioFunctor::parameters {
00080     public:
00081       /**
00082        * default constructor
00083        */
00084       parameters();
00085 
00086       /**
00087        * copy constructor
00088        * @param other the parameters object to be copied
00089        */
00090       parameters(const parameters& other);
00091 
00092       /**
00093        * destructor
00094        */
00095       ~parameters();
00096 
00097       /**
00098        * returns name of this type
00099        */
00100       const char* getTypeName() const;
00101 
00102       /**
00103        * copy the contents of a parameters object
00104        * @param other the parameters object to be copied
00105        * @return a reference to this parameters object
00106        */
00107       parameters& copy(const parameters& other);
00108 
00109       /**
00110        * copy the contents of a parameters object
00111        * @param other the parameters object to be copied
00112        * @return a reference to this parameters object
00113        */
00114       parameters& operator=(const parameters& other);
00115 
00116 
00117       /**
00118        * returns a pointer to a clone of the parameters
00119        */
00120       virtual functor::parameters* clone() const;
00121 
00122       /**
00123        * write the parameters in the given ioHandler
00124        * @param handler the ioHandler to be used
00125        * @param complete if true (the default) the enclosing begin/end will
00126        *        be also written, otherwise only the data block will be written.
00127        * @return true if write was successful
00128        */
00129       virtual bool write(ioHandler& handler,const bool complete=true) const;
00130 
00131       /**
00132        * read the parameters from the given ioHandler
00133        * @param handler the ioHandler to be used
00134        * @param complete if true (the default) the enclosing begin/end will
00135        *        be also written, otherwise only the data block will be written.
00136        * @return true if write was successful
00137        */
00138       virtual bool read(ioHandler& handler,const bool complete=true);
00139 
00140 #     ifdef _LTI_MSC_6
00141       /**
00142        * this function is required by MSVC only, as a workaround for a
00143        * very awful bug, which exists since MSVC V.4.0, and still by
00144        * V.6.0 with all bugfixes (so called "service packs") remains
00145        * there...  This method is also public due to another bug, so please
00146        * NEVER EVER call this method directly: use read() instead
00147        */
00148       bool readMS(ioHandler& handler,const bool complete=true);
00149 
00150       /**
00151        * this function is required by MSVC only, as a workaround for a
00152        * very awful bug, which exists since MSVC V.4.0, and still by
00153        * V.6.0 with all bugfixes (so called "service packs") remains
00154        * there...  This method is also public due to another bug, so please
00155        * NEVER EVER call this method directly: use write() instead
00156        */
00157       bool writeMS(ioHandler& handler,const bool complete=true) const;
00158 #     endif
00159 
00160       // ------------------------------------------------
00161       // the parameters
00162       // ------------------------------------------------
00163 
00164       /**
00165        * Should output be formatted for better readability? (default=true)
00166        */
00167       bool formatOutput;
00168     };
00169 
00170     /**
00171      * default constructor
00172      */
00173     configFileHandler();
00174 
00175     /**
00176      * copy constructor
00177      * @param other the object to be copied
00178      */
00179     configFileHandler(const configFileHandler& other);
00180 
00181     /**
00182      * destructor
00183      */
00184     virtual ~configFileHandler();
00185 
00186     /**
00187      * returns the name of this type ("configFileHandler")
00188      */
00189     virtual const char* getTypeName() const;
00190 
00191     /**
00192      * copy data of "other" functor.
00193      * @param other the functor to be copied
00194      * @return a reference to this functor object
00195      */
00196     configFileHandler& copy(const configFileHandler& other);
00197 
00198     /**
00199      * alias for copy member
00200      * @param other the functor to be copied
00201      * @return a reference to this functor object
00202      */
00203     configFileHandler& operator=(const configFileHandler& other);
00204 
00205     /**
00206      * returns a pointer to a clone of this functor.
00207      */
00208     virtual functor* clone() const;
00209 
00210     /**
00211      * returns used parameters
00212      */
00213     const parameters& getParameters() const;
00214 
00215     /**
00216      * This is an alias for loadFile().
00217      */
00218     bool apply();
00219 
00220     /**
00221      * Loads the specified config file into the dictionary. If the file is not
00222      * valid, does not exist, or in case of parse errors 'false' will be returned
00223      * and the statusString will be set.
00224      */
00225     bool loadFile();
00226 
00227     /** Same as loadFile(), but given fileName overrides parameters. */
00228     bool loadFile(const std::string &fileName);
00229 
00230     /**
00231      * Saves the dictionary in the file specified in the parameters
00232      * (replaces existing). On error the status string is set and false is returned.
00233      */
00234     bool saveFile() const;
00235 
00236     /** Same as saveFile(), but given fileName overrides parameters. */
00237     bool saveFile(const std::string &fileName) const;
00238 
00239     // ------------------------------------------------------------------------
00240     /** @name Reading Values
00241      *  Use these methods to obtain a desired value.
00242      *  If request is not available "value" variable will be left
00243      *  unaltered and false will be returned
00244      */
00245     //@{
00246 
00247       /** string
00248        */
00249       bool getValue(const std::string &section, const std::string &key, std::string &value, std::string &comment) const;
00250       /** string
00251        */
00252       bool getValue(const std::string &section, const std::string &key, std::string &value) const{
00253         std::string tt;
00254         return getValue(section,key,value,tt);
00255       }
00256 
00257       /** bool
00258        */
00259       bool getValue(const std::string &section, const std::string &key, bool &value, std::string &comment) const;
00260       /** bool
00261        */
00262       bool getValue(const std::string &section, const std::string &key, bool &value) const{
00263         std::string tt;
00264         return getValue(section,key,value,tt);
00265       }
00266 
00267       /** double
00268        */
00269       bool getValue(const std::string &section, const std::string &key, double &value, std::string &comment) const;
00270       /** double
00271        */
00272       bool getValue(const std::string &section, const std::string &key, double &value) const{
00273         std::string tt;
00274         return getValue(section,key,value,tt);
00275       }
00276 
00277       /** float
00278        */
00279       bool getValue(const std::string &section, const std::string &key, float &value, std::string &comment) const;
00280       /** float
00281        */
00282       bool getValue(const std::string &section, const std::string &key, float &value) const{
00283         std::string tt;
00284         return getValue(section,key,value,tt);
00285       }
00286 
00287       /** int
00288        */
00289       bool getValue(const std::string &section, const std::string &key, int &value, std::string &comment) const;
00290       /** int
00291        */
00292       bool getValue(const std::string &section, const std::string &key, int &value) const{
00293         std::string tt;
00294         return getValue(section,key,value,tt);
00295       }
00296 
00297       /** unsigned int
00298        */
00299       bool getValue(const std::string &section, const std::string &key, unsigned int &value, std::string &comment) const;
00300       /** unsigned int
00301        */
00302       bool getValue(const std::string &section, const std::string &key, unsigned int &value) const{
00303         std::string tt;
00304         return getValue(section,key,value,tt);
00305       }
00306 
00307       /** Returns a list of all keys in the specified section. */
00308       std::list<std::string> getKeys(std::string section) const;
00309 
00310     //@}
00311 
00312 
00313     // ------------------------------------------------------------------------
00314     /** @name Setting Values
00315      * Use one of these methods to set entries (section,key,value,comment).
00316      * You can also use these to set comments:
00317      * - \b global if((section=="") && (key==""))
00318      * - \b section if((section!="") && (key==""))
00319      *
00320      * In case of errors the status string is set and false returned.
00321      */
00322     //@{
00323 
00324       /** string
00325        */
00326       bool setValue(const std::string &section, const std::string &key = "", const std::string &value = "", const std::string &comment = "");
00327 
00328       /** const char*
00329        */
00330       bool setValue(const std::string &section, const std::string &key = "", const char* value= "", const std::string &comment = ""){
00331         return setValue(section, key, std::string(value), std::string(comment));
00332       }
00333 
00334       /** bool
00335        */
00336       bool setValue(const std::string &section, const std::string &key = "", const bool &value = false, const std::string &comment = "");
00337 
00338       /** double
00339        */
00340       bool setValue(const std::string &section, const std::string &key = "", const double &value = 0.0, const std::string &comment = "");
00341 
00342       /** float
00343        */
00344       bool setValue(const std::string &section, const std::string &key = "", const float &value = 0.0f, const std::string &comment = "");
00345 
00346       /** int
00347        */
00348       bool setValue(const std::string &section, const std::string &key = "", const int &value = 0, const std::string &comment = "");
00349 
00350       /** unsigned int
00351        */
00352       bool setValue(const std::string &section, const std::string &key = "", const unsigned int &value = 0, const std::string &comment = "");
00353 
00354     //@}
00355 
00356     // ------------------------------------------------------------------------
00357     /** @name Manipulation
00358      *  Use these methods to manipulate the dictionary
00359      */
00360     //@{
00361 
00362       /**
00363        * Sort the sections of the dictionary. The sections are sorted in ascending order.
00364        * The order of the keys in a section in not changed!
00365        */
00366       void sortSections();
00367 
00368       /**
00369        * Remove alle elements of the section 'section'. If section is not set all
00370        * comments above the first section are removed. The return value is false if
00371        * no section of this name exists.
00372        */
00373       bool deleteSection(const std::string &section="");
00374 
00375       /**
00376        * Delete a key in an section. The return value is false if
00377        * no key of this name exists. If you set the name of the section
00378        * only you remove all comments of this section.
00379        */
00380       bool deleteKey(const std::string &section, const std::string &key="");
00381 
00382 
00383       /**
00384        * Delete every comment, section and key of the internal structure
00385        * of the config file. If you write after this to disk you get an empty file.
00386        */
00387       void clear();
00388 
00389     //@}
00390 
00391 
00392   protected:
00393     class configEntry {
00394     public:
00395       configEntry() {
00396         configEntry("","");
00397       }
00398       configEntry(std::string v,
00399                   std::string c) {
00400         value = v;
00401         comment = c;
00402       }
00403       ~configEntry() { };
00404       std::string value;
00405       std::string comment;
00406     };
00407 
00408     /**
00409      * This function splits a line into the tokens key, section...
00410      */
00411     std::string splitLine(const std::string& inputLine,
00412                           std::string& prolog,
00413                           std::string& section,
00414                           std::string& key,
00415                           std::string& value,
00416                           std::string& comment) const;
00417 
00418     /**
00419      * Creates a line of the configFile based on the given values
00420      */
00421     void composeLine(const std::string& prolog,
00422                      const std::string& section,
00423                      const std::string& key,
00424                      const std::string& value,
00425                      const std::string& comment,
00426                      bool secDef,
00427                      int keyLength,
00428                      std::string& outputLine) const;
00429 
00430     /**
00431      * Creates a map containing section|->maxKeyLength for formatted saving.
00432      * Additionally returns the overall maximum length of a key name
00433      */
00434     int getMaxKeyLengths(std::map<std::string,int>& maxKeyLengths) const;
00435 
00436     /** Map with section name as key, and map of section's keys as value */
00437     std::map<std::string, std::map<std::string, configEntry> > dictionary;
00438 
00439     /** Stores the order of the sections. */
00440     std::list<std::string> orderSections;
00441 
00442     /** Stores the order of the keys in each section. */
00443     std::map<std::string, std::list<std::string> > orderKeys;
00444 
00445     /** Stores pure comments without a key */
00446     std::map<std::string, std::list<std::string> > sectionComments;
00447 
00448     /** Stores capitalization of sections. */
00449     std::map<std::string, std::string> sectionOrig;
00450     
00451     /** Stores capitalization of keys. */
00452     std::map<std::string, std::map<std::string, std::string> > keyOrig;
00453   };
00454 }
00455 
00456 #endif

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