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 
14 WV_LINK(UniTempGen);
15 
16 static IUniConfGen *creator(WvStringParm, IObject*)
17 {
18  return new UniTempGen();
19 }
20 
21 static WvMoniker<IUniConfGen> reg("temp", creator);
22 
23 
24 /***** UniTempGen *****/
25 
26 UniTempGen::UniTempGen()
27  : root(NULL)
28 {
29 }
30 
31 
32 UniTempGen::~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 
52 void UniTempGen::notify_deleted(const UniConfValueTree *node, void *)
53 {
54  delta(node->fullkey(), WvString::null);
55 }
56 
57 void 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;
93  unhold_delta();
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 
150 void 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 }
UniTempGen::get
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: unitempgen.cc:38
UniTempGen::iterator
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
Definition: unitempgen.cc:167
UniConfKey::pop
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
UniTempGen::haschildren
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
Definition: unitempgen.cc:156
UniListIter
An iterator that iterates through a constant list of keys.
Definition: unilistiter.h:27
UniListIter::add
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
IUniConfGen::ListIter
::UniListIter ListIter
An iterator over a constant list of keys (see below)
Definition: uniconfgen.h:160
WvStringCache::get
WvString get(WvStringParm s)
Get a shared string corresponding to 's'.
Definition: wvstringcache.cc:39
UniTempGen::root
UniConfValueTree * root
Definition: unitempgen.h:25
UniConfGen::unhold_delta
void unhold_delta()
Resumes notifications when each hold_delta() has been matched.
Definition: uniconfgen.cc:38
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
UniConfGen::commit
virtual void commit()
Commits any changes.
Definition: uniconfgen.h:280
IUniConfGen
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:39
UniConfTree::findchild
Sub * findchild(const UniConfKey &key) const
Finds the direct child node with the specified key.
Definition: uniconftree.h:71
UniConfValueTree::value
const WvString & value() const
Returns the value field.
Definition: uniconftree.h:163
UniConfTree::visit
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
WvFastString::isnull
bool isnull() const
returns true if this string is null
Definition: wvstring.h:290
UniConfKey::Iter
An iterator over the segments of a key.
Definition: uniconfkey.h:463
UniTempGen::dirty
bool dirty
Definition: unitempgen.h:26
UniHashTreeBase::Iter
Definition: unihashtree.h:78
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
UniConfValueTree::setvalue
void setvalue(WvStringParm value)
Sets the value field.
Definition: uniconftree.h:167
WvMoniker
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:61
UniConfKey::isempty
bool isempty() const
Returns true if this path has zero segments (also known as root).
Definition: uniconfkey.h:264
UniTempGen::set
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: unitempgen.cc:57
UniConfGen::delta
void delta(const UniConfKey &key, WvStringParm value)
Call this when a key's value or children have possibly changed.
Definition: uniconfgen.cc:77
IObject
Definition: IObject.h:65
UniTempGen::commit
virtual void commit()
Commits any changes.
Definition: unitempgen.cc:185
UniConfTree::fullkey
UniConfKey fullkey(const Sub *ancestor=NULL) const
Returns full path of this node relative to an ancestor.
Definition: uniconftree.h:55
UniTempGen::refresh
virtual bool refresh()
Refreshes information about a key recursively.
Definition: unitempgen.cc:191
UniConfValueTree
A plain UniConfTree that holds keys and values.
Definition: uniconftree.h:152
UniTempGen::setv
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
Definition: unitempgen.cc:150
UniHashTreeBase::haschildren
bool haschildren() const
Returns true if the node has children.
Definition: unihashtree.cc:114
UniConfTree::find
Sub * find(const UniConfKey &key) const
Finds the sub-node with the specified key.
Definition: uniconftree.h:62
UniConfKey::last
UniConfKey last(int n=1) const
Returns the path formed by the n last segments of this path.
Definition: uniconfkey.h:324
UniConfKey::numsegments
int numsegments() const
Returns the number of segments in this path.
Definition: uniconfkey.h:287
UniConfGen::refresh
virtual bool refresh()
Refreshes information about a key recursively.
Definition: uniconfgen.h:281
UniConfGen::hold_delta
void hold_delta()
Pauses notifications until matched with a call to unhold_delta().
Definition: uniconfgen.cc:32
UniTempGen
A UniConf generator that stores keys in memory.
Definition: unitempgen.h:20
UniConfGen::Iter
An abstract iterator over keys and values in a generator.
Definition: uniconfgen.h:323