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