OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; tab-width: 4; 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) 1998 |
| 20 * the Initial Developer. All Rights Reserved. |
| 21 * |
| 22 * Contributor(s): |
| 23 * Benjamin Smedberg <benjamin@smedbergs.us> |
| 24 * |
| 25 * Alternatively, the contents of this file may be used under the terms of |
| 26 * either of the GNU General Public License Version 2 or later (the "GPL"), |
| 27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
| 28 * in which case the provisions of the GPL or the LGPL are applicable instead |
| 29 * of those above. If you wish to allow use of your version of this file only |
| 30 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 31 * use your version of this file under the terms of the MPL, indicate your |
| 32 * decision by deleting the provisions above and replace them with the notice |
| 33 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 34 * the provisions above, a recipient may use your version of this file under |
| 35 * the terms of any one of the MPL, the GPL or the LGPL. |
| 36 * |
| 37 * ***** END LICENSE BLOCK ***** */ |
| 38 |
| 39 #ifndef nsIGenericFactory_h___ |
| 40 #define nsIGenericFactory_h___ |
| 41 |
| 42 #include "nsIFactory.h" |
| 43 #include "nsIModule.h" |
| 44 #include "nsIClassInfo.h" |
| 45 |
| 46 class nsIFile; |
| 47 class nsIComponentManager; |
| 48 |
| 49 // {3bc97f01-ccdf-11d2-bab8-b548654461fc} |
| 50 #define NS_GENERICFACTORY_CID \ |
| 51 { 0x3bc97f01, 0xccdf, 0x11d2, \ |
| 52 { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } } |
| 53 |
| 54 // {3bc97f00-ccdf-11d2-bab8-b548654461fc} |
| 55 #define NS_IGENERICFACTORY_IID \ |
| 56 { 0x3bc97f00, 0xccdf, 0x11d2, \ |
| 57 { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } } |
| 58 |
| 59 #define NS_GENERICFACTORY_CONTRACTID "@mozilla.org/generic-factory;1" |
| 60 #define NS_GENERICFACTORY_CLASSNAME "Generic Factory" |
| 61 |
| 62 struct nsModuleComponentInfo; // forward declaration |
| 63 |
| 64 /** |
| 65 * Provides a Generic nsIFactory implementation that can be used by |
| 66 * DLLs with very simple factory needs. |
| 67 */ |
| 68 class nsIGenericFactory : public nsIFactory { |
| 69 public: |
| 70 NS_DEFINE_STATIC_IID_ACCESSOR(NS_IGENERICFACTORY_IID) |
| 71 |
| 72 NS_IMETHOD SetComponentInfo(const nsModuleComponentInfo *info) = 0; |
| 73 NS_IMETHOD GetComponentInfo(const nsModuleComponentInfo **infop) = 0; |
| 74 }; |
| 75 |
| 76 NS_COM_GLUE nsresult |
| 77 NS_NewGenericFactory(nsIGenericFactory **result, |
| 78 const nsModuleComponentInfo *info); |
| 79 |
| 80 |
| 81 /** Component Callbacks **/ |
| 82 |
| 83 /** |
| 84 * NSConstructorProcPtr |
| 85 * |
| 86 * This function will be used by the generic factory to create an |
| 87 * instance of the given CID. |
| 88 * |
| 89 * @param aOuter : Pointer to a component that wishes to be aggregated |
| 90 * in the resulting instance. This will be nsnull if no |
| 91 * aggregation is requested. |
| 92 * @param iid : The IID of the interface being requested in |
| 93 * the component which is being currently created. |
| 94 * @param result : [out] Pointer to the newly created instance, if successfu
l. |
| 95 * |
| 96 * @return NS_OK Component successfully created and the int
erface |
| 97 * being requested was successfully returned
in result. |
| 98 * NS_NOINTERFACE Interface not accessible. |
| 99 * NS_ERROR_NO_AGGREGATION if an 'outer' object is supplied, but the |
| 100 * component is not aggregatable. |
| 101 * NS_ERROR* Method failure. |
| 102 **/ |
| 103 typedef NS_CALLBACK(NSConstructorProcPtr)(nsISupports *aOuter, |
| 104 REFNSIID aIID, |
| 105 void **aResult); |
| 106 |
| 107 /** |
| 108 * NSRegisterSelfProcPtr |
| 109 * |
| 110 * One time registration call back. Allows you to perform registration |
| 111 * specific activity like adding yourself to a category. |
| 112 * |
| 113 * @param aCompMgr : The global component manager |
| 114 * @param aFile : Component File. This file must have an associated |
| 115 * loader and export the required symbols which this |
| 116 * loader defines. |
| 117 * @param aLoaderStr : Opaque loader specific string. This value is |
| 118 * passed into the nsIModule's registerSelf |
| 119 * callback and must be fowarded unmodified when |
| 120 * registering factories via their location. |
| 121 * @param aType : Component Type of CID aClass. This value is |
| 122 * passed into the nsIModule's registerSelf |
| 123 * callback and must be fowarded unmodified when |
| 124 * registering factories via their location. |
| 125 * @param aInfo : Pointer to array of nsModuleComponentInfo |
| 126 * |
| 127 * @param aInfo |
| 128 * @return NS_OK Registration was successful. |
| 129 * NS_ERROR* Method failure. |
| 130 **/ |
| 131 typedef NS_CALLBACK(NSRegisterSelfProcPtr)(nsIComponentManager *aCompMgr, |
| 132 nsIFile *aPath, |
| 133 const char *aLoaderStr, |
| 134 const char *aType, |
| 135 const nsModuleComponentInfo *aInfo); |
| 136 |
| 137 /** |
| 138 * NSUnregisterSelfProcPtr |
| 139 * |
| 140 * One time unregistration call back. Allows you to perform unregistration |
| 141 * specific activity like removing yourself from a category. |
| 142 * |
| 143 * @param aCompMgr : The global component manager |
| 144 * @param aFile : Component File. This file must have an associated |
| 145 * loader and export the required symbols which this |
| 146 * loader defines. |
| 147 * @param aLoaderStr : Opaque loader specific string. This value is |
| 148 * passed into the nsIModule's registerSelf |
| 149 * callback and must be fowarded unmodified when |
| 150 * registering factories via their location |
| 151 * @param aInfo : Pointer to array of nsModuleComponentInfo |
| 152 * |
| 153 * @param aInfo |
| 154 * @return NS_OK Registration was successful. |
| 155 * NS_ERROR* Method failure. |
| 156 |
| 157 **/ |
| 158 typedef NS_CALLBACK(NSUnregisterSelfProcPtr)(nsIComponentManager *aCompMgr, |
| 159 nsIFile *aPath, |
| 160 const char *aLoaderStr, |
| 161 const nsModuleComponentInfo *aInfo)
; |
| 162 |
| 163 /** |
| 164 * NSFactoryDestructorProcPtr |
| 165 * |
| 166 * This function will be called when the factory is being destroyed. |
| 167 * |
| 168 **/ |
| 169 typedef NS_CALLBACK(NSFactoryDestructorProcPtr)(void); |
| 170 |
| 171 |
| 172 /** |
| 173 * NSGetInterfacesProcPtr |
| 174 * |
| 175 * This function is used to implement class info. |
| 176 * |
| 177 * Get an ordered list of the interface ids that instances of the class |
| 178 * promise to implement. Note that nsISupports is an implicit member |
| 179 * of any such list and need not be included. |
| 180 * |
| 181 * Should set *count = 0 and *array = null and return NS_OK if getting the |
| 182 * list is not supported. |
| 183 * |
| 184 * @see nsIClassInfo.idl |
| 185 **/ |
| 186 typedef NS_CALLBACK(NSGetInterfacesProcPtr)(PRUint32 *countp, |
| 187 nsIID* **array); |
| 188 |
| 189 /** |
| 190 * NSGetLanguageHelperProcPtr |
| 191 * |
| 192 * This function is used to implement class info. |
| 193 * |
| 194 * Get a language mapping specific helper object that may assist in using |
| 195 * objects of this class in a specific lanaguage. For instance, if asked |
| 196 * for the helper for nsIProgrammingLanguage::JAVASCRIPT this might return |
| 197 * an object that can be QI'd into the nsIXPCScriptable interface to assist |
| 198 * XPConnect in supplying JavaScript specific behavior to callers of the |
| 199 * instance object. |
| 200 * |
| 201 * @see: nsIClassInfo.idl, nsIProgrammingLanguage.idl |
| 202 * |
| 203 * Should return null if no helper available for given language. |
| 204 **/ |
| 205 typedef NS_CALLBACK(NSGetLanguageHelperProcPtr)(PRUint32 language, |
| 206 nsISupports **helper); |
| 207 |
| 208 /** |
| 209 * nsModuleComponentInfo |
| 210 * |
| 211 * Use this type to define a list of module component info to pass to |
| 212 * NS_NewGenericModule. |
| 213 * |
| 214 * @param mDescription : Class Name of given object |
| 215 * @param mCID : CID of given object |
| 216 * @param mContractID : Contract ID of given object |
| 217 * @param mConstructor : Constructor of given object |
| 218 * @param mRegisterSelfProc : (optional) Registration Callback |
| 219 * @param mUnregisterSelfProc : (optional) Unregistration Callback |
| 220 * @param mFactoryDestructor : (optional) Destruction Callback |
| 221 * @param mGetInterfacesProc : (optional) Interfaces Callback |
| 222 * @param mGetLanguageHelperProc : (optional) Language Helper Callback |
| 223 * @param mClassInfoGlobal : (optional) Global Class Info of given object |
| 224 * @param mFlags : (optional) Class Info Flags @see nsIClassInfo
|
| 225 * |
| 226 * E.g.: |
| 227 * static nsModuleComponentInfo components[] = { ... }; |
| 228 * |
| 229 * See xpcom/sample/nsSampleModule.cpp for more info. |
| 230 */ |
| 231 struct nsModuleComponentInfo { |
| 232 const char* mDescription; |
| 233 nsCID mCID; |
| 234 const char* mContractID; |
| 235 NSConstructorProcPtr mConstructor; |
| 236 NSRegisterSelfProcPtr mRegisterSelfProc; |
| 237 NSUnregisterSelfProcPtr mUnregisterSelfProc; |
| 238 NSFactoryDestructorProcPtr mFactoryDestructor; |
| 239 NSGetInterfacesProcPtr mGetInterfacesProc; |
| 240 NSGetLanguageHelperProcPtr mGetLanguageHelperProc; |
| 241 nsIClassInfo ** mClassInfoGlobal; |
| 242 PRUint32 mFlags; |
| 243 }; |
| 244 |
| 245 |
| 246 /** Module Callbacks **/ |
| 247 |
| 248 |
| 249 /** |
| 250 * nsModuleConstructorProc |
| 251 * |
| 252 * This function is called when the module is first being constructed. |
| 253 * @param self module which is being constructed. |
| 254 * |
| 255 * @return NS_OK Construction successful. |
| 256 * NS_ERROR* Method failure which will result in module not being |
| 257 * loaded. |
| 258 **/ |
| 259 typedef nsresult (PR_CALLBACK *nsModuleConstructorProc) (nsIModule *self); |
| 260 |
| 261 |
| 262 /** |
| 263 * nsModuleDestructorProc |
| 264 * |
| 265 * This function is called when the module is being destroyed. |
| 266 * @param self module which is being destroyed. |
| 267 * |
| 268 **/ |
| 269 typedef void (PR_CALLBACK *nsModuleDestructorProc) (nsIModule *self); |
| 270 |
| 271 /** |
| 272 * nsModuleInfo |
| 273 * |
| 274 * Use this structure to define meta-information about the module |
| 275 * itself, including the name, its components, and an optional |
| 276 * module-level initialization or shutdown routine. |
| 277 * |
| 278 * @param mVersion : Module Info Version |
| 279 * @param mModuleName : Module Name |
| 280 * @param mComponents : Array of Components |
| 281 * @param mCount : Count of mComponents |
| 282 * @param mCtor : Module user defined constructor |
| 283 * @param mDtor : Module user defined destructor |
| 284 * |
| 285 **/ |
| 286 |
| 287 struct nsModuleInfo { |
| 288 PRUint32 mVersion; |
| 289 const char* mModuleName; |
| 290 const nsModuleComponentInfo *mComponents; |
| 291 PRUint32 mCount; |
| 292 nsModuleConstructorProc mCtor; |
| 293 nsModuleDestructorProc mDtor; |
| 294 }; |
| 295 |
| 296 /** |
| 297 * Rev this if you change the nsModuleInfo, and are worried about |
| 298 * binary compatibility. (Ostensibly fix NS_NewGenericModule2() to deal |
| 299 * with older rev's at the same time.) |
| 300 */ |
| 301 #define NS_MODULEINFO_VERSION 0x00015000UL // 1.5 |
| 302 |
| 303 /** |
| 304 * Create a new generic module. Use the NS_IMPL_NSGETMODULE macro, or |
| 305 * one of its relatives, rather than using this directly. |
| 306 */ |
| 307 NS_COM_GLUE nsresult |
| 308 NS_NewGenericModule2(nsModuleInfo const *info, nsIModule* *result); |
| 309 |
| 310 /** |
| 311 * Obsolete. Use NS_NewGenericModule2() instead. |
| 312 */ |
| 313 NS_COM_GLUE nsresult |
| 314 NS_NewGenericModule(const char* moduleName, |
| 315 PRUint32 componentCount, |
| 316 nsModuleComponentInfo* components, |
| 317 nsModuleDestructorProc dtor, |
| 318 nsIModule* *result); |
| 319 |
| 320 #if defined(XPCOM_TRANSLATE_NSGM_ENTRY_POINT) |
| 321 # define NSGETMODULE_ENTRY_POINT(_name) NS_VISIBILITY_HIDDEN nsresult _name##_
NSGetModule |
| 322 #else |
| 323 # define NSGETMODULE_ENTRY_POINT(_name) extern "C" NS_EXPORT nsresult NSGetMod
ule |
| 324 #endif |
| 325 |
| 326 /** |
| 327 * Ease of use Macros which define NSGetModule for your component. |
| 328 * See xpcom/sample/nsSampleModule.cpp for more info. |
| 329 * |
| 330 **/ |
| 331 |
| 332 #define NS_IMPL_NSGETMODULE(_name, _components) \ |
| 333 NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, nsnull, nsnull) |
| 334 |
| 335 #define NS_IMPL_NSGETMODULE_WITH_CTOR(_name, _components, _ctor) \ |
| 336 NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, _ctor, nsnull) |
| 337 |
| 338 #define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _dtor) \ |
| 339 NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, nsnull, _dtor) |
| 340 |
| 341 #define NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, _ctor, _dtor) \ |
| 342 static nsModuleInfo const kModuleInfo = { \ |
| 343 NS_MODULEINFO_VERSION, \ |
| 344 (#_name), \ |
| 345 (_components), \ |
| 346 (sizeof(_components) / sizeof(_components[0])), \ |
| 347 (_ctor), \ |
| 348 (_dtor) \ |
| 349 }; \ |
| 350 NSGETMODULE_ENTRY_POINT(_name) \ |
| 351 (nsIComponentManager *servMgr, \ |
| 352 nsIFile* location, \ |
| 353 nsIModule** result) \ |
| 354 { \ |
| 355 return NS_NewGenericModule2(&kModuleInfo, result); \ |
| 356 } |
| 357 |
| 358 //////////////////////////////////////////////////////////////////////////////// |
| 359 |
| 360 #define NS_GENERIC_FACTORY_CONSTRUCTOR(_InstanceClass) \ |
| 361 static NS_IMETHODIMP \ |
| 362 _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ |
| 363 void **aResult) \ |
| 364 { \ |
| 365 nsresult rv; \ |
| 366 \ |
| 367 _InstanceClass * inst; \ |
| 368 \ |
| 369 *aResult = NULL; \ |
| 370 if (NULL != aOuter) { \ |
| 371 rv = NS_ERROR_NO_AGGREGATION; \ |
| 372 return rv; \ |
| 373 } \ |
| 374 \ |
| 375 NS_NEWXPCOM(inst, _InstanceClass); \ |
| 376 if (NULL == inst) { \ |
| 377 rv = NS_ERROR_OUT_OF_MEMORY; \ |
| 378 return rv; \ |
| 379 } \ |
| 380 NS_ADDREF(inst); \ |
| 381 rv = inst->QueryInterface(aIID, aResult); \ |
| 382 NS_RELEASE(inst); \ |
| 383 \ |
| 384 return rv; \ |
| 385 } \ |
| 386 |
| 387 |
| 388 #define NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(_InstanceClass, _InitMethod) \ |
| 389 static NS_IMETHODIMP \ |
| 390 _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ |
| 391 void **aResult) \ |
| 392 { \ |
| 393 nsresult rv; \ |
| 394 \ |
| 395 _InstanceClass * inst; \ |
| 396 \ |
| 397 *aResult = NULL; \ |
| 398 if (NULL != aOuter) { \ |
| 399 rv = NS_ERROR_NO_AGGREGATION; \ |
| 400 return rv; \ |
| 401 } \ |
| 402 \ |
| 403 NS_NEWXPCOM(inst, _InstanceClass); \ |
| 404 if (NULL == inst) { \ |
| 405 rv = NS_ERROR_OUT_OF_MEMORY; \ |
| 406 return rv; \ |
| 407 } \ |
| 408 NS_ADDREF(inst); \ |
| 409 rv = inst->_InitMethod(); \ |
| 410 if(NS_SUCCEEDED(rv)) { \ |
| 411 rv = inst->QueryInterface(aIID, aResult); \ |
| 412 } \ |
| 413 NS_RELEASE(inst); \ |
| 414 \ |
| 415 return rv; \ |
| 416 } \ |
| 417 |
| 418 // 'Constructor' that uses an existing getter function that gets a singleton. |
| 419 // NOTE: assumes that getter does an AddRef - so additional AddRef is not done. |
| 420 #define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(_InstanceClass, _GetterProc) \ |
| 421 static NS_IMETHODIMP \ |
| 422 _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ |
| 423 void **aResult) \ |
| 424 { \ |
| 425 nsresult rv; \ |
| 426 \ |
| 427 _InstanceClass * inst; \ |
| 428 \ |
| 429 *aResult = NULL; \ |
| 430 if (NULL != aOuter) { \ |
| 431 rv = NS_ERROR_NO_AGGREGATION; \ |
| 432 return rv; \ |
| 433 } \ |
| 434 \ |
| 435 inst = _GetterProc(); \ |
| 436 if (NULL == inst) { \ |
| 437 rv = NS_ERROR_OUT_OF_MEMORY; \ |
| 438 return rv; \ |
| 439 } \ |
| 440 /* NS_ADDREF(inst); */ \ |
| 441 rv = inst->QueryInterface(aIID, aResult); \ |
| 442 NS_RELEASE(inst); \ |
| 443 \ |
| 444 return rv; \ |
| 445 } \ |
| 446 |
| 447 #endif /* nsIGenericFactory_h___ */ |
OLD | NEW |