1 #ifndef CORELIB___ENV_REG__HPP
2 #define CORELIB___ENV_REG__HPP
3 
4 /*  $Id: env_reg.hpp 542165 2017-07-27 15:01:06Z ucko $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors:  Aaron Ucko
30  *
31  */
32 
33 /// @file env_reg.hpp
34 /// Classes to support using environment variables as a backend for
35 /// the registry framework.
36 
37 #include <corelib/ncbienv.hpp>
38 #include <corelib/ncbireg.hpp>
39 
40 
41 /** @addtogroup Registry
42  *
43  * @{
44  */
45 
46 
47 BEGIN_NCBI_SCOPE
48 
49 /////////////////////////////////////////////////////////////////////////////
50 ///
51 /// IEnvRegMapper --
52 ///
53 /// Abstract policy class mediating conversions between environment
54 /// variable names and registry entry names.
55 
56 class NCBI_XNCBI_EXPORT IEnvRegMapper : public CObject
57 {
58 public:
59     /// Returns empty strings for unsupported (section, name) pairs.
60     virtual string RegToEnv(const string& section, const string& name) const
61         = 0;
62 
63     /// The return value indicates whether the environment variable was
64     /// appropriately formatted.
65     virtual bool   EnvToReg(const string& env, string& section, string& name)
66         const = 0;
67 
68     /// Can be overriden to speed enumeration.
GetPrefix(void) const69     virtual string GetPrefix(void) const { return kEmptyStr; }
70 };
71 
72 
73 /////////////////////////////////////////////////////////////////////////////
74 ///
75 /// CEnvironmentRegistry --
76 ///
77 /// Adapts CNcbiEnvironment to act like a registry.  Leaves all
78 /// caching of values to CNcbiEnvironment, and does not support
79 /// comments.  Always transient, though making it the persistent side
80 /// of a CTwoLayerRegistry can mask that.
81 ///
82 /// Uses customizable mappers between environment variable names and
83 /// registry section/name pairs; see below for details.
84 
85 
86 class NCBI_XNCBI_EXPORT CEnvironmentRegistry : public IRWRegistry
87 {
88 public:
89     /// Constructors.
90     CEnvironmentRegistry(TFlags flags = 0);
91     CEnvironmentRegistry(CNcbiEnvironment& env, EOwnership own = eNoOwnership,
92                          TFlags flags = 0);
93 
94     /// Destructor.
95     ~CEnvironmentRegistry();
96 
97     enum EPriority {
98         ePriority_Min     = kMin_Int,
99         ePriority_Default = 0,
100         ePriority_Max     = kMax_Int
101     };
102     typedef int TPriority; ///< Not restricted to ePriority_*.
103 
104     void AddMapper(const IEnvRegMapper& mapper,
105                    TPriority            prio = ePriority_Default);
106     void RemoveMapper(const IEnvRegMapper& mapper);
107 
108 protected:
109     bool x_Empty(TFlags flags) const;
110     bool x_Modified(TFlags flags) const;
111     void x_SetModifiedFlag(bool modified, TFlags flags);
112     const string& x_Get(const string& section, const string& name,
113                         TFlags flags) const;
114     const string& x_Get(const string& section, const string& name,
115                         TFlags flags, bool& found) const;
116     bool x_HasEntry(const string& section, const string& name,
117                     TFlags flags) const;
118     const string& x_GetComment(const string& section, const string& name,
119                                TFlags flags) const;
120     void x_Enumerate(const string& section, list<string>& entries,
121                      TFlags flags) const;
122     void x_ChildLockAction(FLockAction action);
123 
124     void x_Clear(TFlags flags);
125     bool x_Set(const string& section, const string& name,
126                const string& value, TFlags flags,
127                const string& comment);
128     bool x_Unset(const string& section, const string& name, TFlags flags);
129     bool x_SetComment(const string& comment, const string& section,
130                       const string& name, TFlags flags);
131 
132 private:
133     /// Copying prohibited.
CEnvironmentRegistry(const CEnvironmentRegistry &)134     CEnvironmentRegistry(const CEnvironmentRegistry&) {}
135 
136     typedef multimap<TPriority, CConstRef<IEnvRegMapper> > TPriorityMap;
137 
138     AutoPtr<CNcbiEnvironment> m_Env;
139     TPriorityMap      m_PriorityMap;
140     bool              m_Modified; ///< only tracks mods made through this.
141     TFlags            m_Flags;
142 };
143 
144 
145 /// CSimpleEnvRegMapper --
146 ///
147 /// Treat environment variables named <prefix><name><suffix> as
148 /// registry entries with section <section> and key <section>.  Empty
149 /// prefixes are legal, but must be specified explicitly.  Each
150 /// section name is limited to a single prefix/suffix pair; however,
151 /// there are no obstacles to placing multiple such mappings in a
152 /// CEnvironmentRegistry.
153 ///
154 /// Not used in the default configuration.
155 
156 class NCBI_XNCBI_EXPORT CSimpleEnvRegMapper : public IEnvRegMapper
157 {
158 public:
159     CSimpleEnvRegMapper(const string& section, const string& prefix,
160                         const string& suffix = kEmptyStr);
161 
162     string RegToEnv (const string& section, const string& name) const;
163     bool   EnvToReg (const string& env, string& section, string& name) const;
164     string GetPrefix(void) const;
165 private:
166     string m_Section, m_Prefix, m_Suffix;
167 };
168 
169 
170 /// CNcbiEnvRegMapper --
171 ///
172 /// Somewhat more elaborate mapping used by default, with support for
173 /// tree conversion.  Special node names (starting with dots) get mapped as
174 ///     [<section>].<name> <-> NCBI_CONFIG_<name>__<section> ;
175 /// all other names get mapped as
176 ///     [<section>]<name> <-> NCBI_CONFIG__<section>__<name>
177 /// modulo a few substitutions to ensure that environment variable names
178 /// are always shell-friendly: '.' <-> _DOT_, '-' <-> _HYPHEN_,
179 /// '/' <-> _SLASH_, and ' ' <-> _SPACE_ (valid in fInternalSpaces mode).
180 
181 class NCBI_XNCBI_EXPORT CNcbiEnvRegMapper : public IEnvRegMapper
182 {
183 public:
184     string RegToEnv (const string& section, const string& name) const;
185     bool   EnvToReg (const string& env, string& section, string& name) const;
186     string GetPrefix(void) const;
187 
188 private:
189     static const char* sm_Prefix;
190 };
191 
192 
193 END_NCBI_SCOPE
194 
195 
196 /* @} */
197 
198 #endif  /* CORELIB___ENV_REG__HPP */
199