WvStreams
unidefgen.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2002 Net Integration Technologies, Inc.
4  *
5  * UniDefGen is a UniConfGen for retrieving data with defaults
6  */
7 #include "unidefgen.h"
8 #include "wvmoniker.h"
9 //#include "wvstream.h"
10 #include <ctype.h>
11 #include <stdlib.h>
12 
13 #include "wvlinkerhack.h"
14 
15 WV_LINK(UniDefGen);
16 
17 
18 // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the
19 // given moniker.
20 static IUniConfGen *creator(WvStringParm s, IObject *_obj)
21 {
22  return new UniDefGen(wvcreate<IUniConfGen>(s, _obj));
23 }
24 
25 // this name is too confusing. We should deprecate it.
26 static WvMoniker<IUniConfGen> reg("default", creator);
27 
28 // a better name for the same thing.
29 static WvMoniker<IUniConfGen> reg2("wildcard", creator);
30 
31 
32 UniConfKey UniDefGen::finddefault(const UniConfKey &key, char *p, char *q)
33 {
34  UniConfKey result;
35 
36  if (!p)
37  {
38  q++;
39  if (inner() && inner()->exists(q))
40  return q;
41  else
42  return UniConfKey();
43  }
44 
45  // pop the first segment of p to r
46  char *r = strchr(p, '/');
47  if (r)
48  *r++ = '\0';
49 
50  // append p to q
51  char *s = strchr(q, '\0');
52  *s++ = '/';
53  *s = 0;
54  q = strcat(q, p);
55 
56  // try this literal path
57  result = finddefault(key, r, q);
58  if (result.numsegments())
59  return result;
60 
61  // replace what used to be p with a *
62  *s++ = '*';
63  *s = '\0';
64  result = finddefault(key, r, q);
65 
66  if (r)
67  *--r = '/';
68 
69  return result;
70 }
71 
72 
73 WvString UniDefGen::replacewildcard(const UniConfKey &key,
74  const UniConfKey &defkey, WvStringParm in)
75 {
76  // check if the result wants a wildcard ('*n')
77  if (in.len() < 2 || in[0] != '*')
78  return in;
79 
80  const char *s = in.cstr();
81  int idx = atoi(s+1);
82  if (idx == 0)
83  return in;
84 
85  // search backwards for segment num of the n'th wildcard
86  UniConfKey k(defkey);
87  int loc = key.numsegments();
88  for (int i = 0; i < idx; i++)
89  {
90  if (i != 0)
91  {
92  k = k.removelast();
93  loc--;
94  }
95  while (!k.last().iswild())
96  {
97  k = k.removelast();
98  loc--;
99  if (k.isempty())
100  {
101  // oops, ran out of segments!
102  return WvString();
103  }
104  }
105  }
106 
107 
108  // pull the literal from that segment num of the key
109  return key.segment(loc-1);
110 }
111 
112 
113 bool UniDefGen::keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key)
114 {
115  WvString tmp_key(unmapped_key), tmp("");
116  char *p = tmp_key.edit();
117 
118  tmp.setsize(strlen(tmp_key) * 2);
119  char *q = tmp.edit();
120  *q = '\0';
121 
122  mapped_key = finddefault(unmapped_key, p, q);
123  if (!mapped_key.numsegments())
124  mapped_key = unmapped_key;
125  // fprintf(stderr, "mapping '%s' -> '%s'\n", key.cstr(), result.cstr());
126 
127  return true;
128 }
129 
130 
132 {
133  UniConfKey mapped_key;
134  if (keymap(key, mapped_key))
135  return replacewildcard(key, mapped_key,
136  inner() ? inner()->get(mapped_key) : WvString());
137  else
138  return WvString::null;
139 }
140 
141 
142 void UniDefGen::set(const UniConfKey &key, WvStringParm value)
143 {
144  // no keymap() on set()
145  if (inner())
146  inner()->set(key, value);
147 }
WvString::edit
char * edit()
make the string editable, and return a non-const (char*)
Definition: wvstring.h:397
IUniConfGen::set
virtual void set(const UniConfKey &key, WvStringParm value)=0
Stores a string value for a key into the registry.
UniDefGen::get
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition: unidefgen.cc:131
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
UniDefGen::set
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition: unidefgen.cc:142
IUniConfGen
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:39
UniDefGen
Definition: unidefgen.h:43
WvFastString::cstr
const char * cstr() const
return a (const char *) for this string.
Definition: wvstring.h:267
UniConfKey
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:38
WvMoniker
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:61
UniFilterGen::inner
IUniConfGen * inner() const
Returns the inner generator.
Definition: unifiltergen.h:33
IObject
Definition: IObject.h:65
UniConfKey::segment
UniConfKey segment(int n) const
Returns the specified segment of the path.
Definition: uniconfkey.h:297
UniFilterGen::exists
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
Definition: unifiltergen.cc:108
UniConfKey::numsegments
int numsegments() const
Returns the number of segments in this path.
Definition: uniconfkey.h:287
UniDefGen::keymap
virtual bool keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key)
A mapping function for filters that remap one keyspace onto another.
Definition: unidefgen.cc:113