1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  *
3  * This is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This software is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this software; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16  * USA.
17  */
18 
19 // -=- Configuration.h
20 //
21 // This header defines a set of classes used to represent configuration
22 // parameters of different types.  Instances of the different parameter
23 // types are associated with instances of the Configuration class, and
24 // are each given a unique name.  The Configuration class provides a
25 // generic API through which parameters may be located by name and their
26 // value set, thus removing the need to write platform-specific code.
27 // Simply defining a new parameter and associating it with a Configuration
28 // will allow it to be configured by the user.
29 //
30 // If no Configuration is specified when creating a Parameter, then the
31 // global Configuration will be assumed.
32 //
33 // Configurations can be "chained" into groups.  Each group has a root
34 // Configuration, a pointer to which should be passed to the constructors
35 // of the other group members.  set() and get() operations called on the
36 // root will iterate through all of the group's members.
37 //
38 // NB: On platforms that support Threading, locking is performed to protect
39 //     complex parameter types from concurrent access (e.g. strings).
40 // NB: NO LOCKING is performed when linking Configurations to groups
41 //     or when adding Parameters to Configurations.
42 
43 #ifndef __RFB_CONFIGURATION_H__
44 #define __RFB_CONFIGURATION_H__
45 
46 #include <rfb/util.h>
47 
48 namespace os { class Mutex; }
49 
50 namespace rfb {
51   class VoidParameter;
52   struct ParameterIterator;
53 
54   enum ConfigurationObject { ConfGlobal, ConfServer, ConfViewer };
55 
56   // -=- Configuration
57   //     Class used to access parameters.
58 
59   class Configuration {
60   public:
61     // - Create a new Configuration object
Configuration(const char * name_)62     Configuration(const char* name_) : name(strDup(name_)), head(0), _next(0) {}
63 
64     // - Return the buffer containing the Configuration's name
getName()65     const char* getName() const { return name.buf; }
66 
67     // - Set named parameter to value
68     bool set(const char* param, const char* value, bool immutable=false);
69 
70     // - Set parameter to value (separated by "=")
71     bool set(const char* config, bool immutable=false);
72 
73     // - Set named parameter to value, with name truncated at len
74     bool set(const char* name, int len,
75                   const char* val, bool immutable);
76 
77     // - Get named parameter
78     VoidParameter* get(const char* param);
79 
80     // - List the parameters of this Configuration group
81     void list(int width=79, int nameWidth=10);
82 
83     // - Remove a parameter from this Configuration group
84     bool remove(const char* param);
85 
86     // - readFromFile
87     //   Read configuration parameters from the specified file.
88     void readFromFile(const char* filename);
89 
90     // - writeConfigToFile
91     //   Write a new configuration parameters file, then mv it
92     //   over the old file.
93     void writeToFile(const char* filename);
94 
95 
96     // - Get the Global Configuration object
97     //   NB: This call does NOT lock the Configuration system.
98     //       ALWAYS ensure that if you have ANY global Parameters,
99     //       then they are defined as global objects, to ensure that
100     //       global() is called when only the main thread is running.
101     static Configuration* global();
102 
103     // Enable server/viewer specific parameters
enableServerParams()104     static void enableServerParams() { global()->appendConfiguration(server()); }
enableViewerParams()105     static void enableViewerParams() { global()->appendConfiguration(viewer()); }
106 
107     // - Container for process-wide Global parameters
108     static bool setParam(const char* param, const char* value, bool immutable=false) {
109       return global()->set(param, value, immutable);
110     }
111     static bool setParam(const char* config, bool immutable=false) {
112       return global()->set(config, immutable);
113     }
setParam(const char * name,int len,const char * val,bool immutable)114     static bool setParam(const char* name, int len,
115       const char* val, bool immutable) {
116       return global()->set(name, len, val, immutable);
117     }
getParam(const char * param)118     static VoidParameter* getParam(const char* param) { return global()->get(param); }
119     static void listParams(int width=79, int nameWidth=10) {
120       global()->list(width, nameWidth);
121     }
removeParam(const char * param)122     static bool removeParam(const char* param) {
123       return global()->remove(param);
124     }
125 
126   private:
127     friend class VoidParameter;
128     friend struct ParameterIterator;
129 
130     // Name for this Configuration
131     CharArray name;
132 
133     // - Pointer to first Parameter in this group
134     VoidParameter* head;
135 
136     // Pointer to next Configuration in this group
137     Configuration* _next;
138 
139     // The process-wide, Global Configuration object
140     static Configuration* global_;
141 
142     // The server only Configuration object
143     static Configuration* server_;
144 
145     // The viewer only Configuration object
146     static Configuration* viewer_;
147 
148     // Get server/viewer specific configuration object
149     static Configuration* server();
150     static Configuration* viewer();
151 
152     // Append configuration object to this instance.
153     // NOTE: conf instance can be only one configuration object
appendConfiguration(Configuration * conf)154     void appendConfiguration(Configuration *conf) {
155       conf->_next = _next; _next = conf;
156     }
157   };
158 
159   // -=- VoidParameter
160   //     Configuration parameter base-class.
161 
162   class VoidParameter {
163   public:
164     VoidParameter(const char* name_, const char* desc_, ConfigurationObject co=ConfGlobal);
165     virtual  ~VoidParameter();
166     const char* getName() const;
167     const char* getDescription() const;
168 
169     virtual bool setParam(const char* value)  = 0;
170     virtual bool setParam();
171     virtual char* getDefaultStr() const = 0;
172     virtual char* getValueStr() const = 0;
173     virtual bool isBool() const;
174 
175     virtual void setImmutable();
176 
177   protected:
178     friend class Configuration;
179     friend struct ParameterIterator;
180 
181     VoidParameter* _next;
182     bool immutable;
183     const char* name;
184     const char* description;
185 
186     os::Mutex* mutex;
187   };
188 
189   class AliasParameter : public VoidParameter {
190   public:
191     AliasParameter(const char* name_, const char* desc_,VoidParameter* param_,
192 		   ConfigurationObject co=ConfGlobal);
193     virtual bool setParam(const char* value);
194     virtual bool setParam();
195     virtual char* getDefaultStr() const;
196     virtual char* getValueStr() const;
197     virtual bool isBool() const;
198     virtual void setImmutable();
199   private:
200     VoidParameter* param;
201   };
202 
203   class BoolParameter : public VoidParameter {
204   public:
205     BoolParameter(const char* name_, const char* desc_, bool v,
206 		  ConfigurationObject co=ConfGlobal);
207     virtual bool setParam(const char* value);
208     virtual bool setParam();
209     virtual void setParam(bool b);
210     virtual char* getDefaultStr() const;
211     virtual char* getValueStr() const;
212     virtual bool isBool() const;
213     operator bool() const;
214   protected:
215     bool value;
216     bool def_value;
217   };
218 
219   class IntParameter : public VoidParameter {
220   public:
221     IntParameter(const char* name_, const char* desc_, int v,
222                  int minValue=INT_MIN, int maxValue=INT_MAX,
223 		 ConfigurationObject co=ConfGlobal);
224     using VoidParameter::setParam;
225     virtual bool setParam(const char* value);
226     virtual bool setParam(int v);
227     virtual char* getDefaultStr() const;
228     virtual char* getValueStr() const;
229     operator int() const;
230   protected:
231     int value;
232     int def_value;
233     int minValue, maxValue;
234   };
235 
236   class StringParameter : public VoidParameter {
237   public:
238     // StringParameter contains a null-terminated string, which CANNOT
239     // be Null, and so neither can the default value!
240     StringParameter(const char* name_, const char* desc_, const char* v,
241 		    ConfigurationObject co=ConfGlobal);
242     virtual ~StringParameter();
243     virtual bool setParam(const char* value);
244     virtual char* getDefaultStr() const;
245     virtual char* getValueStr() const;
246     operator const char*() const;
247 
248     // getData() returns a copy of the data - it must be delete[]d by the
249     // caller.
getData()250     char* getData() const { return getValueStr(); }
251   protected:
252     char* value;
253     char* def_value;
254   };
255 
256   class BinaryParameter : public VoidParameter {
257   public:
258     BinaryParameter(const char* name_, const char* desc_,
259                     const void* v, size_t l,
260                     ConfigurationObject co=ConfGlobal);
261     using VoidParameter::setParam;
262     virtual ~BinaryParameter();
263     virtual bool setParam(const char* value);
264     virtual void setParam(const void* v, size_t l);
265     virtual char* getDefaultStr() const;
266     virtual char* getValueStr() const;
267 
268     // getData() will return length zero if there is no data
269     // NB: data may be set to zero, OR set to a zero-length buffer
270     void getData(void** data, size_t* length) const;
271 
272   protected:
273     char* value;
274     size_t length;
275     char* def_value;
276     size_t def_length;
277   };
278 
279   // -=- ParameterIterator
280   //     Iterates over all enabled parameters (global + server/viewer).
281   //     Current Parameter is accessed via param, the current Configuration
282   //     via config. The next() method moves on to the next Parameter.
283 
284   struct ParameterIterator {
ParameterIteratorParameterIterator285     ParameterIterator() : config(Configuration::global()), param(config->head) {}
nextParameterIterator286     void next() {
287       param = param->_next;
288       while (!param) {
289         config = config->_next;
290         if (!config) break;
291         param = config->head;
292       }
293     }
294     Configuration* config;
295     VoidParameter* param;
296   };
297 
298 };
299 
300 #endif // __RFB_CONFIGURATION_H__
301