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