00001
00002
00003
00004
00005
00006
00007
00008 #include "wvmonikerregistry.h"
00009 #include "strutils.h"
00010 #include <wvassert.h>
00011 #include <stdio.h>
00012 #include "wvscatterhash.h"
00013
00014 #if 0
00015 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args)
00016 #else
00017 #ifndef _MSC_VER
00018 # define DEBUGLOG(fmt, args...)
00019 #else // MS Visual C++ doesn't support varags preproc macros
00020 # define DEBUGLOG
00021 #endif
00022 #endif
00023
00024
00025 static unsigned WvHash(const UUID &_uuid)
00026 {
00027 unsigned val = 0;
00028 unsigned int *uuid = (unsigned int *)&_uuid;
00029 int max = sizeof(UUID)/sizeof(*uuid);
00030
00031 for (int count = 0; count < max; count++)
00032 val += uuid[count];
00033
00034 return val;
00035 }
00036
00037
00038 DeclareWvScatterDict(WvMonikerRegistry, UUID, reg_iid);
00039 static WvMonikerRegistryDict *regs;
00040
00041
00042
00043 WvMonikerRegistry::WvMonikerRegistry(const UUID &iid)
00044 : reg_iid(iid)
00045 {
00046 DEBUGLOG("WvMonikerRegistry creating.\n");
00047 refcount = 0;
00048 }
00049
00050
00051 WvMonikerRegistry::~WvMonikerRegistry()
00052 {
00053 DEBUGLOG("WvMonikerRegistry destroying.\n");
00054 }
00055
00056
00057 void WvMonikerRegistry::add(WvStringParm id, WvMonikerCreateFunc *func,
00058 const bool override)
00059 {
00060 DEBUGLOG("WvMonikerRegistry register(%s).\n", id.cstr());
00061 if (!override) {
00062 RegistrationList::Iter i(list);
00063 for (i.rewind(); i.next(); )
00064 assert(i.ptr()->id != id);
00065 }
00066 list.prepend(new Registration(id, func), true);
00067 }
00068
00069
00070 void WvMonikerRegistry::del(WvStringParm id)
00071 {
00072 DEBUGLOG("WvMonikerRegistry unregister(%s).\n", id.cstr());
00073 RegistrationList::Iter i(list);
00074 for (i.rewind(); i.next(); )
00075 {
00076 if (i.ptr()->id == id) {
00077 i.unlink();
00078 return;
00079 }
00080 }
00081
00082
00083 assert(false);
00084 }
00085
00086
00087 void *WvMonikerRegistry::create(WvStringParm _s, IObject *obj)
00088 {
00089 WvString t(_s);
00090 WvString s(trim_string(t.edit()));
00091
00092 char *cptr = strchr(s.edit(), ':');
00093 if (cptr)
00094 *cptr++ = 0;
00095 else
00096 cptr = (char*)"";
00097
00098 DEBUGLOG("WvMonikerRegistry create object ('%s' '%s').\n", s.cstr(), cptr);
00099
00100 RegistrationList::Iter i(list);
00101 for (i.rewind(); i.next(); )
00102 {
00103 if (i.ptr()->id == s)
00104 return i.ptr()->func(cptr, obj);
00105 }
00106
00107 return NULL;
00108 }
00109
00110
00111 WvMonikerRegistry *WvMonikerRegistry::find_reg(const UUID &iid)
00112 {
00113 DEBUGLOG("WvMonikerRegistry find_reg.\n");
00114
00115 if (!regs)
00116 regs = new WvMonikerRegistryDict(10);
00117
00118 WvMonikerRegistry *reg = (*regs)[iid];
00119
00120 if (!reg)
00121 {
00122
00123 reg = new WvMonikerRegistry(iid);
00124 regs->add(reg, true);
00125 reg->addRef();
00126 }
00127
00128 reg->addRef();
00129 return reg;
00130 }
00131
00132
00133 IObject *WvMonikerRegistry::getInterface(const UUID &uuid)
00134 {
00135 #if 0
00136 if (uuid.equals(IObject_IID))
00137 {
00138 addRef();
00139 return this;
00140 }
00141 #endif
00142
00143
00144
00145 return 0;
00146 }
00147
00148
00149 unsigned int WvMonikerRegistry::addRef()
00150 {
00151 DEBUGLOG("WvMonikerRegistry addRef.\n");
00152 return ++refcount;
00153 }
00154
00155
00156 unsigned int WvMonikerRegistry::release()
00157 {
00158 DEBUGLOG("WvMonikerRegistry release.\n");
00159
00160 if (--refcount > 1)
00161 return refcount;
00162
00163 if (refcount == 1)
00164 {
00165
00166
00167 regs->remove(this);
00168 if (regs->isempty())
00169 {
00170 delete regs;
00171 regs = NULL;
00172 }
00173 return 0;
00174 }
00175
00176
00177 refcount = 1;
00178 delete this;
00179 return 0;
00180 }
00181
00182
00183 WvMonikerBase::WvMonikerBase(const UUID &iid, WvStringParm _id,
00184 WvMonikerCreateFunc *func, const bool override)
00185 : id(_id)
00186 {
00187 DEBUGLOG("WvMoniker creating(%s).\n", id.cstr());
00188 reg = WvMonikerRegistry::find_reg(iid);
00189 if (reg)
00190 reg->add(id, func, override);
00191 }
00192
00193
00194 WvMonikerBase::~WvMonikerBase()
00195 {
00196 DEBUGLOG("WvMoniker destroying(%s).\n", id.cstr());
00197 if (reg)
00198 {
00199 reg->del(id);
00200 WVRELEASE(reg);
00201 }
00202 }
00203
00204
00205 void *wvcreate(const UUID &iid, WvStringParm moniker, IObject *obj)
00206 {
00207 assert(!moniker.isnull());
00208
00209 WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(iid);
00210 if (reg)
00211 {
00212 void *ret = reg->create(moniker, obj);
00213 WVRELEASE(reg);
00214 return ret;
00215 }
00216 else
00217 return NULL;
00218 }