WvStreams
unitempgen.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2002-2005 Net Integration Technologies, Inc.
4 *
5 * A UniConf generator that stores keys in memory.
6 */
7#include "unitempgen.h"
8#include "wvmoniker.h"
9#include "wvlog.h"
10#include "wvstringcache.h"
11#include "unilistiter.h"
12#include "wvlinkerhack.h"
13
14WV_LINK(UniTempGen);
15
16static IUniConfGen *creator(WvStringParm, IObject*)
17{
18 return new UniTempGen();
19}
20
21static WvMoniker<IUniConfGen> reg("temp", creator);
22
23
24/***** UniTempGen *****/
25
26UniTempGen::UniTempGen()
27 : root(NULL)
28{
29}
30
31
32UniTempGen::~UniTempGen()
33{
34 delete root;
35}
36
37
39{
40 if (root)
41 {
42 // Look for an empty section at the end.
43 if (!key.isempty() && key.last().isempty())
44 return WvString::null;
45 UniConfValueTree *node = root->find(key);
46 if (node)
47 return node->value();
48 }
49 return WvString::null;
50}
51
52void UniTempGen::notify_deleted(const UniConfValueTree *node, void *)
53{
54 delta(node->fullkey(), WvString::null);
55}
56
57void UniTempGen::set(const UniConfKey &_key, WvStringParm _value)
58{
59 WvString value(scache.get(_value));
60
61 hold_delta();
62 UniConfKey key = _key;
63 // FIXME: Use key.hastrailingslash(), it's shorter and easier and faster
64 bool trailing_slash = false;
65 if (!key.isempty())
66 {
67 // Look for an empty section at the end.
68 UniConfKey last = key;
69 key = last.pop(last.numsegments() - 1);
70 if (last.isempty())
71 trailing_slash = true;
72 else
73 key = _key;
74 }
75
76 if (value.isnull())
77 {
78 // remove a subtree
79 if (root)
80 {
81 UniConfValueTree *node = root->find(key);
82 if (node)
83 {
84 hold_delta();
85 // Issue notifications for every key that gets deleted.
86 node->visit(wv::bind(&UniTempGen::notify_deleted, this,
87 _1, _2),
88 NULL, false, true);
89 delete node;
90 if (node == root)
91 root = NULL;
92 dirty = true;
94 }
95 }
96 }
97 else if (!trailing_slash)
98 {
99 UniConfValueTree *node = root;
100 UniConfValueTree *prev = NULL;
101 UniConfKey prevkey;
102
103 UniConfKey::Iter it(key);
104 it.rewind();
105 for (;;)
106 {
107 bool more = it.next(); // not the last node in the key?
108
109 if (!node)
110 {
111 // we'll have to create the sub-node, since we couldn't
112 // find the most recent part of the key.
113 node = new UniConfValueTree(prev, prevkey,
114 more ? WvString::empty : value);
115 dirty = true;
116 if (!prev) // we just created the root
117 root = node;
118 if (more)
119 delta(node->fullkey(), WvString::empty); // AUTO-VIVIFIED
120 else
121 {
122 delta(node->fullkey(), value); // ADDED
123 break; // done!
124 }
125 }
126 else if (!more)
127 {
128 // don't have to create the most recent sub-node, but there
129 // are no more sub-nodes; that means we're changing the value
130 // of an existing node.
131 if (value != node->value())
132 {
133 node->setvalue(value);
134 dirty = true;
135 delta(node->fullkey(), value); // CHANGED
136 }
137 break;
138 }
139 prevkey = *it;
140 prev = node;
141 node = prev->findchild(prevkey);
142 }
143 assert(node);
144 }
145
146 unhold_delta();
147}
148
149
150void UniTempGen::setv(const UniConfPairList &pairs)
151{
152 setv_naive(pairs);
153}
154
155
157{
158 if (root)
159 {
160 UniConfValueTree *node = root->find(key);
161 return node != NULL && node->haschildren();
162 }
163 return false;
164}
165
166
168{
169 if (root)
170 {
171 UniConfValueTree *node = root->find(key);
172 if (node)
173 {
174 ListIter *it = new ListIter(this);
175 UniConfValueTree::Iter i(*node);
176 for (i.rewind(); i.next(); )
177 it->add(i->key(), i->value());
178 return it;
179 }
180 }
181 return NULL;
182}
183
184
186{
188}
189
190
192{
193 return UniConfGen::refresh();
194}
The basic interface which is included by all other XPLC interfaces and objects.
Definition: IObject.h:65
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:40
::UniListIter ListIter
An iterator over a constant list of keys (see below)
Definition: uniconfgen.h:163
An abstract iterator over keys and values in a generator.
Definition: uniconfgen.h:324
void hold_delta()
Pauses notifications until matched with a call to unhold_delta().
Definition: uniconfgen.cc:32
void unhold_delta()
Resumes notifications when each hold_delta() has been matched.
Definition: uniconfgen.cc:38
void delta(const UniConfKey &key, WvStringParm value)
Call this when a key's value or children have possibly changed.
Definition: uniconfgen.cc:77
virtual void commit()
Commits any changes.
Definition: uniconfgen.h:280
virtual bool refresh()
Refreshes information about a key recursively.
Definition: uniconfgen.h:281
An iterator over the segments of a key.
Definition: uniconfkey.h:464
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:39
UniConfKey pop(int n=1)
Returns the path formed by the first n segments of this path and removes them from the key.
Definition: uniconfkey.cc:183
int numsegments() const
Returns the number of segments in this path.
Definition: uniconfkey.h:287
bool isempty() const
Returns true if this path has zero segments (also known as root).
Definition: uniconfkey.h:264
UniConfKey last(int n=1) const
Returns the path formed by the n last segments of this path.
Definition: uniconfkey.h:324
UniConfKey fullkey(const Sub *ancestor=NULL) const
Returns full path of this node relative to an ancestor.
Definition: uniconftree.h:55
Sub * find(const UniConfKey &key) const
Finds the sub-node with the specified key.
Definition: uniconftree.h:62
void visit(const Visitor &visitor, void *userdata, bool preorder=true, bool postorder=false) const
Performs a traversal on this tree using the specified visitor function and traversal type(s).
Definition: uniconftree.h:108
Sub * findchild(const UniConfKey &key) const
Finds the direct child node with the specified key.
Definition: uniconftree.h:71
A plain UniConfTree that holds keys and values.
Definition: uniconftree.h:153
void setvalue(WvStringParm value)
Sets the value field.
Definition: uniconftree.h:167
const WvString & value() const
Returns the value field.
Definition: uniconftree.h:163
bool haschildren() const
Returns true if the node has children.
Definition: unihashtree.cc:114
An iterator that iterates through a constant list of keys.
Definition: unilistiter.h:28
void add(const UniConfKey &k, WvStringParm v=WvString::null)
Add a key/value pair to the list that gets returned by this iterator.
Definition: unilistiter.cc:16
A UniConf generator that stores keys in memory.
Definition: unitempgen.h:21
virtual bool refresh()
Refreshes information about a key recursively.
Definition: unitempgen.cc:191
virtual void commit()
Commits any changes.
Definition: unitempgen.cc:185
bool dirty
Definition: unitempgen.h:26
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
Definition: unitempgen.cc:167
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: unitempgen.cc:38
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: unitempgen.cc:57
UniConfValueTree * root
Definition: unitempgen.h:25
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
Definition: unitempgen.cc:150
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
Definition: unitempgen.cc:156
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition: wvstring.h:94
bool isnull() const
returns true if this string is null
Definition: wvstring.h:290
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:62
WvString get(WvStringParm s)
Get a shared string corresponding to 's'.
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:330