1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsComponentManagerUtils_h__
8 #define nsComponentManagerUtils_h__
9 
10 #include "nscore.h"
11 #include "nsCOMPtr.h"
12 
13 #include "nsIFactory.h"
14 
15 
16 nsresult CallCreateInstance(const nsCID& aClass, nsISupports* aDelegate,
17                             const nsIID& aIID, void** aResult);
18 
19 nsresult CallCreateInstance(const char* aContractID, nsISupports* aDelegate,
20                             const nsIID& aIID, void** aResult);
21 
22 nsresult CallGetClassObject(const nsCID& aClass, const nsIID& aIID,
23                             void** aResult);
24 
25 nsresult CallGetClassObject(const char* aContractID, const nsIID& aIID,
26                             void** aResult);
27 
28 
29 class MOZ_STACK_CLASS nsCreateInstanceByCID final : public nsCOMPtr_helper
30 {
31 public:
nsCreateInstanceByCID(const nsCID & aCID,nsresult * aErrorPtr)32   nsCreateInstanceByCID(const nsCID& aCID, nsresult* aErrorPtr)
33     : mCID(aCID)
34     , mErrorPtr(aErrorPtr)
35   {
36   }
37 
38   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const
39     override;
40 
41 private:
42   const nsCID&    mCID;
43   nsresult*       mErrorPtr;
44 };
45 
46 class MOZ_STACK_CLASS nsCreateInstanceByContractID final : public nsCOMPtr_helper
47 {
48 public:
nsCreateInstanceByContractID(const char * aContractID,nsresult * aErrorPtr)49   nsCreateInstanceByContractID(const char* aContractID, nsresult* aErrorPtr)
50     : mContractID(aContractID)
51     , mErrorPtr(aErrorPtr)
52   {
53   }
54 
55   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const override;
56 
57 private:
58   const char*   mContractID;
59   nsresult*     mErrorPtr;
60 };
61 
62 class MOZ_STACK_CLASS nsCreateInstanceFromFactory final : public nsCOMPtr_helper
63 {
64 public:
nsCreateInstanceFromFactory(nsIFactory * aFactory,nsresult * aErrorPtr)65   nsCreateInstanceFromFactory(nsIFactory* aFactory, nsresult* aErrorPtr)
66     : mFactory(aFactory)
67     , mErrorPtr(aErrorPtr)
68   {
69   }
70 
71   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const override;
72 
73 private:
74   nsIFactory* MOZ_NON_OWNING_REF mFactory;
75   nsresult*     mErrorPtr;
76 };
77 
78 
79 inline const nsCreateInstanceByCID
80 do_CreateInstance(const nsCID& aCID, nsresult* aError = 0)
81 {
82   return nsCreateInstanceByCID(aCID, aError);
83 }
84 
85 inline const nsCreateInstanceByContractID
86 do_CreateInstance(const char* aContractID, nsresult* aError = 0)
87 {
88   return nsCreateInstanceByContractID(aContractID, aError);
89 }
90 
91 inline const nsCreateInstanceFromFactory
92 do_CreateInstance(nsIFactory* aFactory, nsresult* aError = 0)
93 {
94   return nsCreateInstanceFromFactory(aFactory, aError);
95 }
96 
97 
98 class MOZ_STACK_CLASS nsGetClassObjectByCID final : public nsCOMPtr_helper
99 {
100 public:
nsGetClassObjectByCID(const nsCID & aCID,nsresult * aErrorPtr)101   nsGetClassObjectByCID(const nsCID& aCID, nsresult* aErrorPtr)
102     : mCID(aCID)
103     , mErrorPtr(aErrorPtr)
104   {
105   }
106 
107   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const override;
108 
109 private:
110   const nsCID&    mCID;
111   nsresult*       mErrorPtr;
112 };
113 
114 class MOZ_STACK_CLASS nsGetClassObjectByContractID final : public nsCOMPtr_helper
115 {
116 public:
nsGetClassObjectByContractID(const char * aContractID,nsresult * aErrorPtr)117   nsGetClassObjectByContractID(const char* aContractID, nsresult* aErrorPtr)
118     : mContractID(aContractID)
119     , mErrorPtr(aErrorPtr)
120   {
121   }
122 
123   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const override;
124 
125 private:
126   const char*   mContractID;
127   nsresult*     mErrorPtr;
128 };
129 
130 /**
131  * do_GetClassObject can be used to improve performance of callers
132  * that call |CreateInstance| many times.  They can cache the factory
133  * and call do_CreateInstance or CallCreateInstance with the cached
134  * factory rather than having the component manager retrieve it every
135  * time.
136  */
137 inline const nsGetClassObjectByCID
138 do_GetClassObject(const nsCID& aCID, nsresult* aError = 0)
139 {
140   return nsGetClassObjectByCID(aCID, aError);
141 }
142 
143 inline const nsGetClassObjectByContractID
144 do_GetClassObject(const char* aContractID, nsresult* aError = 0)
145 {
146   return nsGetClassObjectByContractID(aContractID, aError);
147 }
148 
149 // type-safe shortcuts for calling |CreateInstance|
150 template<class DestinationType>
151 inline nsresult
CallCreateInstance(const nsCID & aClass,nsISupports * aDelegate,DestinationType ** aDestination)152 CallCreateInstance(const nsCID& aClass,
153                    nsISupports* aDelegate,
154                    DestinationType** aDestination)
155 {
156   NS_PRECONDITION(aDestination, "null parameter");
157 
158   return CallCreateInstance(aClass, aDelegate,
159                             NS_GET_TEMPLATE_IID(DestinationType),
160                             reinterpret_cast<void**>(aDestination));
161 }
162 
163 template<class DestinationType>
164 inline nsresult
CallCreateInstance(const nsCID & aClass,DestinationType ** aDestination)165 CallCreateInstance(const nsCID& aClass, DestinationType** aDestination)
166 {
167   NS_PRECONDITION(aDestination, "null parameter");
168 
169   return CallCreateInstance(aClass, nullptr,
170                             NS_GET_TEMPLATE_IID(DestinationType),
171                             reinterpret_cast<void**>(aDestination));
172 }
173 
174 template<class DestinationType>
175 inline nsresult
CallCreateInstance(const char * aContractID,nsISupports * aDelegate,DestinationType ** aDestination)176 CallCreateInstance(const char* aContractID,
177                    nsISupports* aDelegate,
178                    DestinationType** aDestination)
179 {
180   NS_PRECONDITION(aContractID, "null parameter");
181   NS_PRECONDITION(aDestination, "null parameter");
182 
183   return CallCreateInstance(aContractID,
184                             aDelegate,
185                             NS_GET_TEMPLATE_IID(DestinationType),
186                             reinterpret_cast<void**>(aDestination));
187 }
188 
189 template<class DestinationType>
190 inline nsresult
CallCreateInstance(const char * aContractID,DestinationType ** aDestination)191 CallCreateInstance(const char* aContractID, DestinationType** aDestination)
192 {
193   NS_PRECONDITION(aContractID, "null parameter");
194   NS_PRECONDITION(aDestination, "null parameter");
195 
196   return CallCreateInstance(aContractID, nullptr,
197                             NS_GET_TEMPLATE_IID(DestinationType),
198                             reinterpret_cast<void**>(aDestination));
199 }
200 
201 template<class DestinationType>
202 inline nsresult
CallCreateInstance(nsIFactory * aFactory,nsISupports * aDelegate,DestinationType ** aDestination)203 CallCreateInstance(nsIFactory* aFactory,
204                    nsISupports* aDelegate,
205                    DestinationType** aDestination)
206 {
207   NS_PRECONDITION(aFactory, "null parameter");
208   NS_PRECONDITION(aDestination, "null parameter");
209 
210   return aFactory->CreateInstance(aDelegate,
211                                   NS_GET_TEMPLATE_IID(DestinationType),
212                                   reinterpret_cast<void**>(aDestination));
213 }
214 
215 template<class DestinationType>
216 inline nsresult
CallCreateInstance(nsIFactory * aFactory,DestinationType ** aDestination)217 CallCreateInstance(nsIFactory* aFactory, DestinationType** aDestination)
218 {
219   NS_PRECONDITION(aFactory, "null parameter");
220   NS_PRECONDITION(aDestination, "null parameter");
221 
222   return aFactory->CreateInstance(nullptr,
223                                   NS_GET_TEMPLATE_IID(DestinationType),
224                                   reinterpret_cast<void**>(aDestination));
225 }
226 
227 template<class DestinationType>
228 inline nsresult
CallGetClassObject(const nsCID & aClass,DestinationType ** aDestination)229 CallGetClassObject(const nsCID& aClass, DestinationType** aDestination)
230 {
231   NS_PRECONDITION(aDestination, "null parameter");
232 
233   return CallGetClassObject(aClass, NS_GET_TEMPLATE_IID(DestinationType),
234                             reinterpret_cast<void**>(aDestination));
235 }
236 
237 template<class DestinationType>
238 inline nsresult
CallGetClassObject(const char * aContractID,DestinationType ** aDestination)239 CallGetClassObject(const char* aContractID, DestinationType** aDestination)
240 {
241   NS_PRECONDITION(aDestination, "null parameter");
242 
243   return CallGetClassObject(aContractID, NS_GET_TEMPLATE_IID(DestinationType),
244                             reinterpret_cast<void**>(aDestination));
245 }
246 
247 #endif /* nsComponentManagerUtils_h__ */
248