00001
00002
00003
00004
00005
00006
00007 #include "unitempgen.h"
00008 #include "wvmoniker.h"
00009 #include "wvlog.h"
00010 #include "wvstringcache.h"
00011 #include "unilistiter.h"
00012
00013 static IUniConfGen *creator(WvStringParm)
00014 {
00015 return new UniTempGen();
00016 }
00017
00018 static WvMoniker<IUniConfGen> reg("temp", creator);
00019
00020
00021
00022
00023 UniTempGen::UniTempGen()
00024 : root(NULL)
00025 {
00026 }
00027
00028
00029 UniTempGen::~UniTempGen()
00030 {
00031 delete root;
00032 }
00033
00034
00035 WvString UniTempGen::get(const UniConfKey &key)
00036 {
00037 if (root)
00038 {
00039
00040 if (!key.isempty() && key.last().isempty())
00041 return WvString::null;
00042 UniConfValueTree *node = root->find(key);
00043 if (node)
00044 return node->value();
00045 }
00046 return WvString::null;
00047 }
00048
00049 void UniTempGen::notify_deleted(const UniConfValueTree *node, void *)
00050 {
00051 delta(node->fullkey(), WvString::null);
00052 }
00053
00054 void UniTempGen::set(const UniConfKey &_key, WvStringParm _value)
00055 {
00056 WvString value(scache.get(_value));
00057
00058 hold_delta();
00059 UniConfKey key = _key;
00060
00061 bool trailing_slash = false;
00062 if (!key.isempty())
00063 {
00064
00065 UniConfKey last = key;
00066 key = last.pop(last.numsegments() - 1);
00067 if (last.isempty())
00068 trailing_slash = true;
00069 else
00070 key = _key;
00071 }
00072
00073 if (value.isnull())
00074 {
00075
00076 if (root)
00077 {
00078 UniConfValueTree *node = root->find(key);
00079 if (node)
00080 {
00081 hold_delta();
00082
00083 node->visit(UniConfValueTree::Visitor(this,
00084 &UniTempGen::notify_deleted), NULL, false, true);
00085 delete node;
00086 if (node == root)
00087 root = NULL;
00088 dirty = true;
00089 unhold_delta();
00090 }
00091 }
00092 }
00093 else if (!trailing_slash)
00094 {
00095 UniConfValueTree *node = root;
00096 UniConfValueTree *prev = NULL;
00097 UniConfKey prevkey;
00098
00099 UniConfKey::Iter it(key);
00100 it.rewind();
00101 for (;;)
00102 {
00103 bool more = it.next();
00104
00105 if (!node)
00106 {
00107
00108
00109 node = new UniConfValueTree(prev, prevkey,
00110 more ? WvString::empty : value);
00111 dirty = true;
00112 if (!prev)
00113 root = node;
00114 if (more)
00115 delta(node->fullkey(), WvString::empty);
00116 else
00117 {
00118 delta(node->fullkey(), value);
00119 break;
00120 }
00121 }
00122 else if (!more)
00123 {
00124
00125
00126
00127 if (value != node->value())
00128 {
00129 node->setvalue(value);
00130 dirty = true;
00131 delta(node->fullkey(), value);
00132 }
00133 break;
00134 }
00135 prevkey = *it;
00136 prev = node;
00137 node = prev->findchild(prevkey);
00138 }
00139 assert(node);
00140 }
00141
00142 unhold_delta();
00143 }
00144
00145
00146 void UniTempGen::setv(const UniConfPairList &pairs)
00147 {
00148 setv_naive(pairs);
00149 }
00150
00151
00152 bool UniTempGen::haschildren(const UniConfKey &key)
00153 {
00154 if (root)
00155 {
00156 UniConfValueTree *node = root->find(key);
00157 return node != NULL && node->haschildren();
00158 }
00159 return false;
00160 }
00161
00162
00163 UniConfGen::Iter *UniTempGen::iterator(const UniConfKey &key)
00164 {
00165 if (root)
00166 {
00167 UniConfValueTree *node = root->find(key);
00168 if (node)
00169 {
00170 ListIter *it = new ListIter(this);
00171 UniConfValueTree::Iter i(*node);
00172 for (i.rewind(); i.next(); )
00173 it->add(i->key(), i->value());
00174 return it;
00175 }
00176 }
00177 return NULL;
00178 }
00179
00180
00181 void UniTempGen::commit()
00182 {
00183 UniConfGen::commit();
00184 }
00185
00186
00187 bool UniTempGen::refresh()
00188 {
00189 return UniConfGen::refresh();
00190 }