Fix compilation with old g++ 3.3.5 and debian-sarge.
[wvstreams.git] / utils / wvmoniker.cc
blobb1f5552fa7f666b4e7f67c5b21af112dba35e99e
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * Support for monikers, which are strings that you can pass to a magic
6 * factory to get objects supporting a particular interface. See wvmoniker.h.
7 */
8 #include "wvmonikerregistry.h"
9 #include "strutils.h"
10 #include <wvassert.h>
11 #include <stdio.h>
13 #if 0
14 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args)
15 #else
16 #ifndef _MSC_VER
17 # define DEBUGLOG(fmt, args...)
18 #else // MS Visual C++ doesn't support varags preproc macros
19 # define DEBUGLOG
20 #endif
21 #endif
24 static unsigned WvHash(const UUID &_uuid)
26 unsigned val = 0;
27 unsigned int *uuid = (unsigned int *)&_uuid;
28 int max = sizeof(UUID)/sizeof(*uuid);
30 for (int count = 0; count < max; count++)
31 val += uuid[count];
33 return val;
37 DeclareWvScatterDict(WvMonikerRegistry, UUID, reg_iid);
38 static WvMonikerRegistryDict *regs;
42 WvMonikerRegistry::WvMonikerRegistry(const UUID &iid)
43 : reg_iid(iid), dict(10)
45 DEBUGLOG("WvMonikerRegistry creating.\n");
46 refcount = 0;
50 WvMonikerRegistry::~WvMonikerRegistry()
52 DEBUGLOG("WvMonikerRegistry destroying.\n");
56 void WvMonikerRegistry::add(WvStringParm id, WvMonikerCreateFunc *func)
58 DEBUGLOG("WvMonikerRegistry register(%s).\n", id.cstr());
59 wvassert(!dict[id], id);
60 dict.add(new Registration(id, func), true);
64 void WvMonikerRegistry::del(WvStringParm id)
66 DEBUGLOG("WvMonikerRegistry unregister(%s).\n", id.cstr());
67 assert(dict[id]);
68 dict.remove(dict[id]);
72 void *WvMonikerRegistry::create(WvStringParm _s, IObject *obj)
74 WvString t(_s);
75 WvString s(trim_string(t.edit()));
77 char *cptr = strchr(s.edit(), ':');
78 if (cptr)
79 *cptr++ = 0;
80 else
81 cptr = (char*)"";
83 DEBUGLOG("WvMonikerRegistry create object ('%s' '%s').\n", s.cstr(), cptr);
85 Registration *r = dict[s];
86 if (r)
87 return r->func(cptr, obj);
88 else
89 return NULL;
93 WvMonikerRegistry *WvMonikerRegistry::find_reg(const UUID &iid)
95 DEBUGLOG("WvMonikerRegistry find_reg.\n");
97 if (!regs)
98 regs = new WvMonikerRegistryDict(10);
100 WvMonikerRegistry *reg = (*regs)[iid];
102 if (!reg)
104 // we have to make one!
105 reg = new WvMonikerRegistry(iid);
106 regs->add(reg, true);
107 reg->addRef(); // one reference for being in the list at all
110 reg->addRef();
111 return reg;
115 IObject *WvMonikerRegistry::getInterface(const UUID &uuid)
117 #if 0
118 if (uuid.equals(IObject_IID))
120 addRef();
121 return this;
123 #endif
125 // we don't really support any interfaces for now.
127 return 0;
131 unsigned int WvMonikerRegistry::addRef()
133 DEBUGLOG("WvMonikerRegistry addRef.\n");
134 return ++refcount;
138 unsigned int WvMonikerRegistry::release()
140 DEBUGLOG("WvMonikerRegistry release.\n");
142 if (--refcount > 1)
143 return refcount;
145 if (refcount == 1)
147 // the list has one reference to us, but it's no longer needed.
148 // Note: remove() will delete this object!
149 regs->remove(this);
150 if (regs->isempty())
152 delete regs;
153 regs = NULL;
155 return 0;
158 /* protect against re-entering the destructor */
159 refcount = 1;
160 delete this;
161 return 0;
165 WvMonikerBase::WvMonikerBase(const UUID &iid, WvStringParm _id,
166 WvMonikerCreateFunc *func)
167 : id(_id)
169 DEBUGLOG("WvMoniker creating(%s).\n", id.cstr());
170 reg = WvMonikerRegistry::find_reg(iid);
171 if (reg)
172 reg->add(id, func);
176 WvMonikerBase::~WvMonikerBase()
178 DEBUGLOG("WvMoniker destroying(%s).\n", id.cstr());
179 if (reg)
181 reg->del(id);
182 WVRELEASE(reg);
187 void *wvcreate(const UUID &iid, WvStringParm moniker, IObject *obj)
189 assert(!moniker.isnull());
190 // fprintf(stderr, "wvcreate: Looking for '%s'\n", moniker.cstr());
191 WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(iid);
192 if (reg)
194 void *ret = reg->create(moniker, obj);
195 WVRELEASE(reg);
196 return ret;
198 else
199 return NULL;