include/corelib/metareg.hpp

Go to the documentation of this file.
00001 #ifndef CORELIB___METAREG__HPP
00002 #define CORELIB___METAREG__HPP
00003 
00004 /*  $Id: metareg.hpp 130631 2008-06-11 20:17:12Z ucko $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NOTICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Authors:  Aaron Ucko
00030  *
00031  */
00032 
00033 /// @file metareg.hpp
00034 /// CMetaRegistry: Singleton class for loading CRegistry data from
00035 /// files; keeps track of what it loaded from where, for potential
00036 /// reuse.
00037 
00038 #include <corelib/ncbimtx.hpp>
00039 #include <corelib/ncbireg.hpp>
00040 #include <corelib/ncbitime.hpp>
00041 
00042 BEGIN_NCBI_SCOPE
00043 
00044 
00045 template <typename T> class CSafeStaticPtr;
00046 
00047 class  CMetaRegistry
00048 {
00049 public:
00050     /// Relevant types
00051 
00052     /// General flags
00053     enum EFlags {
00054         fPrivate         = 0x1, ///< Do not cache, or support automatic saving.
00055         fReloadIfChanged = 0x2, ///< Reload if time or size has changed.
00056         fAlwaysReload    = 0x6, ///< Reload unconditionally.
00057         fKeepContents    = 0x8  ///< Keep existing contents when reloading.
00058     };
00059     typedef int TFlags; ///< Binary OR of "EFlags"
00060 
00061     /// How to treat filenames
00062     enum ENameStyle {
00063         eName_AsIs,   ///< Take the specified filename as is
00064         eName_Ini,    ///< Add .ini, dropping existing extensions as needed
00065         eName_DotRc,  ///< Transform into .*rc
00066         /// C Toolkit style; mostly useful with name = "ncbi"
00067 #ifdef NCBI_OS_MSWIN
00068         eName_RcOrIni = eName_Ini
00069 #else
00070         eName_RcOrIni = eName_DotRc
00071 #endif
00072     };
00073 
00074     typedef IRegistry::TFlags TRegFlags;
00075 
00076     struct  SEntry {
00077         string            actual_name; ///< Either an absolute path or empty.
00078         TFlags            flags;
00079         TRegFlags         reg_flags;
00080         CRef<IRWRegistry> registry;
00081         CTime             timestamp; ///< For cache validation
00082         Int8              length;    ///< For cache validation
00083 
00084         /// Reload the configuration file.  By default, does nothing if
00085         /// the file has the same size and date as before.
00086         ///
00087         /// Note that this may lose other data stored in the registry!
00088         ///
00089         /// @param reload_flags
00090         ///   Controls how aggressively to reload.
00091         /// @return
00092         ///   TRUE if a reload actually occurred.
00093         bool Reload(TFlags reload_flags = fReloadIfChanged);
00094     };
00095 
00096     static CMetaRegistry& Instance(void);
00097 
00098     /// Load the configuration file "name".
00099     ///
00100     /// @param name
00101     ///   The name of the configuration file to look for.  If it does
00102     ///   not contain a path, Load() searches in the default path list.
00103     /// @param style
00104     ///   How, if at all, to modify "name".
00105     /// @param flags
00106     ///   Any relevant options from EFlags above.
00107     /// @param reg
00108     ///   If NULL, yield a new CNcbiRegistry.  Otherwise, populate the
00109     ///   supplied registry (and don't try to share it if it didn't
00110     ///   start out empty).
00111     /// @return
00112     ///   On success, .actual_name will contain the absolute path to
00113     ///   the file ultimately loaded, and .registry will point to an
00114     ///   IRWRegistry object containing its contents (owned by this
00115     ///   class unless fPrivate or fDontOwn was given).
00116     ///   On failure, .actual_name will be empty and .registry will be
00117     ///   NULL.
00118     static SEntry Load(const string&  name,
00119                        ENameStyle     style     = eName_AsIs,
00120                        TFlags         flags     = 0,
00121                        TRegFlags      reg_flags = 0,
00122                        IRWRegistry*   reg       = 0);
00123 
00124     /// Reload the configuration file "path".
00125     ///
00126     /// @param path
00127     ///   A path (ideally absolute) to the configuration file to read.
00128     /// @param reg
00129     ///   The registry to repopulate.
00130     /// @param flags
00131     ///   Any relevant options from EFlags above.
00132     /// @param reg_flags
00133     ///   Flags to use when parsing the registry; ignored if the registry
00134     ///   was already cached.
00135     /// @return
00136     ///   TRUE if a reload actually occurred.
00137     static bool Reload(const string& path,
00138                        IRWRegistry&  reg,
00139                        TFlags        flags = 0,
00140                        TRegFlags     reg_flags = 0);
00141 
00142     /// Search path for unqualified names.
00143     typedef vector<string> TSearchPath;
00144     static const TSearchPath& GetSearchPath(void);
00145     static       TSearchPath& SetSearchPath(void);
00146 
00147     /// Clears path and substitutes the default search path.  If the
00148     /// environment NCBI_CONFIG_PATH is set, the default is to look there
00149     /// exclusively; otherwise, the default list contains the following
00150     /// directories in order:
00151     ///    - The current working directory.
00152     ///    - The user's home directory.
00153     ///    - The directory, if any, given by the environment variable "NCBI".
00154     ///    - The standard system directory (/etc on Unix, and given by the
00155     ///      environment variable "SYSTEMROOT" on Windows).
00156     ///    - The directory containing the application, if known.
00157     ///      (Requires use of CNcbiApplication.)
00158     /// The first two directories are skipped if the environment variable
00159     /// NCBI_DONT_USE_LOCAL_CONFIG is set.
00160     static void GetDefaultSearchPath(TSearchPath& path);
00161 
00162 private:
00163     /// Private functions, mostly non-static implementations of the
00164     /// public interface.
00165 
00166     CMetaRegistry();
00167     ~CMetaRegistry();
00168 
00169     /// name0 and style0 are the originally requested name and style
00170     const SEntry& x_Load(const string& name,  ENameStyle style,
00171                          TFlags flags, TRegFlags reg_flags, IRWRegistry* reg,
00172                          const string& name0, ENameStyle style0,
00173                          SEntry& scratch_entry);
00174 
00175     bool x_Reload(const string& path, IRWRegistry&  reg, TFlags flags,
00176                   TRegFlags reg_flags);
00177 
00178     const TSearchPath& x_GetSearchPath(void) const { return m_SearchPath; }
00179     TSearchPath&       x_SetSearchPath(void)
00180         { CMutexGuard GUARD(m_Mutex); m_Index.clear(); return m_SearchPath; }
00181 
00182     /// Members
00183     struct SKey {
00184         string     requested_name;
00185         ENameStyle style;
00186         TFlags     flags;
00187         TRegFlags  reg_flags;
00188 
00189         SKey(string n, ENameStyle s, TFlags f, TRegFlags rf)
00190             : requested_name(n), style(s), flags(f), reg_flags(rf) { }
00191         bool operator <(const SKey& k) const;
00192     };
00193     typedef map<SKey, size_t> TIndex;
00194 
00195     vector<SEntry> m_Contents;
00196     TSearchPath    m_SearchPath;
00197     TIndex         m_Index;
00198 
00199     CMutex         m_Mutex;
00200 
00201     friend class  CSafeStaticPtr<CMetaRegistry>;
00202     friend struct SEntry;
00203 };
00204 
00205 
00206 
00207 /////////////////////////////////////////////////////////////////////////////
00208 //  IMPLEMENTATION of INLINE functions
00209 /////////////////////////////////////////////////////////////////////////////
00210 
00211 
00212 inline
00213 bool CMetaRegistry::Reload(const string& path,
00214                            IRWRegistry&  reg,
00215                            TFlags        flags,
00216                            TRegFlags     reg_flags)
00217 {
00218     return Instance().x_Reload(path, reg, flags, reg_flags);
00219 }
00220 
00221 inline
00222 const CMetaRegistry::TSearchPath& CMetaRegistry::GetSearchPath(void)
00223 {
00224     return Instance().x_GetSearchPath();
00225 }
00226 
00227 
00228 inline
00229 CMetaRegistry::TSearchPath& CMetaRegistry::SetSearchPath(void)
00230 {
00231     return Instance().x_SetSearchPath();
00232 }
00233 
00234 
00235 inline
00236 CMetaRegistry::CMetaRegistry()
00237 {
00238     GetDefaultSearchPath(x_SetSearchPath());
00239 }
00240 
00241 
00242 END_NCBI_SCOPE
00243 
00244 #endif  /* CORELIB___METAREG__HPP */
00245 
00246 

Generated on Sun Dec 6 21:58:42 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732