Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

unidefgen.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2002 Net Integration Technologies, Inc.
00004  * 
00005  * UniDefGen is a UniConfGen for retrieving data with defaults
00006  *
00007  */
00008 
00009 #include "unidefgen.h"
00010 #include "wvmoniker.h"
00011 
00012 #include <ctype.h>
00013 #include <stdlib.h>
00014 
00015 // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the
00016 // given moniker.
00017 static UniConfGen *creator(WvStringParm s, IObject *obj, void *)
00018 {
00019     UniConfGen *gen = NULL;
00020 
00021     if (obj)
00022         gen = mutate<UniConfGen>(obj);
00023     if (!gen)
00024         gen = wvcreate<UniConfGen>(s);
00025 
00026     return new UniDefGen(gen);
00027 }
00028 
00029 static WvMoniker<UniConfGen> reg("default", creator);
00030 
00031 
00032 WvString UniDefGen::get(const UniConfKey &key)
00033 {
00034     WvString tmp_key(key), tmp("");
00035     char *p = tmp_key.edit();
00036 
00037     tmp.setsize(strlen(tmp_key) * 2);
00038     char *q = tmp.edit();
00039     *q = '\0';
00040 
00041     WvString result;
00042     finddefault(key, p, q, result);
00043     return result;
00044 }
00045 
00046 
00047 void UniDefGen::finddefault(const UniConfKey &key, char *p, char *q,
00048         WvString &result)
00049 {
00050     if (!p)
00051     {
00052         result = UniFilterGen::get(++q);
00053         if (!result.isnull())
00054             replacewildcard(key, q, result);
00055         return;
00056     }
00057 
00058     // pop the first segment of p to r
00059     char *r = strchr(p, '/');
00060     if (r)
00061         *r++ = '\0';
00062 
00063     // append p to q
00064     char *s = strchr(q, '\0');
00065     *s++ = '/';
00066     *s = 0;
00067     q = strcat(q, p);
00068 
00069     // try this literal path
00070     finddefault(key, r, q, result);
00071 
00072     if (!result.isnull())
00073         return;
00074 
00075     // replace what used to be p with a *
00076     *s++ = '*';
00077     *s = '\0';
00078     finddefault(key, r, q, result);
00079 
00080     if (r)
00081         *--r = '/';
00082 }
00083 
00084 
00085 void UniDefGen::replacewildcard(const UniConfKey &key, char *p,
00086         WvString &result)
00087 {
00088     // check if the result wants a wildcard ('*n')
00089     const char *s = result.cstr();
00090     if (strlen(s) < 2 || s[0] != '*')
00091         return;
00092 
00093     int idx = atoi(s+1);
00094     if (idx == 0)
00095         return;
00096 
00097     // search backwards for segment num of the n'th wildcard
00098     UniConfKey k(p);
00099     int loc = key.numsegments();
00100     for (int i = 0; i < idx; i++)
00101     {
00102         if (i != 0)
00103         {
00104             k = k.removelast();
00105             loc--;
00106         }
00107         while (!k.last().iswild())
00108         {
00109             k = k.removelast();
00110             loc--;
00111             if (k.isempty())
00112             {
00113                 // oops, ran out of segments!
00114                 result = WvString::null;
00115                 return;
00116             }
00117         }
00118     }
00119 
00120     // pull the literal from that segment num of the key
00121     result = key.segment(loc-1);
00122 }

Generated on Sat Mar 13 14:55:21 2004 for WvStreams by doxygen 1.3.6-20040222