Make WvStreams compile with gcc 4.4.
[wvstreams.git] / utils / wvmoniker.cc
blob4475830057926994532ecc7e3387d9aeaed7d35c
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>
12 #include "wvscatterhash.h"
14 #if 0
15 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args)
16 #else
17 #ifndef _MSC_VER
18 # define DEBUGLOG(fmt, args...)
19 #else // MS Visual C++ doesn't support varags preproc macros
20 # define DEBUGLOG
21 #endif
22 #endif
25 static unsigned WvHash(const UUID &_uuid)
27 unsigned val = 0;
28 unsigned int *uuid = (unsigned int *)&_uuid;
29 int max = sizeof(UUID)/sizeof(*uuid);
31 for (int count = 0; count < max; count++)
32 val += uuid[count];
34 return val;
38 DeclareWvScatterDict(WvMonikerRegistry, UUID, reg_iid);
39 static WvMonikerRegistryDict *regs;
43 WvMonikerRegistry::WvMonikerRegistry(const UUID &iid)
44 : reg_iid(iid)
46 DEBUGLOG("WvMonikerRegistry creating.\n");
47 refcount = 0;
51 WvMonikerRegistry::~WvMonikerRegistry()
53 DEBUGLOG("WvMonikerRegistry destroying.\n");
57 void WvMonikerRegistry::add(WvStringParm id, WvMonikerCreateFunc *func,
58 const bool override)
60 DEBUGLOG("WvMonikerRegistry register(%s).\n", id.cstr());
61 if (!override) {
62 RegistrationList::Iter i(list);
63 for (i.rewind(); i.next(); )
64 assert(i.ptr()->id != id); //no duplicates without override
66 list.prepend(new Registration(id, func), true);
70 void WvMonikerRegistry::del(WvStringParm id)
72 DEBUGLOG("WvMonikerRegistry unregister(%s).\n", id.cstr());
73 RegistrationList::Iter i(list);
74 for (i.rewind(); i.next(); )
76 if (i.ptr()->id == id) {
77 i.unlink();
78 return;
82 //We should never get here, as we should never be removing elements which don't exist
83 assert(false);
87 void *WvMonikerRegistry::create(WvStringParm _s, IObject *obj)
89 WvString t(_s);
90 WvString s(trim_string(t.edit()));
92 char *cptr = strchr(s.edit(), ':');
93 if (cptr)
94 *cptr++ = 0;
95 else
96 cptr = (char*)"";
98 DEBUGLOG("WvMonikerRegistry create object ('%s' '%s').\n", s.cstr(), cptr);
100 RegistrationList::Iter i(list);
101 for (i.rewind(); i.next(); )
103 if (i.ptr()->id == s)
104 return i.ptr()->func(cptr, obj);
107 return NULL;
111 WvMonikerRegistry *WvMonikerRegistry::find_reg(const UUID &iid)
113 DEBUGLOG("WvMonikerRegistry find_reg.\n");
115 if (!regs)
116 regs = new WvMonikerRegistryDict(10);
118 WvMonikerRegistry *reg = (*regs)[iid];
120 if (!reg)
122 // we have to make one!
123 reg = new WvMonikerRegistry(iid);
124 regs->add(reg, true);
125 reg->addRef(); // one reference for being in the list at all
128 reg->addRef();
129 return reg;
133 IObject *WvMonikerRegistry::getInterface(const UUID &uuid)
135 #if 0
136 if (uuid.equals(IObject_IID))
138 addRef();
139 return this;
141 #endif
143 // we don't really support any interfaces for now.
145 return 0;
149 unsigned int WvMonikerRegistry::addRef()
151 DEBUGLOG("WvMonikerRegistry addRef.\n");
152 return ++refcount;
156 unsigned int WvMonikerRegistry::release()
158 DEBUGLOG("WvMonikerRegistry release.\n");
160 if (--refcount > 1)
161 return refcount;
163 if (refcount == 1)
165 // the list has one reference to us, but it's no longer needed.
166 // Note: remove() will delete this object!
167 regs->remove(this);
168 if (regs->isempty())
170 delete regs;
171 regs = NULL;
173 return 0;
176 /* protect against re-entering the destructor */
177 refcount = 1;
178 delete this;
179 return 0;
183 WvMonikerBase::WvMonikerBase(const UUID &iid, WvStringParm _id,
184 WvMonikerCreateFunc *func, const bool override)
185 : id(_id)
187 DEBUGLOG("WvMoniker creating(%s).\n", id.cstr());
188 reg = WvMonikerRegistry::find_reg(iid);
189 if (reg)
190 reg->add(id, func, override);
194 WvMonikerBase::~WvMonikerBase()
196 DEBUGLOG("WvMoniker destroying(%s).\n", id.cstr());
197 if (reg)
199 reg->del(id);
200 WVRELEASE(reg);
205 void *wvcreate(const UUID &iid, WvStringParm moniker, IObject *obj)
207 assert(!moniker.isnull());
208 // fprintf(stderr, "wvcreate: Looking for '%s'\n", moniker.cstr());
209 WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(iid);
210 if (reg)
212 void *ret = reg->create(moniker, obj);
213 WVRELEASE(reg);
214 return ret;
216 else
217 return NULL;