00001
00002
00003
00004
00005
00006
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
00106 reg = new WvMonikerRegistry(iid);
00107 regs->add(reg, true);
00108 reg->addRef();
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
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
00149
00150 regs->remove(this);
00151 if (regs->isempty())
00152 {
00153 delete regs;
00154 regs = NULL;
00155 }
00156 return 0;
00157 }
00158
00159
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 }