WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 2002-2005 Net Integration Technologies, Inc. 00004 * 00005 * A lightweight but slightly dangerous version of UniCacheGen. 00006 */ 00007 #include <wvassert.h> 00008 00009 #include "unifastregetgen.h" 00010 #include "uniconftree.h" 00011 #include "wvmoniker.h" 00012 00013 // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the 00014 // given moniker. 00015 static IUniConfGen *creator(WvStringParm s, IObject *_obj) 00016 { 00017 return new UniFastRegetGen(wvcreate<IUniConfGen>(s, _obj)); 00018 } 00019 00020 static WvMoniker<IUniConfGen> reg("fast-reget", creator); 00021 00022 00023 UniFastRegetGen::UniFastRegetGen(IUniConfGen *_inner) : 00024 UniFilterGen(_inner), 00025 tree(NULL) 00026 { 00027 tree = new UniConfValueTree(NULL, "/", UniFilterGen::get("/")); 00028 } 00029 00030 00031 UniFastRegetGen::~UniFastRegetGen() 00032 { 00033 if (tree) 00034 { 00035 delete tree; 00036 tree = NULL; 00037 } 00038 } 00039 00040 00041 void UniFastRegetGen::gencallback(const UniConfKey &key, WvStringParm value) 00042 { 00043 if (tree == NULL) 00044 return; // initialising 00045 00046 UniConfValueTree *t = tree->find(key); 00047 if (t) // never previously retrieved; don't cache it 00048 t->setvalue(value); 00049 UniFilterGen::gencallback(key, value); 00050 } 00051 00052 00053 WvString UniFastRegetGen::get(const UniConfKey &key) 00054 { 00055 if (!tree) 00056 { 00057 wvassert(tree, "key: '%s'", key); 00058 abort(); 00059 } 00060 00061 // Keys with trailing slashes can't have values set on them 00062 if (key.hastrailingslash()) 00063 return WvString::null; 00064 00065 UniConfValueTree *t = tree->find(key); 00066 if (!t) 00067 { 00068 UniConfKey parentkey(key.removelast()); 00069 get(parentkey); // guaranteed to create parent node 00070 t = tree->find(parentkey); 00071 assert(t); 00072 00073 WvString value; 00074 if (!t->value().isnull()) // if parent is null, child guaranteed null 00075 value = UniFilterGen::get(key); 00076 new UniConfValueTree(t, key.last(), value); 00077 return value; 00078 } 00079 else 00080 return t->value(); 00081 } 00082 00083 00084 bool UniFastRegetGen::exists(const UniConfKey &key) 00085 { 00086 // even if inner generator has a more efficient version of exists(), 00087 // do it this way so we can cache the result. 00088 return !get(key).isnull(); 00089 } 00090 00091 00092 bool UniFastRegetGen::haschildren(const UniConfKey &key) 00093 { 00094 if (!tree) 00095 { 00096 wvassert(tree, "key: '%s'", key); 00097 abort(); 00098 } 00099 00100 // if we already know the node is null, we can short circuit this one 00101 UniConfValueTree *t = tree->find(key); 00102 if (t && t->value().isnull()) 00103 return false; // definitely no children 00104 return UniFilterGen::haschildren(key); 00105 }