WvStreams
uniconf.h
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Defines a hierarchical registry abstraction.
00006  */
00007 #ifndef __UNICONF_H
00008 #define __UNICONF_H
00009 
00010 #include <vector>
00011 
00012 #include "uniconfgen.h"
00013 #include "uniconfkey.h"
00014 #include "wvtr1.h"
00015 
00016 class WvStream;
00017 class UniConf;
00018 class UniConfRoot;
00019 
00027 typedef wv::function<void(const UniConf&, const UniConfKey&)> UniConfCallback;
00028 
00050 class UniConf
00051 {
00052     friend class UniConfRoot;
00053     
00054 protected:
00055     UniConfRoot *xroot;
00056     UniConfKey xfullkey;
00057 
00064     UniConf(UniConfRoot *root, const UniConfKey &fullkey = UniConfKey::EMPTY);
00065     
00066 public:
00068     UniConf();
00069     
00071     UniConf(const UniConf &other);
00072     
00074     virtual ~UniConf();
00075 
00076     
00077     /***** Handle Manipulation API *****/
00078 
00080     UniConf root() const
00081         { return UniConf(xroot, UniConfKey::EMPTY); }
00082 
00084     UniConf parent() const
00085         { return UniConf(xroot, xfullkey.removelast()); }
00086     
00091     UniConfRoot *rootobj() const
00092         { return xroot; }
00093 
00095     bool isnull() const
00096         { return xroot == NULL; }
00097 
00099     UniConfKey fullkey() const
00100         { return xfullkey; }
00101     
00104     UniConfKey fullkey(const UniConfKey &k) const;
00105     
00107     UniConfKey fullkey(const UniConf &cfg) const
00108         { return fullkey(cfg.fullkey()); }
00109 
00111     UniConfKey key() const
00112         { return xfullkey.last(); }
00113 
00119     const UniConf operator[] (const UniConfKey &key) const
00120         { return UniConf(xroot, UniConfKey(xfullkey, key)); }
00121 
00126     const UniConf u(const UniConfKey &key) const
00127         { return (*this)[key]; }
00128 
00130     UniConf &operator= (const UniConf &other)
00131     {
00132         xroot = other.xroot;
00133         xfullkey = other.xfullkey;
00134         return *this;
00135     }
00136 
00137     
00138     /***** Key Retrieval API *****/
00139     
00141     void prefetch(bool recursive) const;
00142     
00147     WvString getme(WvStringParm defvalue = WvString::null) const;
00148 
00150     WvString operator* () const
00151         { return getme(); }
00152 
00154     WvStringStar operator -> () const
00155         { return getme(); }
00156     
00158     WvString xget(WvStringParm key,
00159                   WvStringParm defvalue = WvString::null) const
00160         { return (*this)[key].getme(defvalue); }
00161 
00169     int getmeint(int defvalue = 0) const;
00170 
00172     int xgetint(WvStringParm key, int defvalue = 0) const
00173         { return (*this)[key].getmeint(defvalue); }
00174 
00181     bool exists() const;
00182 
00183 
00184     /***** Key Storage API *****/
00185 
00190     void setme(WvStringParm value) const;
00191 
00195     void setme(WVSTRING_FORMAT_DECL) const
00196         { return setme(WvString(WVSTRING_FORMAT_CALL)); }
00197 
00199     void xset(WvStringParm key, WvStringParm value) const
00200         { (*this)[key].setme(value); }
00201 
00205     void setmeint(int value) const;
00206 
00208     void xsetint(WvStringParm key, int value) const
00209         { (*this)[key].setmeint(value); }
00210 
00211 
00212     /***** Key Handling API *****/
00213 
00227     void move(const UniConf &dst) const;
00228 
00232     void remove() const
00233         { setme(WvString::null); }
00234 
00244     void copy(const UniConf &dst, bool force) const;
00245 
00246 
00247     
00248     /***** Key Persistence API *****/
00249 
00255     bool refresh() const;
00256     
00260     void commit() const;
00261 
00262     
00263     /***** Generator Mounting API *****/
00264     
00273     IUniConfGen *mount(WvStringParm moniker, bool refresh = true) const;
00274     
00285     IUniConfGen *mountgen(IUniConfGen *gen, bool refresh = true) const;
00286     
00288     void unmount(IUniConfGen *gen, bool commit) const;
00289     
00291     bool ismountpoint() const;
00292     
00294     bool isok() const;
00295     
00306     IUniConfGen *whichmount(UniConfKey *mountpoint = NULL) const;
00307 
00308     
00309     /***** Notification API *****/
00310 
00319     void add_callback(void *cookie, const UniConfCallback &callback,
00320                       bool recurse = true) const;
00321     
00325     void del_callback(void *cookie, bool recurse = true) const;
00326 
00331     void add_setbool(bool *flag, bool recurse = true) const;
00332 
00336     void del_setbool(bool *flag, bool recurse = true) const;
00337     
00346     void hold_delta();
00347 
00356     void unhold_delta();
00357     
00362     void clear_delta();
00363 
00368     void flush_delta();
00369     
00370     
00371     /***** Key Enumeration API *****/
00372     
00377     void dump(WvStream &stream, bool everything = false) const;
00378     
00385     bool haschildren() const;
00386     
00387     /*** Iterators (see comments in class declaration) ***/
00388 
00389     // internal base class for all of the key iterators
00390     class IterBase;
00391     // iterates over direct children
00392     class Iter;
00393     // iterates over all descendents in preorder traversal
00394     class RecursiveIter;
00395     // iterates over children matching a wildcard
00396     class XIter;
00397 
00398     // internal base class for sorted key iterators
00399     class SortedIterBase;
00400     // sorted variant of Iter
00401     class SortedIter;
00402     // sorted variant of RecursiveIter
00403     class SortedRecursiveIter;
00404     // sorted variant of XIter
00405     class SortedXIter;
00406 
00407     // lists of iterators
00408     DeclareWvList(Iter);
00409 };
00410 
00411 
00415 class UniConf::IterBase
00416 {
00417 protected:
00418     UniConf top;
00419     UniConf current;
00420 
00421     IterBase(const UniConf &_top)
00422         : top(_top)
00423         { }
00424 
00425 public:
00426     const UniConf *ptr() const
00427         { return &current; }
00428     WvIterStuff(const UniConf);
00429 };
00430 
00431 
00435 class UniConf::Iter : public UniConf::IterBase
00436 {
00437     UniConfGen::Iter *it;
00438     
00439 public:
00441     Iter(const UniConf &_top);
00442 
00443     ~Iter()
00444         { delete it; }
00445 
00446     void rewind()
00447         { it->rewind(); }
00448     bool next()
00449     {
00450         if (!it->next())
00451             return false;
00452         current = top[it->key()];
00453         return true;
00454     }
00455     
00456     // FIXME: this is a speed optimization only.  Don't use this unless
00457     // you're apenwarr.  It will change.
00458     WvString _value() const
00459         { return it->value(); }
00460 };
00461 
00462 
00466 class UniConf::RecursiveIter : public UniConf::IterBase
00467 {
00468     UniConfGen::Iter *it;
00469 
00470 public:
00472     RecursiveIter(const UniConf &_top);
00473 
00474     ~RecursiveIter()
00475         { delete it; }
00476 
00477     void rewind()
00478         { it->rewind(); }
00479     bool next()
00480     {
00481         if (!it->next())
00482             return false;
00483         current = top[it->key()];
00484         return true;
00485     }   
00486 
00487     // FIXME: this is a speed optimization only.  Don't use this unless
00488     // you're apenwarr.  It will change.
00489     WvString _value() const
00490         { return it->value(); }
00491 };
00492 
00493 
00511 class UniConf::XIter : public UniConf::IterBase
00512 {
00513     UniConfKey pathead;
00514     UniConfKey pattail;
00515     UniConf::XIter *subit;
00516     UniConf::Iter *it; 
00517     UniConf::RecursiveIter *recit; 
00518     bool ready; 
00520 public:
00522     XIter(const UniConf &_top, const UniConfKey &pattern);
00523     ~XIter();
00524 
00525     void rewind();
00526     bool next();
00527     
00528 private:
00529     void cleanup();
00530     bool qnext();
00531     void enter(const UniConf &child);
00532 };
00533 
00534 
00543 class UniConf::SortedIterBase : public UniConf::IterBase
00544 {
00545 public:
00546     typedef int (*Comparator)(const UniConf &a, const UniConf &b);
00547 
00549     static int defcomparator(const UniConf &a, const UniConf &b);
00550 
00551     SortedIterBase(const UniConf &_top, Comparator comparator = defcomparator);
00552     ~SortedIterBase();
00553 
00554     bool next();
00555 
00556 private:
00557     Comparator xcomparator;
00558     int index;
00559     int count;
00560     
00561     void _purge();
00562     void _rewind();
00563     
00564 protected:
00565     std::vector<UniConf> xkeys;
00566     
00567     template<class Iter>
00568     void populate(Iter &i)
00569     {
00570         _purge();
00571         for (i.rewind(); i.next(); )
00572             xkeys.push_back(*i);
00573         _rewind();
00574     }
00575 };
00576 
00577 
00581 class UniConf::SortedIter : public UniConf::SortedIterBase
00582 {
00583     UniConf::Iter i;
00584 
00585 public:
00586     SortedIter(const UniConf &_top, Comparator comparator = defcomparator)
00587         : SortedIterBase(_top, comparator), i(_top)
00588         { }
00589 
00590     void rewind()
00591         { populate(i); }
00592 };
00593 
00594 
00598 class UniConf::SortedRecursiveIter : public UniConf::SortedIterBase
00599 {
00600     UniConf::RecursiveIter i;
00601 
00602 public:
00603     SortedRecursiveIter(const UniConf &_top,
00604                         Comparator comparator = defcomparator)
00605         : SortedIterBase(_top, comparator), i(_top)
00606         { }
00607 
00608     void rewind()
00609         { populate(i); }
00610 };
00611 
00612 
00616 class UniConf::SortedXIter : public UniConf::SortedIterBase
00617 {
00618     UniConf::XIter i;
00619 
00620 public:
00621     SortedXIter(const UniConf &_top, const UniConfKey &pattern,
00622                 Comparator comparator = defcomparator) 
00623         : SortedIterBase(_top, comparator), i(_top, pattern) 
00624         { }
00625 
00626     void rewind()
00627         { populate(i); }
00628 };
00629 
00630 #endif // __UNICONF_H