2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
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.
8 #include "wvmonikerregistry.h"
12 #include "wvscatterhash.h"
15 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args)
18 # define DEBUGLOG(fmt, args...)
19 #else // MS Visual C++ doesn't support varags preproc macros
25 static unsigned WvHash(const UUID
&_uuid
)
28 unsigned int *uuid
= (unsigned int *)&_uuid
;
29 int max
= sizeof(UUID
)/sizeof(*uuid
);
31 for (int count
= 0; count
< max
; count
++)
38 DeclareWvScatterDict(WvMonikerRegistry
, UUID
, reg_iid
);
39 static WvMonikerRegistryDict
*regs
;
43 WvMonikerRegistry::WvMonikerRegistry(const UUID
&iid
)
46 DEBUGLOG("WvMonikerRegistry creating.\n");
51 WvMonikerRegistry::~WvMonikerRegistry()
53 DEBUGLOG("WvMonikerRegistry destroying.\n");
57 void WvMonikerRegistry::add(WvStringParm id
, WvMonikerCreateFunc
*func
,
60 DEBUGLOG("WvMonikerRegistry register(%s).\n", id
.cstr());
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
) {
82 //We should never get here, as we should never be removing elements which don't exist
87 void *WvMonikerRegistry::create(WvStringParm _s
, IObject
*obj
)
90 WvString
s(trim_string(t
.edit()));
92 char *cptr
= strchr(s
.edit(), ':');
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
);
111 WvMonikerRegistry
*WvMonikerRegistry::find_reg(const UUID
&iid
)
113 DEBUGLOG("WvMonikerRegistry find_reg.\n");
116 regs
= new WvMonikerRegistryDict(10);
118 WvMonikerRegistry
*reg
= (*regs
)[iid
];
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
133 IObject
*WvMonikerRegistry::getInterface(const UUID
&uuid
)
136 if (uuid
.equals(IObject_IID
))
143 // we don't really support any interfaces for now.
149 unsigned int WvMonikerRegistry::addRef()
151 DEBUGLOG("WvMonikerRegistry addRef.\n");
156 unsigned int WvMonikerRegistry::release()
158 DEBUGLOG("WvMonikerRegistry release.\n");
165 // the list has one reference to us, but it's no longer needed.
166 // Note: remove() will delete this object!
176 /* protect against re-entering the destructor */
183 WvMonikerBase::WvMonikerBase(const UUID
&iid
, WvStringParm _id
,
184 WvMonikerCreateFunc
*func
, const bool override
)
187 DEBUGLOG("WvMoniker creating(%s).\n", id
.cstr());
188 reg
= WvMonikerRegistry::find_reg(iid
);
190 reg
->add(id
, func
, override
);
194 WvMonikerBase::~WvMonikerBase()
196 DEBUGLOG("WvMoniker destroying(%s).\n", id
.cstr());
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
);
212 void *ret
= reg
->create(moniker
, obj
);