WvStreams
uniconfgen.cc
1/*
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#include "uniconfgen.h"
8#include "strutils.h"
9
10// FIXME: interfaces (IUniConfGen) shouldn't have implementations!
11IUniConfGen::~IUniConfGen()
12{
13}
14
19
21{
22 hold_nesting = 0;
23}
24
25
27{
28 assert(cblist.isempty());
29}
30
31
33{
34 hold_nesting++;
35}
36
37
39{
40 assert(hold_nesting > 0);
41 if (hold_nesting == 1)
43 hold_nesting--;
44}
45
46
48{
49 deltas.zap();
50}
51
52
54{
55 UniConfPairList::Iter it(deltas);
56 for (;;)
57 {
58 it.rewind();
59 if (! it.next())
60 break;
61
62 UniConfKey key((*it).key());
63 WvString value((*it).value());
64
65 it.xunlink();
66 dispatch_delta(key, value);
67 }
68}
69
70
72{
73 cblist(key, value);
74}
75
76
78{
79 if (hold_nesting == 0)
80 {
81 // not nested, dispatch immediately
82 dispatch_delta(key, value);
83 }
84 else
85 {
86 hold_delta();
87 deltas.add(new UniConfPair(key, value), true);
89 }
90}
91
92
93void UniConfGen::setv_naive(const UniConfPairList &pairs)
94{
95 UniConfPairList::Iter pair(pairs);
96 for (pair.rewind(); pair.next(); )
97 set(pair->key(), pair->value());
98}
99
100
102{
103 bool children = false;
104
105 hold_delta();
106
107 Iter *it = iterator(key);
108 if (it)
109 {
110 it->rewind();
111 if (it->next()) children = true;
112 delete it;
113 }
114
115 unhold_delta();
116 return children;
117}
118
119
121{
122 return !get(key).isnull();
123}
124
125
126int UniConfGen::str2int(WvStringParm value, int defvalue) const
127{
128 // also recognize bool strings as integers
129 const char *strs[] = {
130 "true", "yes", "on", "enabled",
131 "false", "no", "off", "disabled"
132 };
133 const size_t numtruestrs = 4;
134
135 if (!value.isnull())
136 {
137 // try to recognize an integer
138 char *end;
139 int num = strtol(value.cstr(), &end, 0);
140 if (end != value.cstr())
141 return num; // was a valid integer
142
143 // try to recognize a special string
144 for (size_t i = 0; i < sizeof(strs) / sizeof(const char*); ++i)
145 if (strcasecmp(value, strs[i]) == 0)
146 return i < numtruestrs;
147 }
148 return defvalue;
149}
150
151
153{
154 return true;
155}
156
157
158void UniConfGen::add_callback(void *cookie,
159 const UniConfGenCallback &callback)
160{
161 cblist.add(callback, cookie);
162}
163
164
165void UniConfGen::del_callback(void *cookie)
166{
167 cblist.del(cookie);
168}
169
170
171
172class _UniConfGenRecursiveIter : public IUniConfGen::Iter
173{
175 IUniConfGen *gen;
176 UniConfKey top, current;
177 bool sub_next;
178
179public:
181 : top(_top)
182 {
183 gen = _gen;
184 sub_next = false;
185 }
186
187 virtual ~_UniConfGenRecursiveIter() { }
188
189 virtual void rewind()
190 {
191 current = "";
192 sub_next = false;
193 itlist.zap();
194
195 Iter *subi = gen->iterator(top);
196 if (subi)
197 {
198 subi->rewind();
199 itlist.prepend(subi, true);
200 }
201 }
202
203 virtual bool next()
204 {
205 //assert(!itlist.isempty()); // trying to seek past the end is illegal!
206
207 if (sub_next)
208 {
209 sub_next = false;
210
211 UniConfKey subkey(itlist.first()->key());
212 UniConfKey newkey(current, subkey);
213 //fprintf(stderr, "subiter: '%s'\n", newkey.cstr());
214 Iter *newsub = gen->iterator(UniConfKey(top, newkey));
215 if (newsub)
216 {
217 current.append(subkey);
218 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
219 newsub->rewind();
220 itlist.prepend(newsub, true);
221 }
222 }
223
225 for (i.rewind(); i.next(); )
226 {
227 if (i->next()) // NOTE: not the same as i.next()
228 {
229 // set up so next time, we go into its subtree
230 sub_next = true;
231 return true;
232 }
233
234 // otherwise, this iterator is empty; move up the tree
235 current = current.removelast();
236 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
237 i.xunlink();
238 }
239
240 // all done!
241 return false;
242 }
243
244 virtual UniConfKey key() const
245 {
246 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
247 if (!itlist.isempty())
248 return UniConfKey(current, itlist.first()->key());
249 else
250 return current;
251 }
252
253 virtual WvString value() const
254 {
255 return gen->get(UniConfKey(top, key()));
256 }
257};
258
259
264
265
The basic interface which is included by all other XPLC interfaces and objects.
Definition IObject.h:65
An abstract data container that backs a UniConf tree.
Definition uniconfgen.h:40
virtual Iter * iterator(const UniConfKey &key)=0
Returns an iterator over the children of the specified key.
virtual WvString get(const UniConfKey &key)=0
Fetches a string value for a key from the registry.
An abstract iterator over keys and values in a generator.
Definition uniconfgen.h:324
virtual bool next()=0
Seeks to the next element in the sequence.
virtual void rewind()=0
Rewinds the iterator.
A default implementation of IUniConfGen, providing various handy features that save trouble when impl...
Definition uniconfgen.h:200
void dispatch_delta(const UniConfKey &key, WvStringParm value)
Immediately sends notification that a key has possibly changed.
Definition uniconfgen.cc:71
void hold_delta()
Pauses notifications until matched with a call to unhold_delta().
Definition uniconfgen.cc:32
void unhold_delta()
Resumes notifications when each hold_delta() has been matched.
Definition uniconfgen.cc:38
virtual ~UniConfGen()
Destroys the UniConfGen and may discard uncommitted data.
Definition uniconfgen.cc:26
UniConfGen()
Creates a UniConfGen object.
Definition uniconfgen.cc:20
void delta(const UniConfKey &key, WvStringParm value)
Call this when a key's value or children have possibly changed.
Definition uniconfgen.cc:77
virtual WvString get(const UniConfKey &key)=0
Fetches a string value for a key from the registry.
virtual Iter * recursiveiterator(const UniConfKey &key)
Like iterator(), but the returned iterator is recursive, that is, it will return children of the imme...
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
virtual void add_callback(void *cookie, const UniConfGenCallback &callback)
Adds a callback for change notification.
virtual int str2int(WvStringParm s, int defvalue) const
Converts a string to an integer.
virtual void del_callback(void *cookie)
Removes a callback for change notification.
void flush_delta()
Flushes the list of pending notifications by sending them.
Definition uniconfgen.cc:53
virtual Iter * iterator(const UniConfKey &key)=0
Returns an iterator over the children of the specified key.
void clear_delta()
Clears the list of pending notifications without sending them.
Definition uniconfgen.cc:47
virtual bool isok()
Determines if the generator is usable and working properly.
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition uniconfkey.h:39
UniConfKey removelast(int n=1) const
Returns the path formed by removing the last n segments of this path.
Definition uniconfkey.h:346
void append(const UniConfKey &other)
Appends a path to this path.
Represents a simple key-value pair.
Definition uniconfpair.h:17
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition wvstring.h:94
bool isnull() const
returns true if this string is null
Definition wvstring.h:290
const char * cstr() const
return a (const char *) for this string.
Definition wvstring.h:267
void rewind()
Rewinds the iterator to make it point to an imaginary element preceeding the first element of the lis...
Definition wvlinklist.h:90
WvLink * next()
Moves the iterator along the list to point to the next element.
Definition wvlinklist.h:103
bool isempty() const
Quickly determines if the list is empty.
Definition wvlinklist.h:62
The iterator type for linked lists.
Definition wvlinklist.h:351
void xunlink(bool destroy=true)
Unlinks the current element from the list but unlike unlink() automatically returns the iterator to t...
Definition wvlinklist.h:409
A linked list container class.
Definition wvlinklist.h:198
void prepend(T *data, bool autofree, const char *id=NULL)
Prepends the element to the beginning of the list.
Definition wvlinklist.h:293
T * first() const
Returns a pointer to the first element in the linked list.
Definition wvlinklist.h:241
void zap(bool destroy=true)
Clears the linked list.
Definition wvlinklist.h:228
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330
#define UUID_MAP_END
Marks the end of an interface map.
Definition utils.h:80
#define UUID_MAP_BEGIN(component)
Start the interface map for "component".
Definition utils.h:63
#define UUID_MAP_ENTRY(iface)
Add an entry to an interface map.
Definition utils.h:68