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, 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
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
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
00210
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