00001
00002
00003
00004
00005
00006
00007 #include "uniconfgen.h"
00008 #include "strutils.h"
00009
00010
00011 IUniConfGen::~IUniConfGen()
00012 {
00013 }
00014
00015 UUID_MAP_BEGIN(UniConfGen)
00016 UUID_MAP_ENTRY(IObject)
00017 UUID_MAP_ENTRY(IUniConfGen)
00018 UUID_MAP_END
00019
00020 UniConfGen::UniConfGen()
00021 {
00022 hold_nesting = 0;
00023 }
00024
00025
00026 UniConfGen::~UniConfGen()
00027 {
00028 assert(cblist.isempty());
00029 }
00030
00031
00032 void UniConfGen::hold_delta()
00033 {
00034 hold_nesting++;
00035 }
00036
00037
00038 void UniConfGen::unhold_delta()
00039 {
00040 assert(hold_nesting > 0);
00041 if (hold_nesting == 1)
00042 flush_delta();
00043 hold_nesting--;
00044 }
00045
00046
00047 void UniConfGen::clear_delta()
00048 {
00049 deltas.zap();
00050 }
00051
00052
00053 void UniConfGen::flush_delta()
00054 {
00055 UniConfPairList::Iter it(deltas);
00056 for (;;)
00057 {
00058 it.rewind();
00059 if (! it.next())
00060 break;
00061
00062 UniConfKey key((*it).key());
00063 WvString value((*it).value());
00064
00065 it.xunlink();
00066 dispatch_delta(key, value);
00067 }
00068 }
00069
00070
00071 void UniConfGen::dispatch_delta(const UniConfKey &key, WvStringParm value)
00072 {
00073 cblist(key, value);
00074 }
00075
00076
00077 void UniConfGen::delta(const UniConfKey &key, WvStringParm value)
00078 {
00079 if (hold_nesting == 0)
00080 {
00081
00082 dispatch_delta(key, value);
00083 }
00084 else
00085 {
00086 hold_delta();
00087 deltas.add(new UniConfPair(key, value), true);
00088 unhold_delta();
00089 }
00090 }
00091
00092
00093 void UniConfGen::setv_naive(const UniConfPairList &pairs)
00094 {
00095 UniConfPairList::Iter pair(pairs);
00096 for (pair.rewind(); pair.next(); )
00097 set(pair->key(), pair->value());
00098 }
00099
00100
00101 bool UniConfGen::haschildren(const UniConfKey &key)
00102 {
00103 bool children = false;
00104
00105 hold_delta();
00106
00107 Iter *it = iterator(key);
00108 if (it)
00109 {
00110 it->rewind();
00111 if (it->next()) children = true;
00112 delete it;
00113 }
00114
00115 unhold_delta();
00116 return children;
00117 }
00118
00119
00120 bool UniConfGen::exists(const UniConfKey &key)
00121 {
00122 return !get(key).isnull();
00123 }
00124
00125
00126 int UniConfGen::str2int(WvStringParm value, int defvalue) const
00127 {
00128
00129 const char *strs[] = {
00130 "true", "yes", "on", "enabled",
00131 "false", "no", "off", "disabled"
00132 };
00133 const size_t numtruestrs = 4;
00134
00135 if (!value.isnull())
00136 {
00137
00138 char *end;
00139 int num = strtol(value.cstr(), &end, 0);
00140 if (end != value.cstr())
00141 return num;
00142
00143
00144 for (size_t i = 0; i < sizeof(strs) / sizeof(const char*); ++i)
00145 if (strcasecmp(value, strs[i]) == 0)
00146 return i < numtruestrs;
00147 }
00148 return defvalue;
00149 }
00150
00151
00152 bool UniConfGen::isok()
00153 {
00154 return true;
00155 }
00156
00157
00158 void UniConfGen::add_callback(void *cookie,
00159 const UniConfGenCallback &callback)
00160 {
00161 cblist.add(callback, cookie);
00162 }
00163
00164
00165 void UniConfGen::del_callback(void *cookie)
00166 {
00167 cblist.del(cookie);
00168 }
00169
00170
00171
00172 class _UniConfGenRecursiveIter : public IUniConfGen::Iter
00173 {
00174 WvList<IUniConfGen::Iter> itlist;
00175 IUniConfGen *gen;
00176 UniConfKey top, current;
00177 bool sub_next;
00178
00179 public:
00180 _UniConfGenRecursiveIter(IUniConfGen *_gen, const UniConfKey &_top)
00181 : top(_top)
00182 {
00183 gen = _gen;
00184 sub_next = false;
00185 }
00186
00187 virtual ~_UniConfGenRecursiveIter() { }
00188
00189 virtual void rewind()
00190 {
00191 current = "";
00192 sub_next = false;
00193 itlist.zap();
00194
00195 Iter *subi = gen->iterator(top);
00196 if (subi)
00197 {
00198 subi->rewind();
00199 itlist.prepend(subi, true);
00200 }
00201 }
00202
00203 virtual bool next()
00204 {
00205
00206
00207 if (sub_next)
00208 {
00209 sub_next = false;
00210
00211 UniConfKey subkey(itlist.first()->key());
00212 UniConfKey newkey(current, subkey);
00213
00214 Iter *newsub = gen->iterator(UniConfKey(top, newkey));
00215 if (newsub)
00216 {
00217 current.append(subkey);
00218
00219 newsub->rewind();
00220 itlist.prepend(newsub, true);
00221 }
00222 }
00223
00224 WvList<IUniConfGen::Iter>::Iter i(itlist);
00225 for (i.rewind(); i.next(); )
00226 {
00227 if (i->next())
00228 {
00229
00230 sub_next = true;
00231 return true;
00232 }
00233
00234
00235 current = current.removelast();
00236
00237 i.xunlink();
00238 }
00239
00240
00241 return false;
00242 }
00243
00244 virtual UniConfKey key() const
00245 {
00246
00247 if (!itlist.isempty())
00248 return UniConfKey(current, itlist.first()->key());
00249 else
00250 return current;
00251 }
00252
00253 virtual WvString value() const
00254 {
00255 return gen->get(UniConfKey(top, key()));
00256 }
00257 };
00258
00259
00260 UniConfGen::Iter *UniConfGen::recursiveiterator(const UniConfKey &key)
00261 {
00262 return new _UniConfGenRecursiveIter(this, key);
00263 }
00264
00265