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

unimounttreegen.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 UniConfGen that manages a tree of UniConfGen instances. 00006 */ 00007 #include "unimounttreegen.h" 00008 #include "wvmoniker.h" 00009 00010 /***** UniMountTreeGen *****/ 00011 00012 UniMountTreeGen::UniMountTreeGen() 00013 { 00014 mounts = new UniMountTree(NULL, UniConfKey::EMPTY); 00015 } 00016 00017 00018 UniMountTreeGen::~UniMountTreeGen() 00019 { 00020 // destroys all generators 00021 delete mounts; 00022 } 00023 00024 00025 WvString UniMountTreeGen::get(const UniConfKey &key) 00026 { 00027 // consult the generators 00028 hold_delta(); 00029 UniMountTree::GenIter it(*mounts, key); 00030 for (it.rewind(); it.next(); ) 00031 { 00032 UniConfGen *gen = it.ptr(); 00033 WvString result = gen->get(it.tail()); 00034 if (!result.isnull()) 00035 { 00036 unhold_delta(); 00037 return result; 00038 } 00039 } 00040 unhold_delta(); 00041 00042 // ensure key exists if it is in the path of a mountpoint 00043 UniMountTree *node = mounts->find(key); 00044 if (node) 00045 return ""; // fake read-only key not provided by anyone 00046 00047 // no matches 00048 return WvString::null; 00049 } 00050 00051 00052 void UniMountTreeGen::set(const UniConfKey &key, WvStringParm value) 00053 { 00054 // update the generator that defines the key, if any 00055 UniConfKey mountpoint; 00056 UniConfGen *provider = whichmount(key, &mountpoint); 00057 if (provider) 00058 provider->set(mountpoint, value); 00059 } 00060 00061 00062 bool UniMountTreeGen::exists(const UniConfKey &key) 00063 { 00064 // ensure key exists if it is in the path of a mountpoint 00065 UniMountTree *node = mounts->find(key); 00066 if (node) 00067 return true; 00068 00069 // otherwise consult the generators 00070 hold_delta(); 00071 UniMountTree::GenIter it(*mounts, key); 00072 for (it.rewind(); it.next(); ) 00073 { 00074 UniConfGen *gen = it.ptr(); 00075 if (gen->exists(it.tail())) 00076 { 00077 unhold_delta(); 00078 return true; 00079 } 00080 } 00081 unhold_delta(); 00082 00083 // no match 00084 return false; 00085 } 00086 00087 00088 bool UniMountTreeGen::haschildren(const UniConfKey &key) 00089 { 00090 hold_delta(); 00091 UniMountTree *node = mounts->find(key); 00092 bool result = node && node->haschildren(); 00093 if (! result) 00094 { 00095 UniMountTree::GenIter it(*mounts, key); 00096 for (it.rewind(); it.next(); ) 00097 { 00098 UniConfGen *gen = it.ptr(); 00099 if (gen->haschildren(it.tail())) 00100 { 00101 result = true; 00102 break; 00103 } 00104 } 00105 } 00106 unhold_delta(); 00107 return result; 00108 } 00109 00110 00111 bool UniMountTreeGen::refresh() 00112 { 00113 hold_delta(); 00114 bool result = true; 00115 00116 UniConfGenList::Iter i(mounts->generators); 00117 for (i.rewind(); i.next();) 00118 result = result && i->refresh(); 00119 00120 unhold_delta(); 00121 return result; 00122 } 00123 00124 00125 void UniMountTreeGen::commit() 00126 { 00127 hold_delta(); 00128 00129 UniConfGenList::Iter i(mounts->generators); 00130 for (i.rewind(); i.next();) 00131 i->commit(); 00132 00133 unhold_delta(); 00134 } 00135 00136 00137 UniConfGen *UniMountTreeGen::mount(const UniConfKey &key, 00138 WvStringParm moniker, bool refresh) 00139 { 00140 UniConfGen *gen = wvcreate<UniConfGen>(moniker); 00141 if (gen) 00142 mountgen(key, gen, refresh); // assume always succeeds for now 00143 assert(gen && "Moniker doesn't get us a generator!"); 00144 return gen; 00145 } 00146 00147 00148 UniConfGen *UniMountTreeGen::mountgen(const UniConfKey &key, 00149 UniConfGen *gen, bool refresh) 00150 { 00151 UniMountTree *node = mounts->findormake(key); 00152 node->generators.append(gen, true); 00153 00154 hold_delta(); 00155 00156 gen->setcallback(UniConfGenCallback(this, 00157 &UniMountTreeGen::gencallback), node); 00158 if (gen && refresh) 00159 gen->refresh(); 00160 00161 unhold_delta(); 00162 return gen; 00163 } 00164 00165 00166 void UniMountTreeGen::unmount(const UniConfKey &key, 00167 UniConfGen *gen, bool commit) 00168 { 00169 UniMountTree *node = mounts->find(key); 00170 if (!node) 00171 return; 00172 00173 UniConfGenList::Iter genit(node->generators); 00174 if (! genit.find(gen)) 00175 return; 00176 00177 hold_delta(); 00178 00179 if (commit) 00180 gen->commit(); 00181 gen->setcallback(UniConfGenCallback(), NULL); 00182 00183 node->generators.unlink(gen); 00184 00185 unhold_delta(); 00186 } 00187 00188 00189 UniConfGen *UniMountTreeGen::whichmount(const UniConfKey &key, 00190 UniConfKey *mountpoint) 00191 { 00192 hold_delta(); 00193 00194 // see if a generator acknowledges the key 00195 UniMountTree::GenIter it(*mounts, key); 00196 for (it.rewind(); it.next(); ) 00197 { 00198 UniConfGen *gen = it.ptr(); 00199 if (gen->exists(it.tail())) 00200 goto found; 00201 } 00202 // find the generator that would be used to set the value 00203 it.rewind(); 00204 if (! it.next()) 00205 { 00206 unhold_delta(); 00207 return NULL; 00208 } 00209 00210 found: 00211 if (mountpoint) 00212 *mountpoint = it.tail(); 00213 unhold_delta(); 00214 return it.ptr(); 00215 } 00216 00217 00218 bool UniMountTreeGen::ismountpoint(const UniConfKey &key) 00219 { 00220 UniMountTree *node = mounts->find(key); 00221 return node && ! node->generators.isempty(); 00222 } 00223 00224 00225 UniMountTreeGen::Iter *UniMountTreeGen::iterator(const UniConfKey &key) 00226 { 00227 return new KeyIter(*this, key); 00228 } 00229 00230 00231 void UniMountTreeGen::prune(UniMountTree *node) 00232 { 00233 while (node != mounts && !node->isessential()) 00234 { 00235 UniMountTree *next = node->parent(); 00236 delete node; 00237 node = next; 00238 } 00239 } 00240 00241 00242 void UniMountTreeGen::gencallback(const UniConfKey &key, WvStringParm value, 00243 void *userdata) 00244 { 00245 UniMountTree *node = static_cast<UniMountTree*>(userdata); 00246 delta(UniConfKey(node->fullkey(), key), value); 00247 } 00248 00249 00250 00251 /***** UniMountTreeGen::KeyIter *****/ 00252 00253 UniMountTreeGen::KeyIter::KeyIter(UniMountTreeGen &root, const UniConfKey &key) 00254 : xroot(&root), xkey(key), genit(*root.mounts, key), 00255 hack(71), hackit(hack) 00256 { 00257 } 00258 00259 00260 void UniMountTreeGen::KeyIter::rewind() 00261 { 00262 xroot->hold_delta(); 00263 hack.zap(); 00264 00265 // find nodes provided by the root of any mount points. 00266 // (if we want to iterate over /foo, then mounts directly on /foo/blah and 00267 // /foo/snoo must be included) 00268 UniMountTree *node = xroot->mounts->find(xkey); 00269 if (node) 00270 { 00271 UniMountTree::Iter nodeit(*node); 00272 for (nodeit.rewind(); nodeit.next(); ) 00273 hack.add(new WvString(nodeit->key()), true); 00274 } 00275 00276 // walk through *all* generators and add any appropriate sub-keys 00277 // provided by each generator. 00278 for (genit.rewind(); genit.next(); ) 00279 { 00280 UniConfGen *gen = genit.ptr(); 00281 UniConfGen::Iter *keyit = gen->iterator(genit.tail()); 00282 for (keyit->rewind(); keyit->next(); ) 00283 hack.add(new WvString(keyit->key()), true); 00284 delete keyit; 00285 } 00286 00287 hackit.rewind(); 00288 xroot->unhold_delta(); 00289 } 00290 00291 00292 bool UniMountTreeGen::KeyIter::next() 00293 { 00294 return hackit.next(); 00295 } 00296 00297 00298 UniConfKey UniMountTreeGen::KeyIter::key() const 00299 { 00300 return UniConfKey(hackit()); 00301 } 00302 00303 00304 00305 /***** UniMountTree *****/ 00306 00307 UniMountTree::UniMountTree(UniMountTree *parent, 00308 const UniConfKey &key) : 00309 UniConfTree<UniMountTree>(parent, key) 00310 { 00311 } 00312 00313 00314 UniMountTree::~UniMountTree() 00315 { 00316 } 00317 00318 00319 UniMountTree *UniMountTree::findnearest(const UniConfKey &key, 00320 int &split) 00321 { 00322 split = 0; 00323 UniMountTree *node = this; 00324 UniConfKey::Iter it(key); 00325 for (it.rewind(); it.next(); split++) 00326 { 00327 UniMountTree *next = node->findchild(it()); 00328 if (!next) 00329 break; 00330 node = next; 00331 } 00332 return node; 00333 } 00334 00335 00336 UniMountTree *UniMountTree::findormake(const UniConfKey &key) 00337 { 00338 UniMountTree *node = this; 00339 UniConfKey::Iter it(key); 00340 for (it.rewind(); it.next(); ) 00341 { 00342 UniMountTree *prev = node; 00343 node = prev->findchild(it()); 00344 if (!node) 00345 node = new UniMountTree(prev, it()); 00346 } 00347 return node; 00348 } 00349 00350 00351 00352 /***** UniMountTree::MountIter *****/ 00353 00354 UniMountTree::MountIter::MountIter(UniMountTree &root, 00355 const UniConfKey &key) 00356 : xkey(key) 00357 { 00358 bestnode = root.findnearest(key, bestsplit); 00359 } 00360 00361 00362 void UniMountTree::MountIter::rewind() 00363 { 00364 xnode = NULL; 00365 } 00366 00367 00368 bool UniMountTree::MountIter::next() 00369 { 00370 if (! xnode) 00371 { 00372 xsplit = bestsplit; 00373 xnode = bestnode; 00374 } 00375 else if (xsplit != 0) 00376 { 00377 xsplit -= 1; 00378 xnode = xnode->parent(); 00379 } 00380 else 00381 return false; 00382 return true; 00383 } 00384 00385 00386 00387 /***** UniMountTree::GenIter *****/ 00388 00389 UniMountTree::GenIter::GenIter(UniMountTree &root, 00390 const UniConfKey &key) : 00391 UniMountTree::MountIter(root, key), 00392 genit(NULL) 00393 { 00394 } 00395 00396 00397 UniMountTree::GenIter::~GenIter() 00398 { 00399 delete genit; 00400 } 00401 00402 00403 void UniMountTree::GenIter::rewind() 00404 { 00405 if (genit) 00406 { 00407 delete genit; 00408 genit = NULL; 00409 } 00410 UniMountTree::MountIter::rewind(); 00411 } 00412 00413 00414 bool UniMountTree::GenIter::next() 00415 { 00416 for (;;) 00417 { 00418 if (genit && genit->next()) 00419 return true; 00420 if (! UniMountTree::MountIter::next()) 00421 return false; 00422 00423 genit = new UniConfGenList::Iter(node()->generators); 00424 genit->rewind(); 00425 } 00426 return false; 00427 }

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