Make WvStreams compile with gcc 4.4.
[wvstreams.git] / include / uniconfgen.h
blobbc4e4d3dc78a22d75c05cea4ea8dd0a8a4d7c512
1 /* -*- Mode: C++ -*-
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2002 Net Integration Technologies, Inc.
4 *
5 * An abstract data container that backs a UniConf tree.
6 */
7 #ifndef __UNICONFGEN_H
8 #define __UNICONFGEN_H
10 #include "uniconfpair.h"
11 #include "wvcallbacklist.h"
12 #include "wvtr1.h"
14 class UniConfGen;
15 class UniListIter;
17 /**
18 * The callback type for signalling key changes from a UniConfGen.
20 * Generators that wrap other generators should catch notifications
21 * and reissue them using themselves as the "gen" parameter and their
22 * userdata as the "userdata parameter". This can be done effectively by
23 * invoking the delta() function on receipt of a notification from a
24 * wrapped generator. See UniFilterGen.
26 * Parameters: gen, key, userdata
27 * gen - the externally visible generator whose key has changed
28 * key - the key that has changed
30 typedef wv::function<void(const UniConfKey&, WvStringParm)>
31 UniConfGenCallback;
33 /**
34 * An abstract data container that backs a UniConf tree.
36 * This is intended to be implemented to provide support for fetching
37 * and storing keys and values using different access methods.
39 class IUniConfGen : public IObject
41 public:
42 virtual ~IUniConfGen();
44 /***** Notification API *****/
46 /** Adds a callback for change notification. */
47 virtual void add_callback(void *cookie,
48 const UniConfGenCallback &callback) = 0;
50 /** Removes a callback for change notification. */
51 virtual void del_callback(void *cookie) = 0;
54 /***** Status API *****/
56 /**
57 * Determines if the generator is usable and working properly.
58 * The default implementation always returns true.
60 virtual bool isok() = 0;
63 /***** Key Persistence API *****/
65 /** Commits any changes. The default implementation does nothing. */
66 virtual void commit() = 0;
68 /**
69 * Refreshes information about a key recursively.
70 * May discard uncommitted data.
72 * The default implementation always returns true.
74 virtual bool refresh() = 0;
76 /**
77 * Flushes any commitment/notification buffers .
79 * The default implementation always returns true.
80 * NOTE: This method should be 'protected'
82 virtual void flush_buffers() = 0;
84 /***** Key Retrieval API *****/
86 /**
87 * Indicate that we will eventually be interested in doing get(),
88 * haschildren(), or other "get-like" operations on a particular key
89 * or tree of keys. The generator may be able to speed up these
90 * operations by, say, caching them in advance.
92 * This function is not allowed to do blocking operations. It is allowed
93 * to do nothing at all, however, and then get() might block later.
95 virtual void prefetch(const UniConfKey &key, bool recursive) = 0;
97 /**
98 * Fetches a string value for a key from the registry. If the key doesn't
99 * exist, the return value has .isnull() == true.
101 virtual WvString get(const UniConfKey &key) = 0;
104 * Without fetching its value, returns true if a key exists.
106 * This is provided because it is often more efficient to
107 * test existance than to actually retrieve the value.
109 * The default implementation returns !get(key).isnull().
111 virtual bool exists(const UniConfKey &key) = 0;
115 * Converts a string to an integer. If the string is null or not
116 * recognized, return defvalue.
118 * This is here to support the common str2int(get(key)).
120 * The default implementation recognizes the booleans 'true', 'yes', 'on'
121 * and 'enabled' as 1, and 'false', 'no', 'off' and 'disabled' as 0.
123 virtual int str2int(WvStringParm s, int defvalue) const = 0;
126 /***** Key Storage API *****/
129 * Stores a string value for a key into the registry. If the value is
130 * WvString::null, the key is deleted.
132 virtual void set(const UniConfKey &key, WvStringParm value) = 0;
136 * Stores multiple key-value pairs into the registry. If the value is
137 * WvString::null, the key is deleted.
139 virtual void setv(const UniConfPairList &pairs) = 0;
142 /***** Key Enumeration API *****/
145 * Returns true if a key has children.
147 * This is provided because it is often more efficient to
148 * test existance than to actually retrieve the keys.
150 * The default implementation uses the iterator returned by iterator()
151 * to test whether the child has any keys.
152 * Subclasses are strongly encouraged to provide a better implementation.
154 virtual bool haschildren(const UniConfKey &key) = 0;
156 /** The abstract iterator type (see below) */
157 class Iter;
159 /** A concrete null iterator type (see below) */
160 class NullIter;
162 /** An iterator over a constant list of keys (see below) */
163 typedef ::UniListIter ListIter;
166 * Returns an iterator over the children of the specified key.
167 * May return NULL or an empty iterator if the key has no children.
169 * The caller takes ownership of the returned iterator and is responsible
170 * for deleting it when finished.
172 virtual Iter *iterator(const UniConfKey &key) = 0;
175 * Like iterator(), but the returned iterator is recursive, that is,
176 * it will return children of the immediate children, not just the
177 * immediate children themselves.
179 * May return NULL if the key has no immediate children (since that means
180 * there are also no indirect children).
182 * Note that UniConfGen::recursiveiterator() is a default
183 * implementation that just calls iterator() recursively, so it'll work
184 * in any derived class without you overriding this function. However,
185 * you might want to do it anyway if it would be more efficient in your
186 * particular case.
188 virtual Iter *recursiveiterator(const UniConfKey &key) = 0;
191 DEFINE_IID(IUniConfGen, {0x7ca76e98, 0xb694, 0x43ca,
192 {0xb0, 0x56, 0x8b, 0x9d, 0xde, 0x9a, 0xbe, 0x9f}});
196 * A default implementation of IUniConfGen, providing various handy features
197 * that save trouble when implementing typical generators.
199 class UniConfGen : public IUniConfGen
201 IMPLEMENT_IOBJECT(UniConfGen);
203 // These fields are deliberately hidden to encourage use of the
204 // special notification members
206 WvCallbackList<UniConfGenCallback> cblist;
207 int hold_nesting;
208 UniConfPairList deltas;
210 protected:
211 /** Creates a UniConfGen object. */
212 UniConfGen();
214 public:
215 /** Destroys the UniConfGen and may discard uncommitted data. */
216 virtual ~UniConfGen();
218 /***** Notification API *****/
221 * Adds a callback for change notification.
222 * Must *not* be reimplemented by subclasses of UniConfGen.
224 virtual void add_callback(void *cookie,
225 const UniConfGenCallback &callback);
226 virtual void del_callback(void *cookie);
229 * Immediately sends notification that a key has possibly changed.
230 * Takes care of the details of invoking the callback.
232 * Note: You probably want to be using delta() instead.
234 void dispatch_delta(const UniConfKey &key, WvStringParm value);
237 * Pauses notifications until matched with a call to unhold_delta().
239 * While paused, notification events are placed into a pending list.
240 * Redundant notifications may be discarded.
242 * Use this to safeguard non-reentrant code.
244 void hold_delta();
247 * Resumes notifications when each hold_delta() has been matched.
249 * On resumption, dispatches all pending notifications except
250 * those that were destined to watches that were removed.
252 * Use this to safeguard non-reentrant code.
254 void unhold_delta();
257 * Clears the list of pending notifications without sending them.
258 * Does not affect the hold nesting count.
260 void clear_delta();
263 * Flushes the list of pending notifications by sending them.
264 * Does not affect the hold nesting count.
266 void flush_delta();
269 * Call this when a key's value or children have possibly changed.
271 * If the hold nesting count is 0, the notification is sent immediately.
272 * Otherwise it is added to a pending list for later.
274 void delta(const UniConfKey &key, WvStringParm value);
276 /***** Status API *****/
277 virtual bool isok();
279 /***** Key Persistence API *****/
280 virtual void commit() { }
281 virtual bool refresh() { return true; }
282 virtual void prefetch(const UniConfKey &key, bool recursive) { }
283 virtual WvString get(const UniConfKey &key) = 0;
284 virtual bool exists(const UniConfKey &key);
285 virtual int str2int(WvStringParm s, int defvalue) const;
287 /***** Key Storage API *****/
288 virtual void set(const UniConfKey &key, WvStringParm value) = 0;
289 virtual void setv(const UniConfPairList &pairs) = 0;
291 virtual void flush_buffers() = 0;
293 /***** Key Enumeration API *****/
294 virtual bool haschildren(const UniConfKey &key);
295 virtual Iter *iterator(const UniConfKey &key) = 0;
297 // a helpful default that just calls iterator() recursively
298 virtual Iter *recursiveiterator(const UniConfKey &key);
300 protected:
301 // A naive implementation of setv() that uses only set().
302 void setv_naive(const UniConfPairList &pairs);
305 DeclareWvList(IUniConfGen);
306 DeclareWvList2(UniConfGenList, IUniConfGen);
310 * An abstract iterator over keys and values in a generator.
312 * Unlike other WvStreams iterators, this one declares virtual methods so
313 * that UniConfGen implementations can supply the right behaviour
314 * through a common interface that does not depend on static typing.
316 * The precise traversal sequence is defined by the iterator implementation.
318 * The iterator need not support concurrent modifications of the underlying
319 * data structures.
321 * TODO: Consider changing this rule depending on observed usage patterns.
323 class UniConfGen::Iter
325 public:
326 /** Destroys the iterator. */
327 virtual ~Iter() { }
330 * Rewinds the iterator.
331 * Must be called prior to the first invocation of next().
333 virtual void rewind() = 0;
336 * Seeks to the next element in the sequence.
337 * Returns true if that element exists.
338 * Must be called prior to the first invocation of key().
340 virtual bool next() = 0;
342 /** Returns the current key. */
343 virtual UniConfKey key() const = 0;
345 /**
346 * Returns the value of the current key. You could just do a get(),
347 * but maybe your generator has a more efficient way.
349 virtual WvString value() const = 0;
354 * An iterator that's always empty.
355 * This is handy if you don't have anything good to iterate over.
357 class UniConfGen::NullIter : public UniConfGen::Iter
359 public:
360 /***** Overridden members *****/
362 virtual void rewind() { }
363 virtual bool next() { return false; }
364 virtual UniConfKey key() const { return UniConfKey::EMPTY; }
365 virtual WvString value() const { return WvString(); }
369 #endif // __UNICONFGEN_H