2 * Worldvisions Weaver Software:
3 * Copyright (C) 2002 Net Integration Technologies, Inc.
5 * An abstract data container that backs a UniConf tree.
10 #include "uniconfpair.h"
11 #include "wvcallbacklist.h"
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
)>
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
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 *****/
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;
69 * Refreshes information about a key recursively.
70 * May discard uncommitted data.
72 * The default implementation always returns true.
74 virtual bool refresh() = 0;
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 *****/
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;
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) */
159 /** A concrete null iterator type (see below) */
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
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
;
208 UniConfPairList deltas
;
211 /** Creates a UniConfGen object. */
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.
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.
257 * Clears the list of pending notifications without sending them.
258 * Does not affect the hold nesting count.
263 * Flushes the list of pending notifications by sending them.
264 * Does not affect the hold nesting count.
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 *****/
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
);
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
321 * TODO: Consider changing this rule depending on observed usage patterns.
323 class UniConfGen::Iter
326 /** Destroys the iterator. */
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;
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
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