Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

appconf.h

Go to the documentation of this file.
00001 /*-*- c++ -*-*****************************************************************\
00002  * Project:   CppLib: C++ library for Windows/UNIX platfroms                 *
00003  * File:      config.h - Config class, .INI/.rc file manager                 *
00004  *---------------------------------------------------------------------------*
00005  * Language:  C++                                                            *
00006  * Platfrom:  any (tested under Windows NT)                                  *
00007  *---------------------------------------------------------------------------*
00008  * (c) Karsten Ballüder & Vadim Zeitlin                                      *
00009  *     Ballueder@usa.net  Vadim.zeitlin@dptmaths.ens-cachan.fr               *
00010  *---------------------------------------------------------------------------*
00011  * $Id: appconf.h,v 1.2 2000/05/03 18:29:00 mbn Exp $                    *
00012  *---------------------------------------------------------------------------*
00013  * Classes:                                                                  *
00014  *  BaseConfig      - ABC for class that manage tree organized config info   *
00015  *  FileConfig      - implementation of BaseConfig based on disk files       *
00016  *  RegistryConfig  - implementation of BaseConfig based Win32 registry      *
00017  *---------------------------------------------------------------------------*
00018  * To do:                                                                    *
00019  *  - derive wxConfig                                                        *
00020  *  - EXTENSIVE ERROR CHECKING (none done actually)                          *
00021  *  - derive IniConfig for standard dumb Windows INI files using Win APIs    *
00022  *---------------------------------------------------------------------------*
00023  * History:                                                                  *
00024  *  25.10.97  adapted from wxConfig by Karsten Ballüder                      *
00025  *  29.10.97  FileConfig now saves comments back (VZ)                        *
00026  *  30.10.97  Immutable entries support added (KB)                           *
00027  *  01.11.97  Fixed NULL pointer access in BaseConfig::setCurrentPath (KB)   *
00028  *            Replaced filterIn() with original function from wxConfig,      *
00029  *            doing environment variable expansion, too (KB)                 *
00030  *            Made parsing case insensitive (Compile time option) (KB)       *
00031  *  02.11.97  Added deleteEntry function (VZ)                                *
00032  *  08.11.97  Environment variable expansion on demand (VZ)                  *
00033  *            RegistryConfig::changeCurrentPath added (VZ)                   *
00034  *            AppConf defined to be used instead of File/RegistryConfig      *
00035  *  18.01.98  Several fixes and changes to FileConfig (KB)                   *
00036  *            Added recordDefaults() method (KB)                             *
00037 \*****************************************************************************/
00038 
00039 #ifndef   _APPCONF_H
00040 #define   _APPCONF_H
00041 
00042 
00098 
00099 #if APPCONF_USE_CONFIG_H
00100 # include <config.h>
00101 #endif
00102 
00103 #include  <iostream>
00104 #include  <stdlib.h>
00105 
00106 // make sure we have a Bool type
00107 typedef   int Bool;
00108 #ifndef    TRUE
00109 # define    TRUE  1
00110 # define    FALSE 0
00111 #endif
00112 
00113 // make sure we have NULL defined properly
00114 // #undef  NULL
00115 // #define NULL 0
00116 
00117 // ----------------------------------------------------------------------------
00118 // constants
00119 // ----------------------------------------------------------------------------
00120 
00121 
00124 
00126 
00127 #ifndef APPCONF_USE_GETTEXT
00128 #               define  APPCONF_USE_GETTEXT     0
00129 #else
00130 #               define  APPCONF_DOMAIN  "appconf"
00131 #endif
00132 
00134 #ifndef APPCONF_CASE_SENSITIVE
00135 #       define  APPCONF_CASE_SENSITIVE  0
00136 #endif
00137 
00139 #ifndef APPCONF_PATH_SEPARATOR
00140 #       define   APPCONF_PATH_SEPARATOR     '/'
00141 #endif
00142 
00144 #ifndef APPCONF_IMMUTABLE_PREFIX
00145 #       define   APPCONF_IMMUTABLE_PREFIX   '!'
00146 #endif
00147 
00149 #ifndef APPCONF_STRBUFLEN
00150 #       define   APPCONF_STRBUFLEN          1024
00151 #endif
00152 
00154 #ifndef   APPCONF_WIN32_NATIVE
00155 #       define APPCONF_WIN32_NATIVE             1       // default: TRUE
00156 #endif
00157 
00159 
00162 // ----------------------------------------------------------------------------
00163 // global functions
00164 // ----------------------------------------------------------------------------
00172 char *ExpandEnvVars(const char *psz);
00174 
00177 
00178 // ----------------------------------------------------------------------------
00180 // ----------------------------------------------------------------------------
00181 class BaseConfig
00182 {
00183 public:
00186 
00187   BaseConfig();
00189   virtual ~BaseConfig();
00191 
00198   virtual void setCurrentPath(const char *szPath = "");
00199 
00205   virtual void changeCurrentPath(const char *szPath = "");
00206 
00211   const char *getCurrentPath() const;
00218   static char *normalizePath(const char *szStartPath, const char *szPath);
00220 
00224    void recordDefaults(Bool enable = TRUE);
00225 
00233   class Enumerator
00234   {
00235   public:
00236     // if bOwnsStrings, it will delete them in dtor
00237     Enumerator(size_t nCount, Bool bOwnsStrings);
00238     ~Enumerator();
00239 
00240     // add a string
00241       // this one may be used only if bOwnsString was TRUE in ctor
00242     void AddString(const char *sz);
00243       // 
00244     void AddString(char *sz);
00245     
00246     // kludge: eliminate duplicate strings
00247     void MakeUnique();
00248 
00249     // accessors
00251     size_t      Count()                   const { return m_nCount;          }
00253     const char *operator[](size_t nIndex) const { return m_aszData[nIndex]; }
00254 
00255   private:
00256     char    **m_aszData;
00257     size_t    m_nCount;
00258     Bool      m_bOwnsStrings;
00259   };
00277   virtual Enumerator *enumSubgroups() const = 0;
00283   virtual Enumerator *enumEntries() const = 0;
00285 
00294   virtual const char *readEntry(const char *szKey, 
00295                                 const char *szDefault = NULL) const = 0;
00296 
00304    long int readEntry(const char *szKey, long int Default) const;
00305 
00313    double readEntry(const char *szKey, double Default) const;
00314 
00321   virtual Bool writeEntry(const char *szKey, const char *szValue) = 0;
00322 
00329    Bool writeEntry(const char *szKey, long int Value);
00330 
00337   Bool writeEntry(const char *szKey, double Value);
00338 
00348   virtual Bool deleteEntry(const char *szKey) = 0;
00350 
00353 
00354   virtual Bool flush(Bool /* bCurrentOnly */ = FALSE) { return TRUE; }
00356   Bool isInitialized() const { return m_bOk; }
00358 
00368 
00369   static char *filterOut(const char *szValue);
00371   static char *filterIn(const char *szValue);
00373   void expandVariables(Bool bExpand = TRUE) { m_bExpandVariables = bExpand; }
00375   Bool doesExpandVariables(void) const { return m_bExpandVariables; }
00377 
00378 protected:
00380   Bool  m_bOk;
00382   Bool  m_bExpandVariables;
00384   Bool  m_bRecordDefaults; 
00385 private:
00386   char *m_szCurrentPath;
00387 };
00388 
00389 // ----------------------------------------------------------------------------
00434 // ----------------------------------------------------------------------------
00435 
00436 class FileConfig : public BaseConfig
00437 {
00438 public:
00455    FileConfig(const char *szFileName, Bool bLocalOnly = FALSE,
00456               Bool bUseSubDir = FALSE);
00462    FileConfig(std::istream *iStream);
00467    FileConfig(void);
00468 
00474  ~FileConfig();
00476 
00482    void readFile(const char *szFileName);
00483    
00486 
00487   const char *readEntry(const char *szKey, const char *szDefault = NULL) const;
00489   long int readEntry(const char *szKey, long int Default) const
00490        { return BaseConfig::readEntry(szKey, Default); }
00492   double readEntry(const char *szKey, double Default) const
00493       { return BaseConfig::readEntry(szKey, Default); }
00495   Bool writeEntry(const char *szKey, const char *szValue);
00497   Bool writeEntry(const char *szKey, long int Value)
00498      { return BaseConfig::writeEntry(szKey, Value);}
00500   Bool writeEntry(const char *szKey, double Value)
00501      { return BaseConfig::writeEntry(szKey, Value); }
00503   Bool deleteEntry(const char *szKey);
00505   Bool flush(Bool bCurrentOnly = FALSE);
00507   Bool flush(std::ostream *oStream, Bool /* bCurrentOnly */ = FALSE);
00508 
00510   Bool parseLine(const char *psz);
00511 
00512    
00514   void changeCurrentPath(const char *szPath = "");
00516 
00522 
00523   Enumerator *enumSubgroups() const;
00525   Enumerator *enumEntries() const;
00527 
00528 //protected: --- if FileConfig::ConfigEntry is not public, functions in
00529 //               ConfigGroup such as Find/AddEntry can't return ConfigEntry*!
00530   class ConfigGroup;
00531   class ConfigEntry
00532   {
00533   private:
00534     ConfigGroup *m_pParent;     // group that contains us
00535     ConfigEntry *m_pNext;       // next entry (in linked list)
00536     char        *m_szName,      // entry name
00537                 *m_szValue,     //       value
00538                 *m_szExpValue,  // value with expanded env variables
00539                 *m_szComment;   // optional comment preceding the entry
00540     Bool         m_bDirty,      // changed since last read?
00541                  m_bLocal,      // read from user's file or global one?
00542                  m_bImmutable;  // can be overriden locally?
00543 
00544   public:
00545     ConfigEntry(ConfigGroup *pParent, ConfigEntry *pNext, const char *szName);
00546    ~ConfigEntry();
00547 
00548     // simple accessors
00549     const char  *Name()         const { return m_szName;     }
00550     const char  *Value()        const { return m_szValue;    }
00551     const char  *Comment()      const { return m_szComment;  }
00552     ConfigEntry *Next()         const { return m_pNext;      }
00553     Bool         IsDirty()      const { return m_bDirty;     }
00554 
00555     // expand environment variables and return the resulting string
00556     const char *ExpandedValue();
00557 
00558     // modify entry attributes
00559     void SetValue(const char *szValue, 
00560                   Bool bLocal = TRUE, 
00561                   Bool bFromFile = FALSE);
00562     void SetComment(char *szComment);
00563     void SetDirty(Bool bDirty = TRUE);
00564     void SetNext(ConfigEntry *pNext) { m_pNext = pNext; }
00565   };
00566 
00567 protected:
00568   class ConfigGroup
00569   {
00570   private:
00571     ConfigEntry *m_pEntries,    // list of entries in this group
00572                 *m_pLastEntry;  // last entry
00573     ConfigGroup *m_pSubgroups,  // list of subgroups
00574                 *m_pLastGroup,  // last subgroup
00575                 *m_pNext,       // next group at the same level as this one
00576                 *m_pParent;     // parent group
00577     char        *m_szName,      // group's name
00578                 *m_szComment;   // optional comment preceding this group
00579     Bool         m_bDirty;      // if FALSE => all subgroups are not dirty
00580 
00581   public:
00582     // ctors
00583     ConfigGroup(ConfigGroup *pParent, ConfigGroup *pNext, const char *szName);
00584 
00585     // dtor deletes all entries and subgroups also
00586     ~ConfigGroup();
00587 
00588     // simple accessors
00589     const char  *Name()     const { return m_szName;      }
00590     const char  *Comment()  const { return m_szComment;   }
00591     ConfigGroup *Next()     const { return m_pNext;       }
00592     ConfigGroup *Parent()   const { return m_pParent;     }
00593     ConfigGroup *Subgroup() const { return m_pSubgroups;  }
00594     ConfigEntry *Entries()  const { return m_pEntries;    }
00595     Bool         IsDirty()  const { return m_bDirty;      }
00596 
00597     // full name ('/' separated path from top)
00598     // caller must free buffer
00599     char *FullName() const;
00600 
00601     // find entry/subgroup (NULL if not found)
00602     ConfigGroup *FindSubgroup(const char *szName) const;
00603     ConfigEntry *FindEntry   (const char *szName) const;
00604 
00605     // delete entry/subgroup, return FALSE if doesn't exist
00606     Bool DeleteSubgroup(const char *szName);
00607     Bool DeleteEntry   (const char *szName);
00608 
00609     // create new entry/subgroup returning pointer to newly created element
00610     ConfigGroup *AddSubgroup(const char *szName);
00611     ConfigEntry *AddEntry   (const char *szName);
00612 
00613     // will also recursively call parent's dirty flag
00614     void SetDirty(Bool bDirty = TRUE);
00615     
00616     // comment shouldn't be empty if this function is used
00617     void SetComment(char *szComment);
00618     
00619     // write dirty data
00620     Bool flush(std::ostream *ostr);
00621   };
00622 
00623   // delete current group if has no more entries/subgroups
00624   // NB: changes m_pCurGroup is returns TRUE (i.e. the group was deleted)
00625   Bool DeleteIfEmpty();
00626 
00627   ConfigGroup *m_pRootGroup,  // there is one and only one root group
00628               *m_pCurGroup;   // and also unique current (default) one
00629 
00630   // create all groups found in the strem under group pRootGroup or
00631   // m_pRootGroup if parameter is NULL
00632   // returns TRUE on success
00633   Bool readStream(std::istream *istr, ConfigGroup *pRootGroup = NULL);
00634 
00635   // construct global and local filenames based on the base file name
00636   // (which nevertheless may contain "/")
00637     // get the name of system-wide config file
00638   const char *GlobalConfigFile() const;
00639     // get the name of user's config file
00640   const char *LocalConfigFile() const;
00641 
00643   void Init();
00644 
00645 private:
00646   char     *m_szFileName;        // config file name
00647  
00648   const char *m_szFullFileName;  // full file name for error messages
00649   unsigned  m_uiLine;            // line number for error messages
00650   Bool      m_bParsingLocal;     // TRUE while parsing user's config file
00651   Bool      m_bUseSubDir;       // shall we use a subdirectory for config file?  
00652   // we store in a variable all comments + whitespace preceding the
00653   // current entry or group in order to be able to store it later
00654   void      AppendCommentLine(const char *psz = NULL);
00655   char     *m_szComment;
00656 };
00657 
00658 // ----------------------------------------------------------------------------
00660 // ----------------------------------------------------------------------------
00661 #ifdef  __WIN32__
00662 
00663 class RegistryConfig : public BaseConfig
00664 {
00665 public:
00673   RegistryConfig(const char *szRootKey);
00675  ~RegistryConfig();
00677 
00680 
00681    const char *readEntry(const char *szKey, const char *szDefault = NULL) const;
00683    long int readEntry(const char *szKey, long int Default) const
00684       { return BaseConfig::readEntry(szKey, Default); }
00686    double readEntry(const char *szKey, double Default) const
00687       { return BaseConfig::readEntry(szKey, Default); }
00688 
00690    Bool writeEntry(const char *szKey, const char *szValue);
00692    Bool writeEntry(const char *szKey, long int Value)
00693      { return BaseConfig::writeEntry(szKey, Default);}
00695    Bool writeEntry(const char *szKey, double Value)
00696      { return BaseConfig::writeEntry(szKey, Default); }
00697 
00699   Bool deleteEntry(const char *szKey);
00701 
00707 
00708   Enumerator *enumSubgroups() const;
00710   Enumerator *enumEntries() const;
00712 
00713   // intercept this function and change m_hCurrentKey
00714   virtual void changeCurrentPath(const char *szPath = "");
00715 
00716 private:
00717   const char *ReadValue(void *hKey, const char *szValue) const;
00718   static Bool KeyIsEmpty(void *hKey);
00719 
00720   void *m_hGlobalRootKey,       // top of system settings
00721        *m_hLocalRootKey,        // top of user settings
00722        *m_hGlobalCurKey,        // current registry key (child of global root)
00723        *m_hLocalCurKey;         //                                local
00724 
00725   char *m_pLastRead;      // pointer to last read value (###)
00726 };
00727 
00728 #endif  // WIN32
00729 
00731 #if       APPCONF_WIN32_NATIVE && defined(__WIN32__)
00732   typedef class RegistryConfig AppConfig;
00733 #else
00734   typedef class FileConfig     AppConfig;
00735 #endif
00736 
00738 
00740 #endif  //_APPCONF_H
00741 

Generated at Wed Apr 4 19:53:58 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001