VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/components/nsStaticComponentLoader.cpp

Last change on this file was 3175, checked in by vboxsync, 18 years ago

XPCOM: Suppressed GCC 4 warnings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org Code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "nsStaticComponent.h"
39#include "nsIComponentLoader.h"
40#include "nsVoidArray.h"
41#include "pldhash.h"
42#include NEW_H
43#include <stdio.h>
44
45struct StaticModuleInfo : public PLDHashEntryHdr {
46 nsStaticModuleInfo info;
47 nsCOMPtr<nsIModule> module;
48};
49
50class nsStaticComponentLoader : public nsIComponentLoader
51{
52public:
53 NS_DECL_ISUPPORTS
54 NS_DECL_NSICOMPONENTLOADER
55
56 nsStaticComponentLoader() :
57 mAutoRegistered(PR_FALSE), mLoadedInfo(PR_FALSE) {
58 }
59
60 static NS_HIDDEN_(PLDHashOperator) PR_CALLBACK
61 info_RegisterSelf(PLDHashTable *table, PLDHashEntryHdr *hdr,
62 PRUint32 number, void *arg);
63
64private:
65 ~nsStaticComponentLoader() {
66 if (mInfoHash.ops)
67 PL_DHashTableFinish(&mInfoHash);
68 }
69
70protected:
71 nsresult GetModuleInfo();
72 nsresult GetInfoFor(const char *aLocation, StaticModuleInfo **retval);
73
74 PRBool mAutoRegistered;
75 PRBool mLoadedInfo;
76 nsCOMPtr<nsIComponentManager> mComponentMgr;
77 PLDHashTable mInfoHash;
78 static PLDHashTableOps sInfoHashOps;
79 nsVoidArray mDeferredComponents;
80};
81
82PR_STATIC_CALLBACK(void)
83info_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
84{
85 StaticModuleInfo *info = NS_STATIC_CAST(StaticModuleInfo *, entry);
86 info->module = 0;
87 info->~StaticModuleInfo();
88}
89
90PR_STATIC_CALLBACK(PRBool)
91info_InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key)
92{
93 // Construct so that our nsCOMPtr is zeroed, etc.
94 new (NS_STATIC_CAST(void *, entry)) StaticModuleInfo();
95 return PR_TRUE;
96}
97
98/* static */ PLDHashTableOps nsStaticComponentLoader::sInfoHashOps = {
99 PL_DHashAllocTable, PL_DHashFreeTable,
100 PL_DHashGetKeyStub, PL_DHashStringKey, PL_DHashMatchStringKey,
101 PL_DHashMoveEntryStub, info_ClearEntry,
102 PL_DHashFinalizeStub, info_InitEntry
103};
104
105NS_IMPL_THREADSAFE_ISUPPORTS1(nsStaticComponentLoader, nsIComponentLoader)
106
107NS_COM NSGetStaticModuleInfoFunc NSGetStaticModuleInfo;
108
109nsresult
110nsStaticComponentLoader::GetModuleInfo()
111{
112 if (mLoadedInfo)
113 return NS_OK;
114
115 if (!mInfoHash.ops) { // creation failed in init, why are we here?
116 NS_WARNING("operating on uninitialized static component loader");
117 return NS_ERROR_NOT_INITIALIZED;
118 }
119
120 if (! NSGetStaticModuleInfo) {
121 // We're a static build with no static modules to
122 // register. This can happen in shared uses (such as the GRE)
123 return NS_OK;
124 }
125
126 nsStaticModuleInfo *infoList;
127 PRUint32 count;
128 nsresult rv;
129 if (NS_FAILED(rv = (*NSGetStaticModuleInfo)(&infoList, &count)))
130 return rv;
131 for (PRUint32 i = 0; i < count; i++) {
132 StaticModuleInfo *info =
133 NS_STATIC_CAST(StaticModuleInfo *,
134 PL_DHashTableOperate(&mInfoHash, infoList[i].name,
135 PL_DHASH_ADD));
136 if (!info)
137 return NS_ERROR_OUT_OF_MEMORY;
138 info->info = infoList[i];
139 }
140
141 mLoadedInfo = PR_TRUE;
142 return NS_OK;
143}
144
145nsresult
146nsStaticComponentLoader::GetInfoFor(const char *aLocation,
147 StaticModuleInfo **retval)
148{
149 nsresult rv;
150 if (NS_FAILED(rv = GetModuleInfo()))
151 return rv;
152
153 StaticModuleInfo *info =
154 NS_STATIC_CAST(StaticModuleInfo *,
155 PL_DHashTableOperate(&mInfoHash, aLocation,
156 PL_DHASH_LOOKUP));
157
158 if (PL_DHASH_ENTRY_IS_FREE(info))
159 return NS_ERROR_FACTORY_NOT_REGISTERED;
160
161 if (!info->module) {
162 rv = info->info.getModule(mComponentMgr, nsnull,
163 getter_AddRefs(info->module));
164#ifdef DEBUG
165 fprintf(stderr, "nSCL: GetInfoFor(\"%s\"): %x\n", aLocation, rv);
166#endif
167 if (NS_FAILED(rv))
168 return rv;
169 }
170
171 *retval = info;
172 return NS_OK;
173}
174
175NS_IMETHODIMP
176nsStaticComponentLoader::Init(nsIComponentManager *mgr, nsISupports *aReg)
177{
178 mComponentMgr = mgr;
179 if (!PL_DHashTableInit(&mInfoHash, &sInfoHashOps, nsnull,
180 sizeof(StaticModuleInfo), 1024)) {
181 mInfoHash.ops = nsnull;
182 return NS_ERROR_OUT_OF_MEMORY;
183 }
184 return NS_OK;
185}
186
187PLDHashOperator PR_CALLBACK
188nsStaticComponentLoader::info_RegisterSelf(PLDHashTable *table,
189 PLDHashEntryHdr *hdr,
190 PRUint32 number, void *arg)
191{
192 nsStaticComponentLoader *loader = NS_STATIC_CAST(nsStaticComponentLoader *,
193 arg);
194 nsIComponentManager *mgr = loader->mComponentMgr;
195 StaticModuleInfo *info = NS_STATIC_CAST(StaticModuleInfo *, hdr);
196
197 nsresult rv;
198 if (!info->module) {
199 rv = info->info.getModule(mgr, nsnull, getter_AddRefs(info->module));
200#ifdef DEBUG
201 fprintf(stderr, "nSCL: getModule(\"%s\"): %x\n", info->info.name, rv);
202#endif
203 if (NS_FAILED(rv))
204 return PL_DHASH_NEXT; // oh well.
205 }
206
207 rv = info->module->RegisterSelf(mgr, nsnull, info->info.name,
208 staticComponentType);
209#ifdef DEBUG
210 fprintf(stderr, "nSCL: autoreg of \"%s\": %x\n", info->info.name, rv);
211#endif
212
213 if (rv == NS_ERROR_FACTORY_REGISTER_AGAIN)
214 loader->mDeferredComponents.AppendElement(info);
215
216 return PL_DHASH_NEXT;
217}
218
219NS_IMETHODIMP
220nsStaticComponentLoader::AutoRegisterComponents(PRInt32 when, nsIFile *dir)
221{
222 if (mAutoRegistered)
223 return NS_OK;
224
225 // if a directory has been explicitly specified, then return early. we
226 // don't load static components from disk ;)
227 if (dir)
228 return NS_OK;
229
230 nsresult rv;
231 if (NS_FAILED(rv = GetModuleInfo()))
232 return rv;
233
234 PL_DHashTableEnumerate(&mInfoHash, info_RegisterSelf, this);
235
236 mAutoRegistered = PR_TRUE;
237 return NS_OK;
238}
239
240NS_IMETHODIMP
241nsStaticComponentLoader::AutoUnregisterComponent(PRInt32 when,
242 nsIFile *component,
243 PRBool *retval)
244{
245 *retval = PR_FALSE;
246 return NS_OK;
247}
248
249NS_IMETHODIMP
250nsStaticComponentLoader::AutoRegisterComponent(PRInt32 when, nsIFile *component,
251 PRBool *retval)
252{
253 *retval = PR_FALSE;
254 return NS_OK;
255}
256
257NS_IMETHODIMP
258nsStaticComponentLoader::RegisterDeferredComponents(PRInt32 when,
259 PRBool *aRegistered)
260{
261 *aRegistered = PR_FALSE;
262 if (!mDeferredComponents.Count())
263 return NS_OK;
264
265 for (int i = mDeferredComponents.Count() - 1; i >= 0; i--) {
266 StaticModuleInfo *info = NS_STATIC_CAST(StaticModuleInfo *,
267 mDeferredComponents[i]);
268 nsresult rv = info->module->RegisterSelf(mComponentMgr, nsnull,
269 info->info.name,
270 staticComponentType);
271 if (rv != NS_ERROR_FACTORY_REGISTER_AGAIN) {
272 if (NS_SUCCEEDED(rv))
273 *aRegistered = PR_TRUE;
274 mDeferredComponents.RemoveElementAt(i);
275 }
276 }
277 return NS_OK;
278}
279
280NS_IMETHODIMP
281nsStaticComponentLoader::OnRegister(const nsCID &aCID, const char *aType,
282 const char *aClassName,
283 const char *aContractID,
284 const char *aLocation,
285 PRBool aReplace, PRBool aPersist)
286{
287 return NS_OK;
288}
289
290NS_IMETHODIMP
291nsStaticComponentLoader::UnloadAll(PRInt32 aWhen)
292{
293 return NS_OK;
294}
295
296NS_IMETHODIMP
297nsStaticComponentLoader::GetFactory(const nsCID &aCID, const char *aLocation,
298 const char *aType, nsIFactory **_retval)
299{
300 StaticModuleInfo *info;
301 nsresult rv;
302
303 if (NS_FAILED(rv = GetInfoFor(aLocation, &info)))
304 return rv;
305
306 return info->module->GetClassObject(mComponentMgr, aCID,
307 NS_GET_IID(nsIFactory),
308 (void **)_retval);
309}
310
311nsresult
312NS_NewStaticComponentLoader(nsIComponentLoader **retval)
313{
314 NS_IF_ADDREF(*retval = NS_STATIC_CAST(nsIComponentLoader *,
315 new nsStaticComponentLoader));
316 return *retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
317}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette