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

wvmoniker.cc

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

Generated on Sat Feb 21 21:05:30 2004 for WvStreams by doxygen 1.3.5