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.
Definition IObject.h:65
An abstract data container that backs a UniConf tree.
Definition uniconfgen.h:40
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...
Definition uniconfkey.h:39
int numsegments() const
Returns the number of segments in this path.
Definition uniconfkey.h:287
UniConfKey segment(int n) const
Returns the specified segment of the path.
Definition uniconfkey.h:297
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...
Definition wvstring.h:94
const char * cstr() const
return a (const char *) for this string.
Definition wvstring.h:267
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition wvmoniker.h:62
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330
char * edit()
make the string editable, and return a non-const (char*)
Definition wvstring.h:397