WvStreams
unilistgen.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2002 Net Integration Technologies, Inc.
4  *
5  * UniListGen is a UniConf generator to allow multiple generators to be
6  * stacked in a priority sequence for get/set/etc.
7  *
8  */
9 #include "unilistgen.h"
10 #include "wvmoniker.h"
11 #include "wvtclstring.h"
12 #include "wvstringlist.h"
13 #include "wvlinkerhack.h"
14 
15 WV_LINK(UniListGen);
16 
17 
18 
20 {
21 protected:
22  DeclareWvScatterTable(UniConfKey);
23  DeclareWvList2(IterList, UniConfGen::Iter);
24 
25  IterList l;
26  IterList::Iter *i;
27  UniConfKeyTable d;
28 
29 public:
30  IterIter(UniListGen *gen, const UniConfKey &key);
31  virtual ~IterIter() { delete i; }
32 
33  virtual void rewind();
34  virtual bool next();
35  virtual UniConfKey key() const;
36  virtual WvString value() const;
37 };
38 
39 
40 
41 static IUniConfGen *creator(WvStringParm s, IObject *_obj)
42 {
43  UniConfGenList *l = new UniConfGenList();
44 
45  WvStringList gens;
46  wvtcl_decode(gens, s);
47  WvStringList::Iter i(gens);
48 
49  for (i.rewind(); i.next();)
50  {
51  if (_obj) _obj->addRef();
52  IUniConfGen *gen = wvcreate<IUniConfGen>(i(), _obj);
53  if (gen)
54  l->append(gen, true);
55  }
56  if (_obj) _obj->release();
57 
58  return new UniListGen(l);
59 }
60 
61 static WvMoniker<IUniConfGen> reg("list", creator);
62 
63 UniListGen::UniListGen(UniConfGenList *_l) : l(_l)
64 {
65  UniConfGenList::Iter i(*l);
66  for (i.rewind(); i.next(); )
67  i->add_callback(this, wv::bind(&UniListGen::gencallback, this, _1, _2));
68 }
69 
70 
71 UniListGen::~UniListGen()
72 {
73  UniConfGenList::Iter i(*l);
74  for (i.rewind(); i.next(); )
75  i->del_callback(this);
76  delete l;
77 }
78 
79 
81 {
82  UniConfGenList::Iter i(*l);
83  for (i.rewind(); i.next();)
84  i->commit();
85 }
86 
87 
89 {
90  bool result = true;
91 
92  UniConfGenList::Iter i(*l);
93  for (i.rewind(); i.next();)
94  result = i->refresh() && result;
95  return result;
96 }
97 
98 
100 {
101  UniConfGenList::Iter i(*l);
102  for (i.rewind(); i.next(); )
103  if (i->exists(key))
104  return i->get(key);
105  return WvString::null;
106 }
107 
108 
109 // we try to set *all* our generators. Read-only ones will ignore us.
110 void UniListGen::set(const UniConfKey &key, WvStringParm value)
111 {
112  UniConfGenList::Iter i(*l);
113  for (i.rewind(); i.next(); )
114  i->set(key, value);
115 }
116 
117 
118 void UniListGen::setv(const UniConfPairList &pairs)
119 {
120  UniConfGenList::Iter i(*l);
121  for (i.rewind(); i.next(); )
122  i->setv(pairs);
123 }
124 
125 
127 {
128  UniConfGenList::Iter i(*l);
129  for (i.rewind(); i.next();)
130  {
131  if (i->exists(key))
132  return true;
133  }
134  return false;
135 }
136 
137 
139 {
140  UniConfGenList::Iter i(*l);
141  for (i.rewind(); i.next();)
142  {
143  if (i->haschildren(key))
144  return true;
145  }
146  return false;
147 }
148 
149 
151 {
152  UniConfGenList::Iter i(*l);
153  for (i.rewind(); i.next();)
154  {
155  if (!i->isok())
156  return false;
157  }
158  return true;
159 }
160 
161 
162 void UniListGen::gencallback(const UniConfKey &key, WvStringParm value)
163 {
164  delta(key, get(key));
165 }
166 
167 
169 {
170  return new IterIter(this, key);
171 }
172 
173 
174 /***** UniListGen::IterIter *****/
175 
176 UniListGen::IterIter::IterIter(UniListGen *gen, const UniConfKey &key)
177 {
178  UniConfGenList::Iter geniter(*gen->l);
179  for (geniter.rewind(); geniter.next(); )
180  {
181  Iter *it = geniter->iterator(key);
182  if (it)
183  l.append(it, true);
184  }
185 
186  i = new IterList::Iter(l);
187 }
188 
189 
191 {
192  for ((*i).rewind(); (*i).next(); )
193  (*i)->rewind();
194 
195  i->rewind();
196  i->next();
197 
198  d.zap();
199 }
200 
201 
203 {
204  if (l.isempty())
205  return false;
206 
207  if ((*i)->next())
208  {
209  // When iterating, make sure each key value is only returned once
210  // (from the top item in the list)
211  if (!d[(*i)->key()])
212  {
213  d.add(new UniConfKey((*i)->key()), true);
214  return true;
215  }
216  else
217  return next();
218  }
219 
220  if (!i->next())
221  return false;
222 
223  return next();
224 }
225 
226 
228 {
229  return (*i)->key();
230 }
231 
232 
234 {
235  return (*i)->value();
236 }
237 
238 
UniListGen::commit
virtual void commit()
Commits any changes.
Definition: unilistgen.cc:80
UniListGen::IterIter::key
virtual UniConfKey key() const
Returns the current key.
Definition: unilistgen.cc:227
wvtclstring.h
UniListGen::exists
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
Definition: unilistgen.cc:126
UniListGen::iterator
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
Definition: unilistgen.cc:168
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
IUniConfGen
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:39
UniListGen::setv
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
Definition: unilistgen.cc:118
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
UniListGen::IterIter
Definition: unilistgen.cc:19
WvMoniker
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:61
IObject::release
virtual unsigned int release()=0
Indicate that you are finished using this object.
UniListGen::gencallback
virtual void gencallback(const UniConfKey &key, WvStringParm value)
Called by first generator when a key changes.
Definition: unilistgen.cc:162
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
UniListGen::get
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: unilistgen.cc:99
UniListGen::refresh
virtual bool refresh()
Refreshes information about a key recursively.
Definition: unilistgen.cc:88
UniListGen::set
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: unilistgen.cc:110
UniListGen::haschildren
virtual bool haschildren(const UniConfKey &key)
Returns true if a key has children.
Definition: unilistgen.cc:138
UniListGen
Accepts a list of UniConf generators, and stacks them, treating them as one uniconf source.
Definition: unilistgen.h:30
UniListGen::IterIter::next
virtual bool next()
Seeks to the next element in the sequence.
Definition: unilistgen.cc:202
WvStringList
This is a WvList of WvStrings, and is a really handy way to parse strings.
Definition: wvstringlist.h:27
wvtcl_decode
void wvtcl_decode(WvList< WvString > &l, WvStringParm _s, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
split a tcl-style list.
Definition: wvtclstring.cc:386
UniListGen::IterIter::rewind
virtual void rewind()
Rewinds the iterator.
Definition: unilistgen.cc:190
UniListGen::IterIter::value
virtual WvString value() const
Returns the value of the current key.
Definition: unilistgen.cc:233
UniListGen::isok
virtual bool isok()
Determines if the generator is usable and working properly.
Definition: unilistgen.cc:150
IObject::addRef
virtual unsigned int addRef()=0
Indicate you are using this object.
UniConfGen::Iter
An abstract iterator over keys and values in a generator.
Definition: uniconfgen.h:323