WvStreams
|
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, IObject *_obj) 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 if (_obj) _obj->addRef(); 00052 IUniConfGen *gen = wvcreate<IUniConfGen>(i(), _obj); 00053 if (gen) 00054 l->append(gen, true); 00055 } 00056 if (_obj) _obj->release(); 00057 00058 return new UniListGen(l); 00059 } 00060 00061 static WvMoniker<IUniConfGen> reg("list", creator); 00062 00063 UniListGen::UniListGen(UniConfGenList *_l) : l(_l) 00064 { 00065 UniConfGenList::Iter i(*l); 00066 for (i.rewind(); i.next(); ) 00067 i->add_callback(this, wv::bind(&UniListGen::gencallback, this, _1, _2)); 00068 } 00069 00070 00071 UniListGen::~UniListGen() 00072 { 00073 UniConfGenList::Iter i(*l); 00074 for (i.rewind(); i.next(); ) 00075 i->del_callback(this); 00076 delete l; 00077 } 00078 00079 00080 void UniListGen::commit() 00081 { 00082 UniConfGenList::Iter i(*l); 00083 for (i.rewind(); i.next();) 00084 i->commit(); 00085 } 00086 00087 00088 bool UniListGen::refresh() 00089 { 00090 bool result = true; 00091 00092 UniConfGenList::Iter i(*l); 00093 for (i.rewind(); i.next();) 00094 result = i->refresh() && result; 00095 return result; 00096 } 00097 00098 00099 WvString UniListGen::get(const UniConfKey &key) 00100 { 00101 UniConfGenList::Iter i(*l); 00102 for (i.rewind(); i.next(); ) 00103 if (i->exists(key)) 00104 return i->get(key); 00105 return WvString::null; 00106 } 00107 00108 00109 // we try to set *all* our generators. Read-only ones will ignore us. 00110 void UniListGen::set(const UniConfKey &key, WvStringParm value) 00111 { 00112 UniConfGenList::Iter i(*l); 00113 for (i.rewind(); i.next(); ) 00114 i->set(key, value); 00115 } 00116 00117 00118 void UniListGen::setv(const UniConfPairList &pairs) 00119 { 00120 UniConfGenList::Iter i(*l); 00121 for (i.rewind(); i.next(); ) 00122 i->setv(pairs); 00123 } 00124 00125 00126 bool UniListGen::exists(const UniConfKey &key) 00127 { 00128 UniConfGenList::Iter i(*l); 00129 for (i.rewind(); i.next();) 00130 { 00131 if (i->exists(key)) 00132 return true; 00133 } 00134 return false; 00135 } 00136 00137 00138 bool UniListGen::haschildren(const UniConfKey &key) 00139 { 00140 UniConfGenList::Iter i(*l); 00141 for (i.rewind(); i.next();) 00142 { 00143 if (i->haschildren(key)) 00144 return true; 00145 } 00146 return false; 00147 } 00148 00149 00150 bool UniListGen::isok() 00151 { 00152 UniConfGenList::Iter i(*l); 00153 for (i.rewind(); i.next();) 00154 { 00155 if (!i->isok()) 00156 return false; 00157 } 00158 return true; 00159 } 00160 00161 00162 void UniListGen::gencallback(const UniConfKey &key, WvStringParm value) 00163 { 00164 delta(key, get(key)); 00165 } 00166 00167 00168 UniConfGen::Iter *UniListGen::iterator(const UniConfKey &key) 00169 { 00170 return new IterIter(this, key); 00171 } 00172 00173 00174 /***** UniListGen::IterIter *****/ 00175 00176 UniListGen::IterIter::IterIter(UniListGen *gen, const UniConfKey &key) 00177 { 00178 UniConfGenList::Iter geniter(*gen->l); 00179 for (geniter.rewind(); geniter.next(); ) 00180 { 00181 Iter *it = geniter->iterator(key); 00182 if (it) 00183 l.append(it, true); 00184 } 00185 00186 i = new IterList::Iter(l); 00187 } 00188 00189 00190 void UniListGen::IterIter::rewind() 00191 { 00192 for ((*i).rewind(); (*i).next(); ) 00193 (*i)->rewind(); 00194 00195 i->rewind(); 00196 i->next(); 00197 00198 d.zap(); 00199 } 00200 00201 00202 bool UniListGen::IterIter::next() 00203 { 00204 if (l.isempty()) 00205 return false; 00206 00207 if ((*i)->next()) 00208 { 00209 // When iterating, make sure each key value is only returned once 00210 // (from the top item in the list) 00211 if (!d[(*i)->key()]) 00212 { 00213 d.add(new UniConfKey((*i)->key()), true); 00214 return true; 00215 } 00216 else 00217 return next(); 00218 } 00219 00220 if (!i->next()) 00221 return false; 00222 00223 return next(); 00224 } 00225 00226 00227 UniConfKey UniListGen::IterIter::key() const 00228 { 00229 return (*i)->key(); 00230 } 00231 00232 00233 WvString UniListGen::IterIter::value() const 00234 { 00235 return (*i)->value(); 00236 } 00237 00238