1 /********************************************************************************
2 *                                                                               *
3 *                          S e t t i n g s   C l a s s                          *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1998,2020 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify          *
9 * it under the terms of the GNU Lesser General Public License as published by   *
10 * the Free Software Foundation; either version 3 of the License, or             *
11 * (at your option) any later version.                                           *
12 *                                                                               *
13 * This library is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
16 * GNU Lesser General Public License for more details.                           *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public License      *
19 * along with this program.  If not, see <http://www.gnu.org/licenses/>          *
20 ********************************************************************************/
21 #ifndef FXSETTINGS_H
22 #define FXSETTINGS_H
23 
24 namespace FX {
25 
26 
27 /**
28 * The Settings class manages a key-value database.  This is normally used as
29 * part of Registry, but can also be used separately in applications that need
30 * to maintain a key-value database in a file of their own.
31 * String values can contain any character, and will be escaped when written
32 * to the file.
33 */
34 class FXAPI FXSettings {
35 protected:
36   struct Entry {
37     FXString           key;             // Key
38     FXStringDictionary data;            // Value
39     FXuint             hash;            // Hash of key
40     };
41 protected:
42   Entry               *table;           // Hash table
43   FXbool               modified;        // Changed
44 protected:
45 
46   // Change size of the table
47   FXbool no(FXival n);
48 
49   // Change number of used entries
used(FXival u)50   void used(FXival u){ ((FXival*)table)[-2]=u; }
51 
52   // Change number of free entries
free(FXival f)53   void free(FXival f){ ((FXival*)table)[-3]=f; }
54 
55   // Resize the table to the given size, keeping contents
56   FXbool resize(FXival n);
57 public:
58 
59   /// Construct settings database.
60   FXSettings();
61 
62   /// Construct from another settings database
63   FXSettings(const FXSettings& other);
64 
65   /// Return the size of the table, including the empty slots
no()66   FXival no() const { return ((FXival*)table)[-1]; }
67 
68   /// Return number of used slots in the table
used()69   FXival used() const { return ((FXival*)table)[-2]; }
70 
71   /// Return number of free slots in the table
free()72   FXival free() const { return ((FXival*)table)[-3]; }
73 
74   /// See if map is empty
empty()75   FXbool empty() const { return ((FXival*)table)[-1]<=1; }
76 
77   /// Assignment operator
78   FXSettings& operator=(const FXSettings& other);
79 
80   /// Adopt string dictionary from another
81   FXSettings& adopt(FXSettings& other);
82 
83   /// Is it modified
isModified()84   FXbool isModified() const { return modified; }
85 
86   /// Mark as changed
87   void setModified(FXbool mdfy=true){ modified=mdfy; }
88 
89   /// Parse a file containing a settings database.
90   FXbool parseFile(const FXString& filename,FXbool mrk=true);
91 
92   /// Unparse settings database into given file.
93   FXbool unparseFile(const FXString& filename);
94 
95   /// Parse single string to populate settings
96   FXbool parse(const FXString& string,FXbool mrk=true);
97 
98   /// Unparse settings to a single string
99   FXbool unparse(FXString& string) const;
100 
101   /// Find position of given key, returning -1 if not found
102   FXival find(const FXchar* ky) const;
103 
104   /// Find position of given key, returning -1 if not found
find(const FXString & ky)105   FXival find(const FXString& ky) const { return find(ky.text()); }
106 
107   /// Return reference to slot assocated with given key
108   FXStringDictionary& at(const FXchar* ky);
109 
110   /// Return constant reference to slot assocated with given key
111   const FXStringDictionary& at(const FXchar* ky) const;
112 
113   /// Return reference to slot assocated with given key
at(const FXString & ky)114   FXStringDictionary& at(const FXString& ky){ return at(ky.text()); }
115 
116   /// Return constant reference to slot assocated with given key
at(const FXString & ky)117   const FXStringDictionary& at(const FXString& ky) const { return at(ky.text()); }
118 
119   /// Return reference to slot assocated with given key
120   FXStringDictionary& operator[](const FXchar* ky){ return at(ky); }
121 
122   /// Return constant reference to slot assocated with given key
123   const FXStringDictionary& operator[](const FXchar* ky) const { return at(ky); }
124 
125   /// Return reference to slot assocated with given key
126   FXStringDictionary& operator[](const FXString& ky){ return at(ky); }
127 
128   /// Return constant reference to slot assocated with given key
129   const FXStringDictionary& operator[](const FXString& ky) const { return at(ky); }
130 
131   /// Return true if slot is empty.
empty(FXival pos)132   FXbool empty(FXival pos) const { return table[pos].key.empty(); }
133 
134   /// Return key at position pos
key(FXival pos)135   const FXString& key(FXival pos) const { return table[pos].key; }
136 
137   /// Return reference to slot at position pos
data(FXival pos)138   FXStringDictionary& data(FXival pos){ return table[pos].data; }
139 
140   /// Return constant reference to slot at position pos
data(FXival pos)141   const FXStringDictionary& data(FXival pos) const { return table[pos].data; }
142 
143   /// Read a formatted registry entry, using scanf-style format
144   FXint readFormatEntry(const FXchar* section,const FXchar* name,const FXchar* fmt,...) const FX_SCANF(4,5) ;
145   FXint readFormatEntry(const FXString& section,const FXchar* name,const FXchar* fmt,...) const FX_SCANF(4,5) ;
146   FXint readFormatEntry(const FXString& section,const FXString& name,const FXchar* fmt,...) const FX_SCANF(4,5) ;
147 
148   /// Write a formatted registry entry, using printf-style format
149   FXint writeFormatEntry(const FXchar* section,const FXchar* name,const FXchar* fmt,...) FX_PRINTF(4,5) ;
150   FXint writeFormatEntry(const FXString& section,const FXchar* name,const FXchar* fmt,...) FX_PRINTF(4,5) ;
151   FXint writeFormatEntry(const FXString& section,const FXString& name,const FXchar* fmt,...) FX_PRINTF(4,5) ;
152 
153   /// Read a string registry entry; if no value is found, the default value def is returned
154   const FXchar* readStringEntry(const FXchar* section,const FXchar* name,const FXchar* def=NULL) const;
155   const FXchar* readStringEntry(const FXString& section,const FXchar* name,const FXchar* def=NULL) const;
156   const FXchar* readStringEntry(const FXString& section,const FXString& name,const FXchar* def=NULL) const;
157 
158   /// Write a string registry entry
159   FXbool writeStringEntry(const FXchar* section,const FXchar* name,const FXchar* val);
160   FXbool writeStringEntry(const FXString& section,const FXchar *name,const FXchar* val);
161   FXbool writeStringEntry(const FXString& section,const FXString& name,const FXchar* val);
162 
163   /// Read a integer registry entry; if no value is found, the default value def is returned
164   FXint readIntEntry(const FXchar* section,const FXchar* name,FXint def=0) const;
165   FXint readIntEntry(const FXString& section,const FXchar* name,FXint def=0) const;
166   FXint readIntEntry(const FXString& section,const FXString& name,FXint def=0) const;
167 
168   /// Write a integer registry entry
169   FXbool writeIntEntry(const FXchar* section,const FXchar* name,FXint val);
170   FXbool writeIntEntry(const FXString& section,const FXchar* name,FXint val);
171   FXbool writeIntEntry(const FXString& section,const FXString& name,FXint val);
172 
173   /// Read a unsigned integer registry entry; if no value is found, the default value def is returned
174   FXuint readUIntEntry(const FXchar* section,const FXchar* name,FXuint def=0) const;
175   FXuint readUIntEntry(const FXString& section,const FXchar* name,FXuint def=0) const;
176   FXuint readUIntEntry(const FXString& section,const FXString& name,FXuint def=0) const;
177 
178   /// Write a unsigned integer registry entry
179   FXbool writeUIntEntry(const FXchar* section,const FXchar* name,FXuint val);
180   FXbool writeUIntEntry(const FXString& section,const FXchar* name,FXuint val);
181   FXbool writeUIntEntry(const FXString& section,const FXString& name,FXuint val);
182 
183   /// Read a 64-bit long integer registry entry; if no value is found, the default value def is returned
184   FXlong readLongEntry(const FXchar* section,const FXchar* name,FXlong def=0) const;
185   FXlong readLongEntry(const FXString& section,const FXchar* name,FXlong def=0) const;
186   FXlong readLongEntry(const FXString& section,const FXString& name,FXlong def=0) const;
187 
188   /// Write a 64-bit long integer registry entry
189   FXbool writeLongEntry(const FXchar* section,const FXchar* name,FXlong val);
190   FXbool writeLongEntry(const FXString& section,const FXchar* name,FXlong val);
191   FXbool writeLongEntry(const FXString& section,const FXString& name,FXlong val);
192 
193   /// Read a 64-bit unsigned long integer registry entry; if no value is found, the default value def is returned
194   FXulong readULongEntry(const FXchar* section,const FXchar* name,FXulong def=0) const;
195   FXulong readULongEntry(const FXString& section,const FXchar* name,FXulong def=0) const;
196   FXulong readULongEntry(const FXString& section,const FXString& name,FXulong def=0) const;
197 
198   /// Write a 64-bit unsigned long integer registry entry
199   FXbool writeULongEntry(const FXchar* section,const FXchar* name,FXulong val);
200   FXbool writeULongEntry(const FXString& section,const FXchar* name,FXulong val);
201   FXbool writeULongEntry(const FXString& section,const FXString& name,FXulong val);
202 
203   /// Read a double-precision floating point registry entry; if no value is found, the default value def is returned
204   FXdouble readRealEntry(const FXchar* section,const FXchar* name,FXdouble def=0.0) const;
205   FXdouble readRealEntry(const FXString& section,const FXchar* name,FXdouble def=0.0) const;
206   FXdouble readRealEntry(const FXString& section,const FXString& name,FXdouble def=0.0) const;
207 
208   /// Write a double-precision floating point registry entry
209   FXbool writeRealEntry(const FXchar* section,const FXchar* name,FXdouble val);
210   FXbool writeRealEntry(const FXString& section,const FXchar* name,FXdouble val);
211   FXbool writeRealEntry(const FXString& section,const FXString& name,FXdouble val);
212 
213   /// Read a color value registry entry; if no value is found, the default value def is returned
214   FXColor readColorEntry(const FXchar* section,const FXchar* name,FXColor def=0) const;
215   FXColor readColorEntry(const FXString& section,const FXchar* name,FXColor def=0) const;
216   FXColor readColorEntry(const FXString& section,const FXString& name,FXColor def=0) const;
217 
218   /// Write a color value entry
219   FXbool writeColorEntry(const FXchar* section,const FXchar* name,FXColor val);
220   FXbool writeColorEntry(const FXString& section,const FXchar* name,FXColor val);
221   FXbool writeColorEntry(const FXString& section,const FXString& name,FXColor val);
222 
223   /// Read a boolean registry entry
224   FXbool readBoolEntry(const FXchar* section,const FXchar* name,FXbool def=false) const;
225   FXbool readBoolEntry(const FXString& section,const FXchar* name,FXbool def=false) const;
226   FXbool readBoolEntry(const FXString& section,const FXString& name,FXbool def=false) const;
227 
228   /// Write a boolean value entry
229   FXbool writeBoolEntry(const FXchar* section,const FXchar* name,FXbool val);
230   FXbool writeBoolEntry(const FXString& section,const FXchar* name,FXbool val);
231   FXbool writeBoolEntry(const FXString& section,const FXString& name,FXbool val);
232 
233   /// See if entry exists
234   FXbool existingEntry(const FXchar* section,const FXchar* name) const;
235   FXbool existingEntry(const FXString& section,const FXchar* name) const;
236   FXbool existingEntry(const FXString& section,const FXString& name) const;
237 
238   /// See if section exists
239   FXbool existingSection(const FXchar* section) const;
240   FXbool existingSection(const FXString& section) const;
241 
242   /// Delete a registry entry
243   void deleteEntry(const FXchar* section,const FXchar* name);
244   void deleteEntry(const FXString& section,const FXchar* name);
245   void deleteEntry(const FXString& section,const FXString& name);
246 
247   /// Delete section
248   void deleteSection(const FXchar* section);
249   void deleteSection(const FXString& section);
250 
251   /// Clear all sections
252   void clear();
253 
254   /// Cleanup
255  ~FXSettings();
256   };
257 
258 
259 }
260 
261 #endif
262