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 
00016 #ifdef  __cplusplus
00017 
00018 #include "uniconfkey.h"
00019 #include "uniconfgen.h"
00020 #include "wvcallback.h"
00021 #include "wvvector.h"
00022 
00023 class WvStream;
00024 class UniConf;
00025 class UniConfRoot;
00026 
00034 typedef WvCallback<void, const UniConf &, const UniConfKey &> UniConfCallback;
00035 
00036 #ifdef SWIG_NO_OVERLOAD
00037 // FIXME: This directive doesn't work.  Why not?
00038 %ignore UniConf::u(const UniConfKey &key);
00039 #endif
00040 
00062 class UniConf
00063 {
00064     friend class UniConfRoot;
00065     
00066 protected:
00067     UniConfRoot *xroot;
00068     UniConfKey xfullkey;
00069 
00076     UniConf(UniConfRoot *root, const UniConfKey &fullkey = UniConfKey::EMPTY);
00077     
00078 public:
00080     UniConf();
00081     
00083     UniConf(const UniConf &other);
00084     
00086     virtual ~UniConf();
00087 
00088     
00089     /***** Handle Manipulation API *****/
00090 
00092     UniConf root() const
00093         { return UniConf(xroot, UniConfKey::EMPTY); }
00094 
00096     UniConf parent() const
00097         { return UniConf(xroot, xfullkey.removelast()); }
00098     
00103     UniConfRoot *rootobj() const
00104         { return xroot; }
00105 
00107     bool isnull() const
00108         { return xroot == NULL; }
00109 
00111     UniConfKey fullkey() const
00112         { return xfullkey; }
00113     
00116 #ifdef SWIG_NO_OVERLOAD
00117     %name(fullkey_from_key)
00118 #endif
00119     UniConfKey fullkey(const UniConfKey &k) const;
00120     
00122 #ifdef SWIG_NO_OVERLOAD
00123     %name(fullkey_from_handle)
00124 #endif
00125 
00126     UniConfKey fullkey(const UniConf &cfg) const
00127         { return fullkey(cfg.fullkey()); }
00128 
00130     UniConfKey key() const
00131         { return xfullkey.last(); }
00132 
00133 #ifndef SWIG
00134 
00139     const UniConf operator[] (const UniConfKey &key) const
00140         { return UniConf(xroot, UniConfKey(xfullkey, key)); }
00141 #endif  // SWIG
00142 
00147 #ifdef SWIG_NO_OVERLOAD
00148     %name(u_should_be_ignored)
00149 #endif
00150     const UniConf u(const UniConfKey &key) const
00151         { return (*this)[key]; }
00152 
00154     UniConf &operator= (const UniConf &other)
00155     {
00156         xroot = other.xroot;
00157         xfullkey = other.xfullkey;
00158         return *this;
00159     }
00160 
00161     
00162     /***** Key Retrieval API *****/
00163     
00165     void prefetch(bool recursive) const;
00166     
00171     WvString getme(WvStringParm defvalue = WvString::null) const;
00172 
00174     WvString operator* () const
00175         { return getme(); }
00176 
00178     WvStringStar operator -> () const
00179         { return getme(); }
00180     
00182     WvString xget(WvStringParm key,
00183                   WvStringParm defvalue = WvString::null) const
00184         { return (*this)[key].getme(defvalue); }
00185 
00193     int getmeint(int defvalue = 0) const;
00194 
00196     int xgetint(WvStringParm key, int defvalue = 0) const
00197         { return (*this)[key].getmeint(defvalue); }
00198 
00205     bool exists() const;
00206 
00207 
00208     /***** Key Storage API *****/
00209 
00214     void setme(WvStringParm value) const;
00215 
00219     void setme(WVSTRING_FORMAT_DECL) const
00220         { return setme(WvString(WVSTRING_FORMAT_CALL)); }
00221 
00223     void xset(WvStringParm key, WvStringParm value) const
00224         { (*this)[key].setme(value); }
00225 
00229     void setmeint(int value) const;
00230 
00232     void xsetint(WvStringParm key, int value) const
00233         { (*this)[key].setmeint(value); }
00234 
00235 
00236     /***** Key Handling API *****/
00237 
00251     void move(const UniConf &dst) const;
00252 
00256     void remove() const
00257         { setme(WvString::null); }
00258 
00268     void copy(const UniConf &dst, bool force) const;
00269 
00270 
00271     
00272     /***** Key Persistence API *****/
00273 
00279     bool refresh() const;
00280     
00284     void commit() const;
00285 
00286     
00287     /***** Generator Mounting API *****/
00288     
00297     IUniConfGen *mount(WvStringParm moniker, bool refresh = true) const;
00298     
00309     IUniConfGen *mountgen(IUniConfGen *gen, bool refresh = true) const;
00310     
00312     void unmount(IUniConfGen *gen, bool commit) const;
00313     
00315     bool ismountpoint() const;
00316     
00318     bool isok() const;
00319     
00330     IUniConfGen *whichmount(UniConfKey *mountpoint = NULL) const;
00331 
00332     
00333     /***** Notification API *****/
00334 
00343     void add_callback(void *cookie, const UniConfCallback &callback,
00344                       bool recurse = true) const;
00345     
00349     void del_callback(void *cookie, bool recurse = true) const;
00350 
00355     void add_setbool(bool *flag, bool recurse = true) const;
00356 
00360     void del_setbool(bool *flag, bool recurse = true) const;
00361     
00370     void hold_delta();
00371 
00380     void unhold_delta();
00381     
00386     void clear_delta();
00387 
00392     void flush_delta();
00393     
00394     
00395     /***** Key Enumeration API *****/
00396     
00401     void dump(WvStream &stream, bool everything = false) const;
00402     
00409     bool haschildren() const;
00410     
00411     /*** Iterators (see comments in class declaration) ***/
00412 
00413     // internal base class for all of the key iterators
00414     class IterBase;
00415     // iterates over direct children
00416     class Iter;
00417     // iterates over all descendents in preorder traversal
00418     class RecursiveIter;
00419     // iterates over children matching a wildcard
00420     class XIter;
00421 
00422     // internal base class for sorted key iterators
00423     class SortedIterBase;
00424     // sorted variant of Iter
00425     class SortedIter;
00426     // sorted variant of RecursiveIter
00427     class SortedRecursiveIter;
00428     // sorted variant of XIter
00429     class SortedXIter;
00430 
00431 #ifndef SWIG
00432     // lists of iterators
00433     DeclareWvList(Iter);
00434 #endif  // SWIG
00435 };
00436 
00437 
00438 #ifndef SWIG
00439 
00443 class UniConf::IterBase
00444 {
00445 protected:
00446     UniConf top;
00447     UniConf current;
00448 
00449     IterBase(const UniConf &_top)
00450         : top(_top)
00451         { }
00452 
00453 public:
00454     const UniConf *ptr() const
00455         { return &current; }
00456     WvIterStuff(const UniConf);
00457 };
00458 
00459 
00463 class UniConf::Iter : public UniConf::IterBase
00464 {
00465     UniConfGen::Iter *it;
00466     
00467 public:
00469     Iter(const UniConf &_top);
00470 
00471     ~Iter()
00472         { delete it; }
00473 
00474     void rewind()
00475         { it->rewind(); }
00476     bool next()
00477     {
00478         if (!it->next())
00479             return false;
00480         current = top[it->key()];
00481         return true;
00482     }
00483     
00484     // FIXME: this is a speed optimization only.  Don't use this unless
00485     // you're apenwarr.  It will change.
00486     WvString _value() const
00487         { return it->value(); }
00488 };
00489 
00490 
00494 class UniConf::RecursiveIter : public UniConf::IterBase
00495 {
00496     UniConfGen::Iter *it;
00497 
00498 public:
00500     RecursiveIter(const UniConf &_top);
00501 
00502     ~RecursiveIter()
00503         { delete it; }
00504 
00505     void rewind()
00506         { it->rewind(); }
00507     bool next()
00508     {
00509         if (!it->next())
00510             return false;
00511         current = top[it->key()];
00512         return true;
00513     }   
00514 
00515     // FIXME: this is a speed optimization only.  Don't use this unless
00516     // you're apenwarr.  It will change.
00517     WvString _value() const
00518         { return it->value(); }
00519 };
00520 
00521 
00539 class UniConf::XIter : public UniConf::IterBase
00540 {
00541     UniConfKey pathead;
00542     UniConfKey pattail;
00543     UniConf::XIter *subit;
00544     UniConf::Iter *it; 
00545     UniConf::RecursiveIter *recit; 
00546     bool ready; 
00548 public:
00550     XIter(const UniConf &_top, const UniConfKey &pattern);
00551     ~XIter();
00552 
00553     void rewind();
00554     bool next();
00555     
00556 private:
00557     void cleanup();
00558     bool qnext();
00559     void enter(const UniConf &child);
00560 };
00561 
00562 
00571 class UniConf::SortedIterBase : public UniConf::IterBase
00572 {
00573 public:
00574     typedef int (*Comparator)(const UniConf &a, const UniConf &b);
00575 
00577     static int defcomparator(const UniConf &a, const UniConf &b);
00578 
00579     SortedIterBase(const UniConf &_top, Comparator comparator = defcomparator);
00580     ~SortedIterBase();
00581 
00582     bool next();
00583 
00584 private:
00585     Comparator xcomparator;
00586     int index;
00587     int count;
00588     
00589     void _purge();
00590     void _rewind();
00591     
00592     static int wrapcomparator(const UniConf *a, const UniConf *b);
00593     static Comparator innercomparator;
00594 
00595 protected:
00596     typedef WvVector<UniConf> Vector;
00597     Vector xkeys;
00598     
00599     template<class Iter>
00600     void populate(Iter &i)
00601     {
00602         _purge();
00603         for (i.rewind(); i.next(); )
00604             xkeys.append(new UniConf(*i), true);
00605         _rewind();
00606     }
00607 };
00608 
00609 
00613 class UniConf::SortedIter : public UniConf::SortedIterBase
00614 {
00615     UniConf::Iter i;
00616 
00617 public:
00618     SortedIter(const UniConf &_top, Comparator comparator = defcomparator)
00619         : SortedIterBase(_top, comparator), i(_top)
00620         { }
00621 
00622     void rewind()
00623         { populate(i); }
00624 };
00625 
00626 
00630 class UniConf::SortedRecursiveIter : public UniConf::SortedIterBase
00631 {
00632     UniConf::RecursiveIter i;
00633 
00634 public:
00635     SortedRecursiveIter(const UniConf &_top,
00636                         Comparator comparator = defcomparator)
00637         : SortedIterBase(_top, comparator), i(_top)
00638         { }
00639 
00640     void rewind()
00641         { populate(i); }
00642 };
00643 
00644 
00648 class UniConf::SortedXIter : public UniConf::SortedIterBase
00649 {
00650     UniConf::XIter i;
00651 
00652 public:
00653     SortedXIter(const UniConf &_top, const UniConfKey &pattern,
00654                 Comparator comparator = defcomparator) 
00655         : SortedIterBase(_top, comparator), i(_top, pattern) 
00656         { }
00657 
00658     void rewind()
00659         { populate(i); }
00660 };
00661 
00662 #endif  // SWIG
00663 
00664 #endif /* __cplusplus */
00665 
00666 
00671 #ifdef ASHLEY
00672 
00673 #ifdef __cplusplus
00674 extern "C" {
00675 #endif  // __cplusplus
00676 
00677 
00679 typedef void *uniconf_t;
00680 
00681 
00682 /* Initialize and destroy UniConf. */
00683 uniconf_t uniconf_init(const char* _moniker);
00684 
00685 
00686 void uniconf_free(uniconf_t _uniconf);
00687 
00688 
00689 /* The string returned has been allocated with malloc() and should
00690  * thus be free()d. */
00691 const char* uniconf_get(uniconf_t _uniconf, const char* _key);
00692 
00693 
00694 void uniconf_set(uniconf_t _uniconf,
00695                  const char* _key, const char* _value);
00696 
00697 
00698 #ifdef  __cplusplus
00699 }
00700 #endif  // __cplusplus
00701 #endif
00702 
00703 #endif // __UNICONF_H

Generated on Thu May 25 21:51:02 2006 for WvStreams by  doxygen 1.4.6