Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

uniconf.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * Defines a hierarchical registry abstraction. See uniconf.h. 00006 */ 00007 #include "uniconf.h" 00008 #include "uniconfroot.h" 00009 #include "uniconfgen.h" 00010 #include "wvstream.h" 00011 #include <assert.h> 00012 00013 00014 UniConfKey UniConf::fullkey(const UniConfKey &k) const 00015 { 00016 int n = k.numsegments(); 00017 00018 // this function is undefined if k isn't an ancestor! 00019 assert(k == xfullkey.first(n)); 00020 00021 return xfullkey.removefirst(n); 00022 } 00023 00024 00025 bool UniConf::exists() const 00026 { 00027 return xroot->mounts.exists(xfullkey); 00028 } 00029 00030 00031 bool UniConf::haschildren() const 00032 { 00033 return xroot->mounts.haschildren(xfullkey); 00034 } 00035 00036 00037 WvString UniConf::get(WvStringParm defvalue) const 00038 { 00039 WvString value = xroot->mounts.get(xfullkey); 00040 if (value.isnull()) 00041 return defvalue; 00042 return value; 00043 } 00044 00045 00046 int UniConf::getint(int defvalue) const 00047 { 00048 return xroot->mounts.str2int(get(), defvalue); 00049 } 00050 00051 00052 void UniConf::set(WvStringParm value) const 00053 { 00054 xroot->mounts.set(xfullkey, value); 00055 } 00056 00057 00058 void UniConf::setint(int value) const 00059 { 00060 set(WvString(value)); 00061 } 00062 00063 00064 void UniConf::move(const UniConf &dst) 00065 { 00066 dst.remove(); 00067 00068 // do the main key first 00069 dst.set(get()); 00070 00071 // now all the children 00072 RecursiveIter i(*this); 00073 for (i.rewind(); i.next(); ) 00074 dst[i->fullkey(*this)].set(i->get()); 00075 00076 remove(); 00077 } 00078 00079 00080 void UniConf::copy(const UniConf &dst, bool force) const 00081 { 00082 // do the main key first 00083 dst.set(get()); 00084 00085 // now all the children 00086 RecursiveIter i(*this); 00087 for (i.rewind(); i.next(); ) 00088 { 00089 UniConf dst2 = dst[i->fullkey(*this)]; 00090 if (force || dst2.get().isnull()) 00091 dst2.set(i->get()); 00092 } 00093 } 00094 00095 00096 bool UniConf::refresh() const 00097 { 00098 return xroot->mounts.refresh(); 00099 } 00100 00101 00102 void UniConf::commit() const 00103 { 00104 xroot->mounts.commit(); 00105 } 00106 00107 00108 UniConfGen *UniConf::mount(WvStringParm moniker, bool refresh) const 00109 { 00110 return xroot->mounts.mount(xfullkey, moniker, refresh); 00111 } 00112 00113 00114 UniConfGen *UniConf::mountgen(UniConfGen *gen, bool refresh) const 00115 { 00116 return xroot->mounts.mountgen(xfullkey, gen, refresh); 00117 } 00118 00119 00120 void UniConf::unmount(UniConfGen *gen, bool commit) const 00121 { 00122 return xroot->mounts.unmount(gen, commit); 00123 } 00124 00125 00126 bool UniConf::ismountpoint() const 00127 { 00128 return xroot->mounts.ismountpoint(xfullkey); 00129 } 00130 00131 00132 UniConfGen *UniConf::whichmount(UniConfKey *mountpoint) const 00133 { 00134 return xroot->mounts.whichmount(xfullkey, mountpoint); 00135 } 00136 00137 00138 void UniConf::add_callback(void *cookie, const UniConfCallback &callback, 00139 bool recurse) const 00140 { 00141 xroot->add_callback(cookie, xfullkey, callback, recurse); 00142 } 00143 00144 00145 void UniConf::del_callback(void *cookie, bool recurse) const 00146 { 00147 xroot->del_callback(cookie, xfullkey, recurse); 00148 } 00149 00150 00151 void UniConf::add_setbool(bool *flag, bool recurse) const 00152 { 00153 xroot->add_setbool(xfullkey, flag, recurse); 00154 } 00155 00156 00157 void UniConf::del_setbool(bool *flag, bool recurse) const 00158 { 00159 xroot->del_setbool(xfullkey, flag, recurse); 00160 } 00161 00162 00163 void UniConf::hold_delta() 00164 { 00165 xroot->mounts.hold_delta(); 00166 } 00167 00168 00169 void UniConf::unhold_delta() 00170 { 00171 xroot->mounts.unhold_delta(); 00172 } 00173 00174 00175 void UniConf::clear_delta() 00176 { 00177 xroot->mounts.clear_delta(); 00178 } 00179 00180 00181 void UniConf::flush_delta() 00182 { 00183 xroot->mounts.flush_delta(); 00184 } 00185 00186 00187 void UniConf::dump(WvStream &stream, bool everything) const 00188 { 00189 UniConf::RecursiveIter it(*this); 00190 for (it.rewind(); it.next(); ) 00191 { 00192 WvString value(it->get()); 00193 if (everything || !!value) 00194 stream.print("%s = %s\n", it->fullkey(), value); 00195 } 00196 } 00197 00198 00199 00200 /***** UniConf::Iter *****/ 00201 00202 UniConf::Iter::Iter(const UniConf &_top) 00203 : IterBase(_top), it(_top.rootobj()->mounts.iterator(top.fullkey())) 00204 { 00205 } 00206 00207 00208 00209 /***** UniConf::RecursiveIter *****/ 00210 00211 UniConf::RecursiveIter::RecursiveIter(const UniConf &root) 00212 : IterBase(root) 00213 { 00214 } 00215 00216 00217 void UniConf::RecursiveIter::rewind() 00218 { 00219 itlist.zap(); 00220 UniConf::Iter *subi = new UniConf::Iter(top); 00221 subi->rewind(); 00222 itlist.prepend(subi, true); 00223 } 00224 00225 00226 bool UniConf::RecursiveIter::next() 00227 { 00228 assert(!itlist.isempty()); // trying to seek past the end is illegal! 00229 00230 UniConf::IterList::Iter i(itlist); 00231 for (i.rewind(); i.next(); ) 00232 { 00233 if (i->next()) // NOTE: not the same as i.next() 00234 { 00235 // return the item first 00236 current = **i; 00237 00238 // set up so next time, we go into its subtree 00239 if (current.haschildren()) 00240 { 00241 UniConf::Iter *subi = new UniConf::Iter(current); 00242 subi->rewind(); 00243 itlist.prepend(subi, true); 00244 } 00245 00246 return true; 00247 } 00248 00249 // otherwise, this iterator is empty; move up the tree 00250 i.xunlink(); 00251 } 00252 00253 // all done! 00254 return false; 00255 } 00256 00257 00258 00259 /***** UniConf::XIter *****/ 00260 00261 UniConf::XIter::XIter(const UniConf &_top, const UniConfKey &pattern) 00262 : IterBase(_top), pathead(pattern.first()), 00263 pattail(pattern.removefirst()), subit(NULL), it(NULL), recit(NULL) 00264 { 00265 if (! pathead.iswild()) 00266 { 00267 // optimization to collect as many consecutive non-wildcard 00268 // segments as possible in one go 00269 while (! pattail.isempty()) 00270 { 00271 UniConfKey patnext(pattail.first()); 00272 if (patnext.iswild()) 00273 break; 00274 pathead.append(patnext); 00275 pattail = pattail.removefirst(); 00276 } 00277 } 00278 } 00279 00280 00281 UniConf::XIter::~XIter() 00282 { 00283 cleanup(); 00284 } 00285 00286 00287 void UniConf::XIter::cleanup() 00288 { 00289 if (subit) 00290 { 00291 delete subit; 00292 subit = NULL; 00293 } 00294 if (it) 00295 { 00296 delete it; 00297 it = NULL; 00298 } 00299 if (recit) 00300 { 00301 delete recit; 00302 recit = NULL; 00303 } 00304 } 00305 00306 00307 void UniConf::XIter::rewind() 00308 { 00309 cleanup(); 00310 ready = false; 00311 00312 if (pathead.isempty()) 00313 { 00314 current = top; 00315 ready = current.exists(); 00316 } 00317 else if (pathead == UniConfKey::RECURSIVE_ANY) 00318 { 00319 recit = new UniConf::RecursiveIter(top); 00320 recit->rewind(); 00321 if (UniConfKey::EMPTY.matches(pattail)) 00322 { 00323 // pattern includes self 00324 current = top; 00325 ready = current.exists(); 00326 } 00327 } 00328 else if (pathead == UniConfKey::ANY) 00329 { 00330 it = new UniConf::Iter(top); 00331 it->rewind(); 00332 } 00333 else 00334 { 00335 // non-wildcard segment 00336 current = top[pathead]; 00337 if (pattail.isempty()) 00338 { 00339 // don't bother recursing if there are no deeper wildcard 00340 // elements (works together with optimization in constructor) 00341 ready = current.exists(); 00342 } 00343 else 00344 { 00345 // more wildcards, setup recursion 00346 enter(current); 00347 } 00348 } 00349 } 00350 00351 00352 inline bool UniConf::XIter::qnext() 00353 { 00354 if (subit) // currently in a sub-iterator 00355 { 00356 bool found = subit->next(); 00357 if (found) 00358 { 00359 current = **subit; 00360 return true; 00361 } 00362 else 00363 { 00364 // end of this sub-iterator 00365 delete subit; 00366 subit = NULL; 00367 return false; 00368 } 00369 } 00370 else // no sub-iterator at all 00371 return false; 00372 } 00373 00374 00375 void UniConf::XIter::enter(const UniConf &child) 00376 { 00377 subit = new UniConf::XIter(child, pattail); 00378 subit->rewind(); 00379 } 00380 00381 00382 bool UniConf::XIter::next() 00383 { 00384 if (ready) 00385 { 00386 ready = false; 00387 return true; 00388 } 00389 while (!qnext()) 00390 { 00391 // UniConfKey::ANY 00392 if (it && it->next()) 00393 { 00394 /* Not needed for now since we don't match partial keys 00395 if (! pathead.matches(it->key())) 00396 break; 00397 */ 00398 enter(**it); 00399 continue; 00400 } 00401 // UniConfKey::RECURSIVE_ANY 00402 if (recit && recit->next()) 00403 { 00404 enter(**recit); 00405 continue; 00406 } 00407 // anything else or finished 00408 return false; 00409 } 00410 00411 // if we get here, qnext() returned true 00412 return true; 00413 } 00414 00415 00416 00417 /***** UniConf::SortedIterBase *****/ 00418 00419 UniConf::SortedIterBase::SortedIterBase(const UniConf &root, 00420 UniConf::SortedIterBase::Comparator comparator) 00421 : IterBase(root), xcomparator(comparator), xkeys(true) 00422 { 00423 } 00424 00425 00426 UniConf::SortedIterBase::~SortedIterBase() 00427 { 00428 _purge(); 00429 } 00430 00431 00432 int UniConf::SortedIterBase::defcomparator(const UniConf &a, 00433 const UniConf &b) 00434 { 00435 return a.fullkey().compareto(b.fullkey()); 00436 } 00437 00438 00439 UniConf::SortedIterBase::Comparator 00440 UniConf::SortedIterBase::innercomparator = NULL; 00441 00442 int UniConf::SortedIterBase::wrapcomparator(const UniConf **a, 00443 const UniConf **b) 00444 { 00445 return innercomparator(**a, **b); 00446 } 00447 00448 00449 void UniConf::SortedIterBase::_purge() 00450 { 00451 count = xkeys.count(); 00452 xkeys.zap(); 00453 } 00454 00455 00456 void UniConf::SortedIterBase::_rewind() 00457 { 00458 index = 0; 00459 count = xkeys.count(); 00460 00461 // This code is NOT reentrant because qsort makes it too hard 00462 innercomparator = xcomparator; 00463 qsort(xkeys.ptr(), count, sizeof(UniConf*), 00464 (int (*)(const void *, const void *))wrapcomparator); 00465 } 00466 00467 00468 bool UniConf::SortedIterBase::next() 00469 { 00470 if (index >= count) 00471 return false; 00472 current = *xkeys[index]; 00473 index += 1; 00474 return true; 00475 }

Generated on Tue Oct 5 01:09:19 2004 for WvStreams by doxygen 1.3.7