2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * Defines a hierarchical registry abstraction. See uniconf.h.
8 #include "uniconfroot.h"
9 #include "uniconfgen.h"
14 UniConf::UniConf(UniConfRoot
*root
, const UniConfKey
&fullkey
)
15 : xroot(root
), xfullkey(fullkey
)
21 UniConf::UniConf() : xroot(NULL
), xfullkey(UniConfKey::EMPTY
)
27 UniConf::UniConf(const UniConf
&other
)
28 : xroot(other
.xroot
), xfullkey(other
.xfullkey
)
42 UniConfKey
UniConf::fullkey(const UniConfKey
&k
) const
44 return k
.subkey(xfullkey
);
48 bool UniConf::exists() const
50 return xroot
->mounts
.exists(xfullkey
);
54 bool UniConf::haschildren() const
56 return xroot
->mounts
.haschildren(xfullkey
);
60 void UniConf::prefetch(bool recursive
) const
62 xroot
->mounts
.prefetch(xfullkey
, recursive
);
66 WvString
UniConf::getme(WvStringParm defvalue
) const
68 WvString value
= xroot
->mounts
.get(xfullkey
);
75 int UniConf::getmeint(int defvalue
) const
77 return xroot
->mounts
.str2int(getme(), defvalue
);
81 void UniConf::setme(WvStringParm value
) const
83 xroot
->mounts
.set(xfullkey
, value
);
87 void UniConf::setmeint(int value
) const
89 setme(WvString(value
));
93 void UniConf::move(const UniConf
&dst
) const
101 void UniConf::copy(const UniConf
&dst
, bool force
) const
103 // do the main key first
106 // now all the children
107 RecursiveIter
i(*this);
108 for (i
.rewind(); i
.next(); )
110 UniConf dst2
= dst
[i
->fullkey(*this)];
111 if (force
|| dst2
.getme().isnull())
112 dst2
.setme(i
->getme());
117 bool UniConf::refresh() const
119 return xroot
->mounts
.refresh();
123 void UniConf::commit() const
125 xroot
->mounts
.commit();
129 IUniConfGen
*UniConf::mount(WvStringParm moniker
, bool refresh
) const
131 return xroot
->mounts
.mount(xfullkey
, moniker
, refresh
);
135 IUniConfGen
*UniConf::mountgen(IUniConfGen
*gen
, bool refresh
) const
137 return xroot
->mounts
.mountgen(xfullkey
, gen
, refresh
);
141 void UniConf::unmount(IUniConfGen
*gen
, bool commit
) const
143 return xroot
->mounts
.unmount(gen
, commit
);
147 bool UniConf::ismountpoint() const
149 return xroot
->mounts
.ismountpoint(xfullkey
);
153 IUniConfGen
*UniConf::whichmount(UniConfKey
*mountpoint
) const
155 return xroot
->mounts
.whichmount(xfullkey
, mountpoint
);
159 bool UniConf::isok() const
161 IUniConfGen
*gen
= whichmount();
162 return gen
&& gen
->isok();
166 void UniConf::add_callback(void *cookie
, const UniConfCallback
&callback
,
169 xroot
->add_callback(cookie
, xfullkey
, callback
, recurse
);
173 void UniConf::del_callback(void *cookie
, bool recurse
) const
175 xroot
->del_callback(cookie
, xfullkey
, recurse
);
179 void UniConf::add_setbool(bool *flag
, bool recurse
) const
181 xroot
->add_setbool(xfullkey
, flag
, recurse
);
185 void UniConf::del_setbool(bool *flag
, bool recurse
) const
187 xroot
->del_setbool(xfullkey
, flag
, recurse
);
191 void UniConf::hold_delta()
193 xroot
->mounts
.hold_delta();
197 void UniConf::unhold_delta()
199 xroot
->mounts
.unhold_delta();
203 void UniConf::clear_delta()
205 xroot
->mounts
.clear_delta();
209 void UniConf::flush_delta()
211 xroot
->mounts
.flush_delta();
215 void UniConf::dump(WvStream
&stream
, bool everything
) const
217 UniConf::RecursiveIter
it(*this);
218 for (it
.rewind(); it
.next(); )
220 WvString
value(it
->getme());
221 if (everything
|| !!value
)
222 stream
.print("%s = %s\n", it
->fullkey(), value
);
228 /***** UniConf::Iter *****/
230 UniConf::Iter::Iter(const UniConf
&_top
)
233 it
= _top
.rootobj()->mounts
.iterator(top
.fullkey());
234 if (!it
) it
= new UniConfGen::NullIter
;
239 /***** UniConf::RecursiveIter *****/
241 UniConf::RecursiveIter::RecursiveIter(const UniConf
&_top
)
244 it
= _top
.rootobj()->mounts
.recursiveiterator(top
.fullkey());
245 if (!it
) it
= new UniConfGen::NullIter
;
249 /***** UniConf::XIter *****/
251 UniConf::XIter::XIter(const UniConf
&_top
, const UniConfKey
&pattern
)
252 : IterBase(_top
), pathead(pattern
.first()),
253 pattail(pattern
.removefirst()), subit(NULL
), it(NULL
), recit(NULL
)
255 if (! pathead
.iswild())
257 // optimization to collect as many consecutive non-wildcard
258 // segments as possible in one go
259 while (! pattail
.isempty())
261 UniConfKey
patnext(pattail
.first());
262 if (patnext
.iswild())
264 pathead
.append(patnext
);
265 pattail
= pattail
.removefirst();
271 UniConf::XIter::~XIter()
277 void UniConf::XIter::cleanup()
297 void UniConf::XIter::rewind()
302 if (pathead
.isempty())
305 ready
= current
.exists();
307 else if (pathead
== UniConfKey::RECURSIVE_ANY
)
309 recit
= new UniConf::RecursiveIter(top
);
311 if (UniConfKey::EMPTY
.matches(pattail
))
313 // pattern includes self
315 ready
= current
.exists();
318 else if (pathead
== UniConfKey::ANY
)
320 it
= new UniConf::Iter(top
);
325 // non-wildcard segment
326 current
= top
[pathead
];
327 if (pattail
.isempty())
329 // don't bother recursing if there are no deeper wildcard
330 // elements (works together with optimization in constructor)
331 ready
= current
.exists();
335 // more wildcards, setup recursion
342 inline bool UniConf::XIter::qnext()
344 if (subit
) // currently in a sub-iterator
346 bool found
= subit
->next();
354 // end of this sub-iterator
360 else // no sub-iterator at all
365 void UniConf::XIter::enter(const UniConf
&child
)
367 subit
= new UniConf::XIter(child
, pattail
);
372 bool UniConf::XIter::next()
382 if (it
&& it
->next())
384 /* Not needed for now since we don't match partial keys
385 if (! pathead.matches(it->key()))
391 // UniConfKey::RECURSIVE_ANY
392 if (recit
&& recit
->next())
397 // anything else or finished
401 // if we get here, qnext() returned true
407 /***** UniConf::SortedIterBase *****/
409 UniConf::SortedIterBase::SortedIterBase(const UniConf
&root
,
410 UniConf::SortedIterBase::Comparator comparator
)
411 : IterBase(root
), xcomparator(comparator
), xkeys()
416 UniConf::SortedIterBase::~SortedIterBase()
422 int UniConf::SortedIterBase::defcomparator(const UniConf
&a
,
425 return a
.fullkey().compareto(b
.fullkey());
429 static UniConf::SortedIterBase::Comparator innercomparator
= NULL
;
431 static bool wrapcomparator(const UniConf
&a
, const UniConf
&b
)
433 return innercomparator(a
, b
) < 0;
437 void UniConf::SortedIterBase::_purge()
439 count
= xkeys
.size();
444 void UniConf::SortedIterBase::_rewind()
447 count
= xkeys
.size();
449 // This code is NOT reentrant because qsort makes it too hard
450 innercomparator
= xcomparator
;
451 std::sort(xkeys
.begin(), xkeys
.end(), wrapcomparator
);
455 bool UniConf::SortedIterBase::next()
459 current
= xkeys
[index
];