unilistgen.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2002 Net Integration Technologies, Inc.
00004  *
00005  * UniListGen is a UniConf generator to allow multiple generators to be
00006  * stacked in a priority sequence for get/set/etc.
00007  * 
00008  */
00009 #include "unilistgen.h"
00010 #include "wvmoniker.h"
00011 #include "wvtclstring.h"
00012 #include "wvstringlist.h"
00013 #include "wvlinkerhack.h"
00014 
00015 WV_LINK(UniListGen);
00016 
00017 
00018 
00019 class UniListGen::IterIter : public UniConfGen::Iter
00020 {
00021 protected:
00022     DeclareWvScatterTable(UniConfKey);
00023     DeclareWvList2(IterList, UniConfGen::Iter);
00024     
00025     IterList l;
00026     IterList::Iter *i;
00027     UniConfKeyTable d;
00028     
00029 public:
00030     IterIter(UniListGen *gen, const UniConfKey &key);
00031     virtual ~IterIter() { delete i; }
00032     
00033     virtual void rewind();
00034     virtual bool next();
00035     virtual UniConfKey key() const;
00036     virtual WvString value() const;
00037 };
00038 
00039 
00040 
00041 static IUniConfGen *creator(WvStringParm s)
00042 {
00043     UniConfGenList *l = new UniConfGenList();
00044 
00045     WvStringList gens;
00046     wvtcl_decode(gens, s);
00047     WvStringList::Iter i(gens);
00048 
00049     for (i.rewind(); i.next();)
00050     {
00051         IUniConfGen *gen = wvcreate<IUniConfGen>(i());
00052         if (gen)
00053             l->append(gen, true);
00054     }
00055 
00056     return new UniListGen(l);
00057 }
00058  
00059 static WvMoniker<IUniConfGen> reg("list", creator);
00060 
00061 UniListGen::UniListGen(UniConfGenList *_l) : l(_l)
00062 {
00063     UniConfGenList::Iter i(*l);
00064     for (i.rewind(); i.next(); )
00065         i->add_callback(this, 
00066                 UniConfGenCallback(this, &UniListGen::gencallback));
00067 }
00068 
00069 
00070 UniListGen::~UniListGen()
00071 {
00072     UniConfGenList::Iter i(*l);
00073     for (i.rewind(); i.next(); )
00074         i->del_callback(this);
00075     delete l;
00076 }
00077 
00078 
00079 void UniListGen::commit()
00080 {
00081     UniConfGenList::Iter i(*l);
00082     for (i.rewind(); i.next();)
00083         i->commit();
00084 }
00085 
00086 
00087 bool UniListGen::refresh()
00088 {
00089     bool result = true;
00090 
00091     UniConfGenList::Iter i(*l);
00092     for (i.rewind(); i.next();)
00093         result = i->refresh() && result;
00094     return result;
00095 }
00096 
00097 
00098 WvString UniListGen::get(const UniConfKey &key)
00099 {
00100     UniConfGenList::Iter i(*l);
00101     for (i.rewind(); i.next(); )
00102         if (i->exists(key))
00103             return i->get(key);
00104     return WvString::null;
00105 }
00106 
00107 
00108 // we try to set *all* our generators.  Read-only ones will ignore us.
00109 void UniListGen::set(const UniConfKey &key, WvStringParm value)
00110 {
00111     UniConfGenList::Iter i(*l);
00112     for (i.rewind(); i.next(); )
00113         i->set(key, value);
00114 }
00115 
00116 
00117 void UniListGen::setv(const UniConfPairList &pairs)
00118 {
00119     UniConfGenList::Iter i(*l);
00120     for (i.rewind(); i.next(); )
00121         i->setv(pairs);
00122 }
00123 
00124 
00125 bool UniListGen::exists(const UniConfKey &key)
00126 {
00127     UniConfGenList::Iter i(*l);
00128     for (i.rewind(); i.next();)
00129     {
00130         if (i->exists(key))
00131             return true;
00132     }
00133     return false;
00134 }
00135 
00136 
00137 bool UniListGen::haschildren(const UniConfKey &key)
00138 {
00139     UniConfGenList::Iter i(*l);
00140     for (i.rewind(); i.next();)
00141     {
00142         if (i->haschildren(key))
00143             return true;
00144     }
00145     return false;
00146 }
00147 
00148 
00149 bool UniListGen::isok()
00150 {
00151     UniConfGenList::Iter i(*l);
00152     for (i.rewind(); i.next();)
00153     {
00154         if (!i->isok())
00155             return false;
00156     }
00157     return true;
00158 }
00159 
00160 
00161 void UniListGen::gencallback(const UniConfKey &key, WvStringParm value)
00162 {
00163     delta(key, get(key));
00164 }
00165 
00166 
00167 UniConfGen::Iter *UniListGen::iterator(const UniConfKey &key)
00168 {
00169     return new IterIter(this, key);
00170 }
00171 
00172 
00173 /***** UniListGen::IterIter *****/
00174 
00175 UniListGen::IterIter::IterIter(UniListGen *gen, const UniConfKey &key)
00176 {
00177     UniConfGenList::Iter geniter(*gen->l);
00178     for (geniter.rewind(); geniter.next(); )
00179     {
00180         Iter *it = geniter->iterator(key);
00181         if (it)
00182             l.append(it, true);
00183     }
00184 
00185     i = new IterList::Iter(l);
00186 }
00187 
00188 
00189 void UniListGen::IterIter::rewind()
00190 {
00191     for ((*i).rewind(); (*i).next(); )
00192         (*i)->rewind();
00193 
00194     i->rewind();
00195     i->next();
00196 
00197     d.zap();
00198 }
00199 
00200 
00201 bool UniListGen::IterIter::next()
00202 {
00203     if (l.isempty())
00204         return false;
00205 
00206     if ((*i)->next())
00207     {
00208         // When iterating, make sure each key value is only returned once
00209         // (from the top item in the list)
00210         if (!d[(*i)->key()])
00211         {
00212             d.add(new UniConfKey((*i)->key()), true);
00213             return true;
00214         }
00215         else
00216             return next();
00217     }
00218 
00219     if (!i->next())
00220         return false;
00221 
00222     return next();
00223 }
00224 
00225 
00226 UniConfKey UniListGen::IterIter::key() const
00227 {
00228     return (*i)->key();
00229 }
00230 
00231 
00232 WvString UniListGen::IterIter::value() const
00233 {
00234     return (*i)->value();
00235 }
00236 
00237 

Generated on Wed Jul 12 17:53:19 2006 for WvStreams by  doxygen 1.4.7