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
189
190
192{
193 return UniConfGen::refresh();
194}
The basic interface which is included by all other XPLC interfaces and objects.
An abstract data container that backs a UniConf tree.
::UniListIter ListIter
An iterator over a constant list of keys (see below)
An abstract iterator over keys and values in a generator.
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 bool refresh()
Refreshes information about a key recursively.
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
UniConfKey pop(int n=1)
Returns the path formed by the first n segments of this path and removes them from the key.
int numsegments() const
Returns the number of segments in this path.
bool isempty() const
Returns true if this path has zero segments (also known as root).
UniConfKey last(int n=1) const
Returns the path formed by the n last segments of this path.
UniConfKey fullkey(const Sub *ancestor=NULL) const
Returns full path of this node relative to an ancestor.
Sub * find(const UniConfKey &key) const
Finds the sub-node with the specified key.
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).
Sub * findchild(const UniConfKey &key) const
Finds the direct child node with the specified key.
A plain UniConfTree that holds keys and values.
void setvalue(WvStringParm value)
Sets the value field.
const WvString & value() const
Returns the value field.
bool haschildren() const
Returns true if the node has children.
An iterator that iterates through a constant list of keys.
void add(const UniConfKey &k, WvStringParm v=WvString::null)
Add a key/value pair to the list that gets returned by this iterator.
A UniConf generator that stores keys in memory.
virtual bool refresh()
Refreshes information about a key recursively.
virtual void commit()
Commits any changes.
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
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
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
bool isnull() const
returns true if this string is null
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
WvString get(WvStringParm s)
Get a shared string corresponding to 's'.
WvString is an implementation of a simple and efficient printable-string class.