00001
00002
00003
00004
00005
00006
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
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
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
00209
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