wvmoniker.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Support for monikers, which are strings that you can pass to a magic
00006  * factory to get objects supporting a particular interface.  See wvmoniker.h.
00007  */
00008 #include "wvmonikerregistry.h"
00009 #include "strutils.h"
00010 #include <assert.h>
00011 #include <stdio.h>
00012 
00013 #if 0
00014 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args)
00015 #else
00016 #ifndef _MSC_VER
00017 # define DEBUGLOG(fmt, args...)
00018 #else  // MS Visual C++ doesn't support varags preproc macros
00019 # define DEBUGLOG
00020 #endif
00021 #endif
00022 
00023 
00024 static unsigned WvHash(const UUID &_uuid)
00025 {
00026     unsigned val = 0;
00027     unsigned int *uuid = (unsigned int *)&_uuid;
00028     int max = sizeof(UUID)/sizeof(*uuid);
00029     
00030     for (int count = 0; count < max; count++)
00031         val += uuid[count];
00032     
00033     return val;
00034 }
00035 
00036 
00037 DeclareWvScatterDict(WvMonikerRegistry, UUID, reg_iid);
00038 static WvMonikerRegistryDict *regs;
00039   
00040 
00041 
00042 WvMonikerRegistry::WvMonikerRegistry(const UUID &iid) 
00043     : reg_iid(iid), dict(10)
00044 {
00045     DEBUGLOG("WvMonikerRegistry creating.\n");
00046     refcount = 0;
00047 }
00048 
00049 
00050 WvMonikerRegistry::~WvMonikerRegistry()
00051 {
00052     DEBUGLOG("WvMonikerRegistry destroying.\n");
00053 }
00054 
00055 
00056 void WvMonikerRegistry::add(WvStringParm id, WvMonikerCreateFunc *func)
00057 {
00058     DEBUGLOG("WvMonikerRegistry register(%s).\n", id.cstr());
00059     assert(!dict[id]);
00060     dict.add(new Registration(id, func), true);
00061 }
00062 
00063 
00064 void WvMonikerRegistry::del(WvStringParm id)
00065 {
00066     DEBUGLOG("WvMonikerRegistry unregister(%s).\n", id.cstr());
00067     assert(dict[id]);
00068     dict.remove(dict[id]);
00069 }
00070 
00071 
00072 void *WvMonikerRegistry::create(WvStringParm _s)
00073 {
00074     WvString t(_s);
00075     WvString s(trim_string(t.edit()));
00076 
00077     char *cptr = strchr(s.edit(), ':');
00078     if (cptr)
00079         *cptr++ = 0;
00080     else
00081         cptr = "";
00082     
00083     DEBUGLOG("WvMonikerRegistry create object ('%s' '%s').\n", s.cstr(), cptr);
00084     
00085     Registration *r = dict[s];
00086     if (r)
00087         return r->func(cptr);
00088     else
00089         return NULL;
00090 }
00091 
00092 
00093 WvMonikerRegistry *WvMonikerRegistry::find_reg(const UUID &iid)
00094 {
00095     DEBUGLOG("WvMonikerRegistry find_reg.\n");
00096     
00097     if (!regs)
00098         regs = new WvMonikerRegistryDict(10);
00099     
00100     WvMonikerRegistry *reg = (*regs)[iid];
00101     
00102     if (!reg)
00103     {
00104         // we have to make one!
00105         reg = new WvMonikerRegistry(iid);
00106         regs->add(reg, true);
00107         reg->addRef(); // one reference for being in the list at all
00108     }
00109     
00110     reg->addRef();
00111     return reg;
00112 }
00113 
00114 
00115 IObject *WvMonikerRegistry::getInterface(const UUID &uuid)
00116 {
00117 #if 0
00118     if (uuid.equals(IObject_IID))
00119     {
00120         addRef();
00121         return this;
00122     }
00123 #endif
00124     
00125     // we don't really support any interfaces for now.
00126     
00127     return 0;
00128 }
00129 
00130 
00131 unsigned int WvMonikerRegistry::addRef()
00132 {
00133     DEBUGLOG("WvMonikerRegistry addRef.\n");
00134     return ++refcount;
00135 }
00136 
00137 
00138 unsigned int WvMonikerRegistry::release()
00139 {
00140     DEBUGLOG("WvMonikerRegistry release.\n");
00141     
00142     if (--refcount > 1)
00143         return refcount;
00144     
00145     if (refcount == 1)
00146     {
00147         // the list has one reference to us, but it's no longer needed.
00148         // Note: remove() will delete this object!
00149         regs->remove(this);
00150         if (regs->isempty())
00151         {
00152             delete regs;
00153             regs = NULL;
00154         }
00155         return 0;
00156     }
00157     
00158     /* protect against re-entering the destructor */
00159     refcount = 1;
00160     delete this;
00161     return 0;
00162 }
00163 
00164 
00165 WvMonikerBase::WvMonikerBase(const UUID &iid, WvStringParm _id, 
00166                              WvMonikerCreateFunc *func)
00167     : id(_id)
00168 {
00169     DEBUGLOG("WvMoniker creating(%s).\n", id.cstr());
00170     reg = WvMonikerRegistry::find_reg(iid);
00171     if (reg)
00172         reg->add(id, func);
00173 }
00174 
00175 
00176 WvMonikerBase::~WvMonikerBase()
00177 {
00178     DEBUGLOG("WvMoniker destroying(%s).\n", id.cstr());
00179     if (reg)
00180     {
00181         reg->del(id);
00182         WVRELEASE(reg);
00183     }
00184 }
00185 
00186 
00187 void *wvcreate(const UUID &iid, WvStringParm moniker)
00188 {
00189     assert(!moniker.isnull());
00190     WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(iid);
00191     if (reg)
00192     {
00193         void *ret = reg->create(moniker);
00194         WVRELEASE(reg);
00195         return ret;
00196     }
00197     else
00198         return NULL;
00199 }

Generated on Mon Feb 5 10:54:29 2007 for WvStreams by  doxygen 1.5.1