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
15WV_LINK(UniDefGen);
16
17
18// if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the
19// given moniker.
20static 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.
26static WvMoniker<IUniConfGen> reg("default", creator);
27
28// a better name for the same thing.
29static WvMoniker<IUniConfGen> reg2("wildcard", creator);
30
31
32UniConfKey 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
73WvString 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
113bool 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
143{
144 // no keymap() on set()
145 if (inner())
146 inner()->set(key, value);
147}
The basic interface which is included by all other XPLC interfaces and objects.
An abstract data container that backs a UniConf tree.
virtual void set(const UniConfKey &key, WvStringParm value)=0
Stores a string value for a key into the registry.
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
int numsegments() const
Returns the number of segments in this path.
UniConfKey segment(int n) const
Returns the specified segment of the path.
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
Definition unidefgen.cc:142
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
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Definition unidefgen.cc:131
IUniConfGen * inner() const
Returns the inner generator.
virtual bool exists(const UniConfKey &key)
Without fetching its value, returns true if a key exists.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
const char * cstr() const
return a (const char *) for this string.
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
WvString is an implementation of a simple and efficient printable-string class.
char * edit()
make the string editable, and return a non-const (char*)