WvStreams
uniconfkey.h
1 /* -*- Mode: C++ -*-
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2002 Net Integration Technologies, Inc.
4  *
5  * UniConfKeys are paths in the UniConf hierarchy.
6  */
7 #ifndef __UNICONFKEY_H
8 #define __UNICONFKEY_H
9 
10 #include "wvstring.h"
11 #include "wvlinklist.h"
12 #include <limits.h>
13 
14 
39 {
40  class Segment : public WvString
41  {
42  public:
43  Segment() :
44  WvString(WvString::empty)
45  {
46  }
47  Segment(WvStringParm str) :
48  WvString((!str)? WvString::empty: str)
49  {
50  }
51  Segment(const Segment &segment) :
53  {
54  }
55 
56  bool iswild() const
57  {
58  return *this == "*" || *this == "...";
59  }
60  };
61 
62  class SegmentVector
63  {
64  int _size, _used;
65  Segment *vec;
66  public:
67  SegmentVector(int size) :
68  _size(size),
69  _used(0),
70  vec(new Segment[_size])
71  {
72  }
73  ~SegmentVector()
74  {
75  deletev vec;
76  }
77 
78  void resize(int size, int shift = 0)
79  {
80  if (size <= _size)
81  {
82  if (shift > 0)
83  {
84  for (int i=_used-1; i>=0; --i)
85  vec[i+shift] = vec[i];
86  _used += shift;
87  }
88  return;
89  }
90  Segment *old_vec = vec;
91  vec = new Segment[size];
92  if (old_vec)
93  {
94  int limit = size-shift;
95  if (limit > _size)
96  limit = _size;
97  if (limit > _used)
98  limit = _used;
99  for (int i=0; i<limit; ++i)
100  vec[i+shift] = old_vec[i];
101  deletev old_vec;
102  }
103  _size = size;
104  _used += shift;
105  }
106  void zap()
107  {
108  _used = 0;
109  }
110  int size() const
111  {
112  return _size;
113  }
114  int used() const
115  {
116  return _used;
117  }
118 
119  void append(const Segment &segment)
120  {
121  vec[_used++] = segment;
122  }
123  void append(WvStringParm string)
124  {
125  append(Segment(string));
126  }
127  void replace(int index, const Segment &segment)
128  {
129  vec[index] = segment;
130  if (index >= _used)
131  _used = index + 1;
132  }
133  void replace(int index, WvStringParm string)
134  {
135  replace(index, Segment(string));
136  }
137  const Segment &operator [](int index) const
138  {
139  return vec[index];
140  }
141  };
142 
143  struct Store
144  {
145  SegmentVector segments;
146  int ref_count;
147 
148  Store(int size, int _ref_count, WvStringParm key = WvString::null);
149  };
150 
151  Store *store;
152  int left, right;
153 
154  static Store EMPTY_store;
155  static Store ANY_store;
156  static Store RECURSIVE_ANY_store;
158  UniConfKey(Store *_store, int _left, int _right) :
159  store(_store),
160  left(_left),
161  right(_right)
162  {
163  store->ref_count++;
164  }
165 
166  void unique();
167  void normalize();
168  UniConfKey &collapse();
169 
170 public:
171  static UniConfKey EMPTY;
172  static UniConfKey ANY;
177  store(&EMPTY_store),
178  left(0),
179  right(0)
180  {
181  store->ref_count++;
182  }
183 
192  UniConfKey(WvStringParm key) :
193  store(new Store(4, 1, key)),
194  left(0),
195  right(store->segments.used())
196  {
197  }
198 
208  UniConfKey(const char *key) :
209  store(new Store(4, 1, WvFastString(key))),
210  left(0),
211  right(store->segments.used())
212  {
213  }
214 
216  UniConfKey(int key) :
217  store(new Store(1, 1, WvFastString(key))),
218  left(0),
219  right(store->segments.used())
220  {
221  }
222 
227  UniConfKey(const UniConfKey &other) :
228  store(other.store),
229  left(other.left),
230  right(other.right)
231  {
232  store->ref_count++;
233  }
234 
240  UniConfKey(const UniConfKey &path, const UniConfKey &key);
241 
242  ~UniConfKey()
243  {
244  if (--store->ref_count == 0)
245  delete store;
246  }
247 
252  void append(const UniConfKey &other);
253 
258  void prepend(const UniConfKey &other);
259 
264  bool isempty() const
265  {
266  return right == left;
267  }
268 
270  bool iswild() const;
271 
273  bool hastrailingslash() const
274  {
275  return right > left && !store->segments[right-1];
276  }
277 
287  int numsegments() const
288  {
289  return right - left;
290  }
291 
297  UniConfKey segment(int n) const
298  {
299  return range(n, n + 1);
300  }
301 
307  UniConfKey pop(int n = 1);
308 
314  UniConfKey first(int n = 1) const
315  {
316  return range(0, n);
317  }
318 
324  UniConfKey last(int n = 1) const
325  {
326  return range(numsegments() - n, INT_MAX);
327  }
328 
335  UniConfKey removefirst(int n = 1) const
336  {
337  return range(n, INT_MAX);
338  }
339 
346  UniConfKey removelast(int n = 1) const
347  {
348  return range(0, numsegments() - n);
349  }
350 
357  UniConfKey range(int i, int j) const;
358 
370  WvString printable() const;
371  operator WvString() const
372  { return printable(); }
373 
377  const char *cstr() const
378  { return printable(); }
379 
385  {
386  if (--store->ref_count == 0)
387  delete store;
388  store = other.store;
389  left = other.left;
390  right = other.right;
391  ++store->ref_count;
392  return *this;
393  }
394 
402  int compareto(const UniConfKey &other) const;
403 
414  bool matches(const UniConfKey &pattern) const;
415 
416 
420  bool suborsame(const UniConfKey &key) const;
421  bool suborsame(const UniConfKey &key, UniConfKey &subkey) const;
422 
428  UniConfKey subkey(const UniConfKey &key) const;
429 
435  bool operator== (const UniConfKey &other) const
436  { return compareto(other) == 0; }
437 
443  bool operator!= (const UniConfKey &other) const
444  { return compareto(other) != 0; }
445 
451  bool operator< (const UniConfKey &other) const
452  { return compareto(other) < 0; }
453 
454  class Iter;
455 
456  friend unsigned WvHash(const UniConfKey &k);
457 };
458 
459 
460 DeclareWvList(UniConfKey);
461 
464 {
465  const UniConfKey &key;
466  int seg, max;
467  UniConfKey curseg;
468 
469 public:
470  Iter(const UniConfKey &_key) : key(_key)
471  { }
472 
473  void rewind()
474  { seg = -1; max = key.numsegments(); }
475 
476  bool cur()
477  { return seg >= 0 && seg < max; }
478 
479  bool next()
480  { seg++; curseg = key.segment(seg); return cur(); }
481 
482  const UniConfKey *ptr() const
483  { return &curseg; }
484 
485  WvIterStuff(const UniConfKey);
486 };
487 
488 #endif // __UNICONFKEY_H
UniConfKey::UniConfKey
UniConfKey(WvStringParm key)
Constructs a UniConfKey from a string.
Definition: uniconfkey.h:192
UniConfKey::removefirst
UniConfKey removefirst(int n=1) const
Returns the path formed by removing the first n segments of this path.
Definition: uniconfkey.h:335
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
UniConfKey::compareto
int compareto(const UniConfKey &other) const
Compares two paths lexicographically.
Definition: uniconfkey.cc:235
UniConfKey::UniConfKey
UniConfKey(const char *key)
Constructs a UniConfKey from a string.
Definition: uniconfkey.h:208
UniConfKey::operator==
bool operator==(const UniConfKey &other) const
Determines if two paths are equal.
Definition: uniconfkey.h:435
UniConfKey::removelast
UniConfKey removelast(int n=1) const
Returns the path formed by removing the last n segments of this path.
Definition: uniconfkey.h:346
UniConfKey::operator<
bool operator<(const UniConfKey &other) const
Determines if this path precedes the other lexicographically.
Definition: uniconfkey.h:451
UniConfKey::prepend
void prepend(const UniConfKey &other)
Prepends a path to this path.
Definition: uniconfkey.cc:152
UniConfKey::printable
WvString printable() const
Returns the canonical string representation of the path.
Definition: uniconfkey.cc:212
UniConfKey::subkey
UniConfKey subkey(const UniConfKey &key) const
If this UniConfKey is a subkey of 'key', then return the subkey portion.
Definition: uniconfkey.cc:324
UniConfKey::UniConfKey
UniConfKey(const UniConfKey &other)
Copies a UniConfKey.
Definition: uniconfkey.h:227
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
UniConfKey::cstr
const char * cstr() const
Returns a (const char *) of printable() directly.
Definition: uniconfkey.h:377
UniConfKey::matches
bool matches(const UniConfKey &pattern) const
Determines if the key matches a pattern.
Definition: uniconfkey.cc:256
UniConfKey::UniConfKey
UniConfKey(int key)
Constructs a UniConfKey from an int.
Definition: uniconfkey.h:216
UniConfKey::Iter
An iterator over the segments of a key.
Definition: uniconfkey.h:463
UniConfKey::operator!=
bool operator!=(const UniConfKey &other) const
Determines if two paths are unequal.
Definition: uniconfkey.h:443
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
UniConfKey::ANY
static UniConfKey ANY
Definition: uniconfkey.h:172
UniConfKey::suborsame
bool suborsame(const UniConfKey &key) const
Returns true if 'key' is a the same, or a subkey, of this UniConfKey.
Definition: uniconfkey.cc:294
UniConfKey::isempty
bool isempty() const
Returns true if this path has zero segments (also known as root).
Definition: uniconfkey.h:264
UniConfKey::first
UniConfKey first(int n=1) const
Returns the path formed by the n first segments of this path.
Definition: uniconfkey.h:314
UniConfKey::range
UniConfKey range(int i, int j) const
Returns a range of segments.
Definition: uniconfkey.cc:200
UniConfKey::EMPTY
static UniConfKey EMPTY
Definition: uniconfkey.h:171
deletev
#define deletev
Remplacement for delete[].
Definition: delete.h:129
UniConfKey::hastrailingslash
bool hastrailingslash() const
Returns true if the key has a trailing slash.
Definition: uniconfkey.h:273
UniConfKey::segment
UniConfKey segment(int n) const
Returns the specified segment of the path.
Definition: uniconfkey.h:297
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::iswild
bool iswild() const
Returns true if the key contains a wildcard.
Definition: uniconfkey.cc:174
UniConfKey::UniConfKey
UniConfKey()
Constructs an empty UniConfKey (the 'root').
Definition: uniconfkey.h:176
UniConfKey::numsegments
int numsegments() const
Returns the number of segments in this path.
Definition: uniconfkey.h:287
WvFastString
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition: wvstring.h:93
UniConfKey::operator=
UniConfKey & operator=(const UniConfKey &other)
Assigns this path to equal another.
Definition: uniconfkey.h:384
UniConfKey::append
void append(const UniConfKey &other)
Appends a path to this path.
Definition: uniconfkey.cc:130
UniConfKey::RECURSIVE_ANY
static UniConfKey RECURSIVE_ANY
Definition: uniconfkey.h:173