blob: e6e7e1b4f432a1dffefda420cb1167f930528343 [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Parsing of config files that have keyword/value pairs. This includes
20 * supporting classes to extract basic config data from files that are stored
21 * as []'s, and uses several supporting classes.
22 * @file ucommon/keydata.h
23 */
24
25/**
26 * Some exercise of keydata routines.
27 * @example keydata.cpp
28 */
29
30#ifndef _UCOMMON_KEYDATA_H_
31#define _UCOMMON_KEYDATA_H_
32
33#ifndef _UCOMMON_CONFIG_H_
34#include <ucommon/platform.h>
35#endif
36
37#ifndef _UCOMMON_LINKED_H_
38#include <ucommon/linked.h>
39#endif
40
41#ifndef _UCOMMON_MEMORY_H_
42#include <ucommon/memory.h>
43#endif
44
45NAMESPACE_UCOMMON
46
47class keyfile;
48
49/**
50 * Data keys parsed from a keyfile. This is a specific [] section from a
51 * fully loaded keyfile, and offers common means to access data members.
52 * This is related to the original GNU Common C++ keydata object, although
53 * it is formed in a keyfile class which is loaded from a config file all
54 * at once.
55 * @author David Sugar <dyfet@gnutelephony.org>
56 */
57class __EXPORT keydata : public OrderedObject
58{
59private:
60 friend class keyfile;
61 OrderedIndex index;
62 keydata(keyfile *file);
63 keydata(keyfile *file, const char *id);
64 const char *name;
65 keyfile *root;
66
67public:
68 /**
69 * A key value set is used for iterative access. Otherwise this class
70 * is normally not used as we usually request the keys directly.
71 * @author David Sugar <dyfet@gnutelephony.org>
72 */
73 class __LOCAL keyvalue : public OrderedObject
74 {
75 private:
76 friend class keydata;
77 friend class keyfile;
78 keyvalue(keyfile *allocator, keydata *section, const char *key, const char *data);
79 public:
80 const char *id;
81 const char *value;
82 };
83
84 friend class keyvalue;
85
86 /**
87 * Lookup a key value by it's id.
88 * @param id to look for.
89 * @return value string or NULL if not found.
90 */
91 const char *get(const char *id) const;
92
93 /**
94 * Lookup a key value by it's id.
95 * @param id to look for.
96 * @return value string or NULL if not found.
97 */
98 inline const char *operator()(const char *id) const
99 {return get(id);};
100
101 /**
102 * Set a keyword and value in the keydata structure. If the keyword
103 * already exists, it is replaced. Removed items still use pager
104 * allocated memory.
105 * @param id to set.
106 * @param value for the id.
107 */
108 void set(const char *id, const char *value);
109
110 /**
111 * Remove a keyword id from the keydata structure. Removed items
112 * still use pager allocated memory.
113 * @param id to remove.
114 */
115 void clear(const char *id);
116
117 /**
118 * Get the name of this section. Useful in iterative examinations.
119 * @return name of keydata section.
120 */
121 inline const char *get(void) const
122 {return name;};
123
124 /**
125 * Get first value object, for iterative examinations.
126 * @return first key value in chain.
127 */
128 inline keyvalue *begin(void) const
129 {return (keyvalue *)index.begin();};
130
131 /**
132 * Get last value object, for iterative examinations.
133 * @return first key value in chain.
134 */
135 inline keyvalue *end(void) const
136 {return (keyvalue*)index.end();};
137
138 /**
139 * Convenience typedef for iterative pointer.
140 */
141 typedef linked_pointer<keyvalue> iterator;
142};
143
144/**
145 * Traditional keypair config file parsing class. This is used to get
146 * generic config data either from a /etc/xxx.conf, a windows style
147 * xxx.ini file, or a ~/.xxxrc file, and parses [] sections from the
148 * entire file at once.
149 */
150class __EXPORT keyfile : public memalloc
151{
152private:
153 friend class keydata;
154 OrderedIndex index;
155 keydata *defaults;
156 int errcode;
157
158protected:
159 keydata *create(const char *section);
160
161#ifdef _MSWINDOWS_
162 void load(HKEY root, keydata *section = NULL, const char *path = NULL);
163 bool save(HKEY root, keydata *section = NULL, const char *path = NULL);
164#endif
165
166public:
167 /**
168 * Create an empty key file ready for loading.
169 * @param pagesize for memory paging.
170 */
171 keyfile(size_t pagesize = 0);
172
173 /**
174 * Create a key file object from an existing config file.
175 * @param path to load from.
176 * @param pagesize for memory paging.
177 */
178 keyfile(const char *path, size_t pagesize = 0);
179
180 keyfile(const keyfile &copy, size_t pagesize = 0);
181
182 /**
183 * Load (overlay) another config file over the currently loaded one.
184 * This is used to merge key data, such as getting default values from
185 * a global config, and then overlaying a local home config file.
186 * @param path to load keys from into current object.
187 */
188 void load(const char *path);
189
190 /**
191 * Save (write) a set of config keys to dist.
192 * @param path of file to save keys to.
193 * @return true on success.
194 */
195 bool save(const char *path);
196
197 /**
198 * Load from an existing keyfile object.
199 * @param source to copy from.
200 */
201 void load(const keyfile *source);
202
203 /**
204 * Load a single set of keys.
205 * @param source of keys to copy.
206 */
207 void load(const keydata *source);
208
209 /**
210 * Release and re-initialize keyfile.
211 */
212 void release(void);
213
214 /**
215 * Get a keydata section name.
216 * @param section name to look for.
217 * @return keydata section object if found, NULL if not.
218 */
219 keydata *get(const char *section) const;
220
221 inline keydata *operator()(const char *section) const
222 {return get(section);};
223
224 inline keydata *operator[](const char *section) const
225 {return get(section);};
226
227 /**
228 * Get the non-sectioned defaults if there are any.
229 * @return default key section.
230 */
231 inline keydata *get(void) const
232 {return defaults;};
233
234 /**
235 * Get first keydata object, for iterative examinations.
236 * @return first key value in chain.
237 */
238 inline keydata *begin(void) const
239 {return (keydata *)index.begin();};
240
241 /**
242 * Get last keydata object, for iterative examinations.
243 * @return first key value in chain.
244 */
245 inline keydata *end(void) const
246 {return (keydata *)index.end();};
247
248 /**
249 * Convenience typedef for iterative pointer.
250 */
251 typedef linked_pointer<keydata> iterator;
252
253 inline int err(void)
254 {return errcode;}
255};
256
257END_NAMESPACE
258
259#endif