diff --git a/content/base/src/nsNodeInfo.cpp b/content/base/src/nsNodeInfo.cpp index 3cf43ad758c..4484db0c037 100644 --- a/content/base/src/nsNodeInfo.cpp +++ b/content/base/src/nsNodeInfo.cpp @@ -91,7 +91,7 @@ nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID, // nsISupports -NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfo, NS_GET_IID(nsINodeInfo)); +NS_IMPL_THREADSAFE_ISUPPORTS1(nsNodeInfo, nsINodeInfo); // nsINodeInfo diff --git a/content/base/src/nsNodeInfoManager.cpp b/content/base/src/nsNodeInfoManager.cpp index 32b3dd25360..2057ec2451b 100644 --- a/content/base/src/nsNodeInfoManager.cpp +++ b/content/base/src/nsNodeInfoManager.cpp @@ -111,8 +111,7 @@ nsNodeInfoManager::~nsNodeInfoManager() } -NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfoManager, - NS_GET_IID(nsINodeInfoManager)); +NS_IMPL_THREADSAFE_ISUPPORTS1(nsNodeInfoManager, nsINodeInfoManager); // nsINodeInfoManager diff --git a/xpcom/base/MANIFEST b/xpcom/base/MANIFEST index f441d42f4ef..f1cd09eeacf 100644 --- a/xpcom/base/MANIFEST +++ b/xpcom/base/MANIFEST @@ -3,13 +3,17 @@ nsIAllocator.h nsMemory.h nsCOMPtr.h nsCom.h +nsComObsolete.h nsCWeakReference.h nsDebug.h nsError.h nsID.h nsIID.h nsIPtr.h +nsISupportsBase.h +nsISupportsImpl.h nsISupportsUtils.h +nsISupportsObsolete.h nsTraceRefcnt.h nsWeakReference.h nsWeakPtr.h diff --git a/xpcom/base/makefile.win b/xpcom/base/makefile.win index b3907ff143b..2c0d24e9cbe 100644 --- a/xpcom/base/makefile.win +++ b/xpcom/base/makefile.win @@ -35,12 +35,16 @@ EXPORTS = \ nsMemory.h \ nsCOMPtr.h \ nsCom.h \ + nsComObsolete.h \ nsCWeakReference.h \ nsDebug.h \ nsError.h \ nsID.h \ nsIID.h \ nsIPtr.h \ + nsISupportsBase.h \ + nsISupportsImpl.h \ + nsISupportsObsolete.h \ nsISupportsUtils.h \ nsTraceRefcnt.h \ nsWeakReference.h \ diff --git a/xpcom/base/nsCOMPtr.h b/xpcom/base/nsCOMPtr.h index 3bd409e7324..526670ccd7c 100644 --- a/xpcom/base/nsCOMPtr.h +++ b/xpcom/base/nsCOMPtr.h @@ -40,17 +40,17 @@ // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design") -#ifndef nsDebug_h___ -#include "nsDebug.h" - // for |NS_PRECONDITION| -#endif - #ifndef nsISupports_h___ #include "nsISupports.h" // for |nsresult|, |NS_ADDREF|, |NS_GET_IID| et al #endif -#ifndef nscore_h__ +#ifndef nsDebug_h___ +#include "nsDebug.h" + // for |NS_PRECONDITION| +#endif + +#ifndef nscore_h___ #include "nscore.h" // for |NS_..._CAST|, |NS_EXPORT| #endif diff --git a/xpcom/base/nsCom.h b/xpcom/base/nsCom.h index 79f09be768d..03aae21aca4 100644 --- a/xpcom/base/nsCom.h +++ b/xpcom/base/nsCom.h @@ -22,244 +22,7 @@ #ifndef nsCom_h__ #define nsCom_h__ - -/* Core XPCOM declarations. */ - -/* - * People who create their own Win32 MSDev projects to compile against mozilla - * code *often* neglect to define XP_WIN and XP_WIN32. Rather than force - * those definitions here - and risk having some code get compiled incorrectly - * before this code is reached - we #error here to let the programmers know - * that they must modify their build projects. - * We would *like* to reduce the usage of these roughly synonymous defines. - * But it is a big modular project with a lot of brainprint issues... - * See bug: http://bugzilla.mozilla.org/show_bug.cgi?id=65727 - */ -#if defined(_WIN32) && (!defined(XP_WIN) || !defined(XP_WIN32)) -#error Add defines for XP_WIN and XP_WIN32 to your Win32 build project. -#endif - -/* - * API Import/Export macros - */ - -#ifdef _IMPL_NS_COM -#if defined(XP_WIN) -#define NS_COM _declspec(dllexport) -#elif defined(XP_MAC) -#define NS_COM __declspec(export) -#else /* !XP_WIN */ -#define NS_COM -#endif /* !XP_WIN */ -#else /* !_IMPL_NS_COM */ -#if defined(XP_WIN) -#define NS_COM _declspec(dllimport) -#else /* !XP_WIN */ -#define NS_COM -#endif /* !XP_WIN */ -#endif /* !_IMPL_NS_COM */ - -/* - * DLL Export macro - */ - -#ifdef XP_WIN - -#define NS_EXPORT _declspec(dllexport) -#define NS_EXPORT_(type) type _declspec(dllexport) __stdcall - -#define NS_IMETHOD_(type) virtual type __stdcall -#define NS_IMETHOD virtual nsresult __stdcall -#define NS_IMETHODIMP_(type) type __stdcall -#define NS_IMETHODIMP nsresult __stdcall - -#define NS_METHOD_(type) type __stdcall -#define NS_METHOD nsresult __stdcall - -#define NS_CALLBACK_(_type, _name) _type (__stdcall * _name) -#define NS_CALLBACK(_name) nsresult (__stdcall * _name) - -#elif defined(XP_MAC) - -#define NS_EXPORT __declspec(export) -#define NS_EXPORT_(type) __declspec(export) type - -#define NS_IMETHOD_(type) virtual type -#define NS_IMETHOD virtual nsresult -#define NS_IMETHODIMP_(type) type -#define NS_IMETHODIMP nsresult - -#define NS_METHOD_(type) type -#define NS_METHOD nsresult - -#define NS_CALLBACK_(_type, _name) _type (* _name) -#define NS_CALLBACK(_name) nsresult (* _name) - -#elif defined(XP_OS2) - -#define NS_EXPORT -#define NS_EXPORT_(type) type - -#define NS_IMETHOD_(type) virtual type -#define NS_IMETHOD virtual nsresult -#define NS_IMETHODIMP_(type) type -#define NS_IMETHODIMP nsresult - -#define NS_METHOD_(type) type -#define NS_METHOD nsresult - -#define NS_CALLBACK_(_type, _name) _type ( _System * _name) -#define NS_CALLBACK(_name) nsresult (* _name) - -#else /* !XP_WIN && !XP_MAC && !XP_OS2 */ - -#define NS_EXPORT -#define NS_EXPORT_(type) type - -#define NS_IMETHOD_(type) virtual type -#define NS_IMETHOD virtual nsresult -#define NS_IMETHODIMP_(type) type -#define NS_IMETHODIMP nsresult - -#define NS_METHOD_(type) type -#define NS_METHOD nsresult - -#define NS_CALLBACK_(_type, _name) _type (* _name) -#define NS_CALLBACK(_name) nsresult (* _name) - -#endif /* !XP_WIN */ - -/* use these functions to associate get/set methods with a - C++ member variable -*/ - -#define NS_METHOD_GETTER(_method, _type, _member) \ -_method(_type* aResult) \ -{\ - if (!aResult) return NS_ERROR_NULL_POINTER; \ - *aResult = _member; \ - return NS_OK; \ -} - -#define NS_METHOD_SETTER(_method, _type, _member) \ -_method(_type aResult) \ -{ \ - _member = aResult; \ - return NS_OK; \ -} - -/* - * special for strings to get/set char* strings - * using PL_strdup and PR_FREEIF - */ -#define NS_METHOD_GETTER_STR(_method,_member) \ -_method(char* *aString)\ -{\ - if (!aString) return NS_ERROR_NULL_POINTER; \ - *aString = PL_strdup(_member); \ - return NS_OK; \ -} - -#define NS_METHOD_SETTER_STR(_method, _member) \ -_method(const char *aString)\ -{\ - PR_FREEIF(_member);\ - if (aString) _member = PL_strdup(aString); \ - else _member = nsnull;\ - return NS_OK; \ -} - -/* Getter/Setter macros. - Usage: - NS_IMPL_[CLASS_]GETTER[_](method, [type,] member); - NS_IMPL_[CLASS_]SETTER[_](method, [type,] member); - NS_IMPL_[CLASS_]GETSET[_]([class, ]postfix, [type,] member); - - where: - CLASS_ - implementation is inside a class definition - (otherwise the class name is needed) - Do NOT use in publicly exported header files, because - the implementation may be included many times over. - Instead, use the non-CLASS_ version. - _ - For more complex (STR, IFACE) data types - (otherwise the simple data type is needed) - method - name of the method, such as GetWidth or SetColor - type - simple data type if required - member - class member variable such as m_width or mColor - class - the class name, such as Window or MyObject - postfix - Method part after Get/Set such as "Width" for "GetWidth" - - Example: - class Window { - public: - NS_IMPL_CLASS_GETSET(Width, int, m_width); - NS_IMPL_CLASS_GETTER_STR(GetColor, m_color); - NS_IMETHOD SetColor(char *color); - - private: - int m_width; // read/write - char *m_color; // readonly - }; - - // defined outside of class - NS_IMPL_SETTER_STR(Window::GetColor, m_color); - - Questions/Comments to alecf@netscape.com -*/ - - -/* - * Getter/Setter implementation within a class definition - */ - -/* simple data types */ -#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \ -NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member) - -#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \ -NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member) - -#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \ -NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \ -NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member) - -/* strings */ -#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \ -NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member) - -#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \ -NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member) - -#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \ -NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \ -NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member) - -/* Getter/Setter implementation outside of a class definition */ - -/* simple data types */ -#define NS_IMPL_GETTER(_method, _type, _member) \ -NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member) - -#define NS_IMPL_SETTER(_method, _type, _member) \ -NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member) - -#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \ -NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \ -NS_IMPL_SETTER(_class::Set##_postfix, _type, _member) - -/* strings */ -#define NS_IMPL_GETTER_STR(_method, _member) \ -NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member) - -#define NS_IMPL_SETTER_STR(_method, _member) \ -NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member) - -#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \ -NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \ -NS_IMPL_SETTER_STR(_class::Set##_postfix, _member) - - - +#include "nscore.h" #endif diff --git a/xpcom/base/nsComObsolete.h b/xpcom/base/nsComObsolete.h new file mode 100644 index 00000000000..8b25529cc41 --- /dev/null +++ b/xpcom/base/nsComObsolete.h @@ -0,0 +1,129 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsComObsolete_h__ +#define nsComObsolete_h__ + +// These _IMPL_NS_* defines should move into their own directories. +#ifdef _IMPL_NS_BASE +#define NS_BASE NS_EXPORT +#else +#define NS_BASE NS_IMPORT +#endif + +#ifdef _IMPL_NS_NET +#define NS_NET NS_EXPORT +#else +#define NS_NET NS_IMPORT +#endif + +#ifdef _IMPL_NS_DOM +#define NS_DOM NS_EXPORT +#else +#define NS_DOM NS_IMPORT +#endif + +#ifdef _IMPL_NS_WIDGET +#define NS_WIDGET NS_EXPORT +#else +#define NS_WIDGET NS_IMPORT +#endif + +#ifdef _IMPL_NS_VIEW +#define NS_VIEW NS_EXPORT +#else +#define NS_VIEW NS_IMPORT +#endif + +#ifdef _IMPL_NS_GFXNONXP +#define NS_GFXNONXP NS_EXPORT +#define NS_GFXNONXP_(type) NS_EXPORT_(type) +#else +#define NS_GFXNONXP NS_IMPORT +#define NS_GFXNONXP_(type) NS_IMPORT_(type) +#endif + +#ifdef _IMPL_NS_GFX +#define NS_GFX NS_EXPORT +#define NS_GFX_(type) NS_EXPORT_(type) +#else +#define NS_GFX NS_IMPORT +#define NS_GFX_(type) NS_IMPORT_(type) +#endif + +#ifdef _IMPL_NS_PLUGIN +#define NS_PLUGIN NS_EXPORT +#else +#define NS_PLUGIN NS_IMPORT +#endif + +#ifdef _IMPL_NS_APPSHELL +#define NS_APPSHELL NS_EXPORT +#else +#define NS_APPSHELL NS_IMPORT +#endif + + +/* + * People who create their own Win32 MSDev projects to compile against mozilla + * code *often* neglect to define XP_WIN and XP_WIN32. Rather than force + * those definitions here - and risk having some code get compiled incorrectly + * before this code is reached - we #error here to let the programmers know + * that they must modify their build projects. + * We would *like* to reduce the usage of these roughly synonymous defines. + * But it is a big modular project with a lot of brainprint issues... + * See bug: http://bugzilla.mozilla.org/show_bug.cgi?id=65727 + */ +#if defined(_WIN32) && (!defined(XP_WIN) || !defined(XP_WIN32)) +#error Add defines for XP_WIN and XP_WIN32 to your Win32 build project. +#endif + + +/* Define brackets for protecting C code from C++ */ +#ifdef __cplusplus +#define NS_BEGIN_EXTERN_C extern "C" { +#define NS_END_EXTERN_C } +#else +#define NS_BEGIN_EXTERN_C +#define NS_END_EXTERN_C +#endif + + + +#ifdef __cplusplus +#include "nsDebug.h" +#endif + +#endif diff --git a/xpcom/base/nsDebug.h b/xpcom/base/nsDebug.h index 144f67d95bf..60b977a7a33 100644 --- a/xpcom/base/nsDebug.h +++ b/xpcom/base/nsDebug.h @@ -23,8 +23,13 @@ #ifndef nsDebug_h___ #define nsDebug_h___ -#include "nsCom.h" -#include "prtypes.h" +#ifndef nscore_h___ +#include "nscore.h" +#endif + +#ifndef nsError_h__ +#include "nsError.h" +#endif #ifdef DEBUG #define NS_DEBUG @@ -299,4 +304,56 @@ if (!(expr)) \ #endif /* ! NS_DEBUG */ #endif /* __cplusplus */ + +// Macros for checking the trueness of an expression passed in within an +// interface implementation. These need to be compiled regardless of the +// NS_DEBUG flag +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_TRUE(x, ret) \ + PR_BEGIN_MACRO \ + if(NS_WARN_IF_FALSE(x, "NS_ENSURE_TRUE(" #x ") failed")) \ + return ret; \ + PR_END_MACRO + +#define NS_ENSURE_FALSE(x, ret) \ + NS_ENSURE_TRUE(!(x), ret) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for checking results +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_SUCCESS(res, ret) \ + NS_ENSURE_TRUE(NS_SUCCEEDED(res), ret) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for checking state and arguments upon entering interface boundaries +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_ARG(arg) \ + NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_POINTER(arg) \ + NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER) + +#define NS_ENSURE_ARG_MIN(arg, min) \ + NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_MAX(arg, max) \ + NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_RANGE(arg, min, max) \ + NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_STATE(state) \ + NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED) + +#define NS_ENSURE_NO_AGGREGATION(outer) \ + NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION) + +#define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \ + NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG) + +/////////////////////////////////////////////////////////////////////////////// + #endif /* nsDebug_h___ */ diff --git a/xpcom/base/nsError.h b/xpcom/base/nsError.h index c3f8f47f1f5..7986641beda 100644 --- a/xpcom/base/nsError.h +++ b/xpcom/base/nsError.h @@ -20,17 +20,12 @@ * Contributor(s): */ -#ifndef nsError_h -#define nsError_h +#ifndef nsError_h__ +#define nsError_h__ -#include "nsCom.h" -#include "prtypes.h" - -/** - * Generic result data type - */ - -typedef PRUint32 nsresult; +#ifndef nscore_h___ +#include "nscore.h" // needed for nsresult +#endif /* * To add error code to your module, you need to do the following: @@ -276,6 +271,4 @@ NS_ErrorAccordingToNSPR(); #pragma warning(disable: 4275) // non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode' #endif -//////////////////////////////////////////////////////////////////////////////// - #endif diff --git a/xpcom/base/nsID.h b/xpcom/base/nsID.h index 558daf1091e..308f0121904 100644 --- a/xpcom/base/nsID.h +++ b/xpcom/base/nsID.h @@ -25,12 +25,8 @@ #include -#ifndef prtypes_h___ -#include "prtypes.h" -#endif - -#ifndef nsCom_h__ -#include "nsCom.h" +#ifndef nscore_h___ +#include "nscore.h" #endif /** @@ -93,5 +89,40 @@ typedef nsID nsCID; #define REFNSCID const nsCID& +/** + * An "interface id" which can be used to uniquely identify a given + * interface. + */ + +typedef nsID nsIID; + +/** + * A macro shorthand for const nsIID& + */ + +#define REFNSIID const nsIID& + +/** + * Define an IID + * obsolete - do not use this macro + */ + +#define NS_DEFINE_IID(_name, _iidspec) \ + const nsIID _name = _iidspec + +/** + * A macro to build the static const IID accessor method + */ + +#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \ + static const nsIID& GetIID() {static const nsIID iid = the_iid; return iid;} + +/** + * A macro to build the static const CID accessor method + */ + +#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \ + static const nsID& GetCID() {static const nsID cid = the_cid; return cid;} + #endif diff --git a/xpcom/base/nsIID.h b/xpcom/base/nsIID.h index 4c63ae7590e..a8bb0cc0db5 100644 --- a/xpcom/base/nsIID.h +++ b/xpcom/base/nsIID.h @@ -22,29 +22,5 @@ #ifndef __nsIID_h #define __nsIID_h - -#ifndef nsID_h__ #include "nsID.h" -#endif - -/** - * An "interface id" which can be used to uniquely identify a given - * interface. - */ - -typedef nsID nsIID; - -/** - * A macro shorthand for const nsIID& - */ - -#define REFNSIID const nsIID& - -/** - * Define an IID (obsolete) - */ - -#define NS_DEFINE_IID(_name, _iidspec) \ - const nsIID _name = _iidspec - #endif /* __nsIID_h */ diff --git a/xpcom/base/nsIProgrammingLanguage.idl b/xpcom/base/nsIProgrammingLanguage.idl index 0e0cb7d2278..cdab6054fe9 100644 --- a/xpcom/base/nsIProgrammingLanguage.idl +++ b/xpcom/base/nsIProgrammingLanguage.idl @@ -41,6 +41,11 @@ #endif %} +/** + * Enumeration of Programming Languages + * @status FROZEN + */ + [scriptable, uuid(ea604e90-40ba-11d5-90bb-0010a4e73d9a)] interface nsIProgrammingLanguage : nsISupports { diff --git a/xpcom/base/nsISupports.idl b/xpcom/base/nsISupports.idl index a666b45e038..9f45c97c5bd 100644 --- a/xpcom/base/nsISupports.idl +++ b/xpcom/base/nsISupports.idl @@ -19,8 +19,11 @@ * * Contributor(s): */ - -/* The mother of all xpcom interfaces. */ + +/** + * The mother of all xpcom interfaces. + * @status FROZEN + */ /* In order to get both the right typelib and the right header we force * the 'real' output from xpidl to be commentout out in the generated header @@ -54,7 +57,9 @@ interface nsISupports { %{C++ +#include "nsISupportsBase.h" +#ifndef MOZILLA_STRICT_API #include "nsISupportsUtils.h" - +#endif %} diff --git a/xpcom/base/nsISupportsBase.h b/xpcom/base/nsISupportsBase.h new file mode 100644 index 00000000000..63ec1f209b5 --- /dev/null +++ b/xpcom/base/nsISupportsBase.h @@ -0,0 +1,119 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsISupportsBase_h__ +#define nsISupportsBase_h__ + +#ifndef nscore_h___ +#include "nscore.h" +#endif + +#ifndef nsID_h__ +#include "nsID.h" +#endif + + +/*@{*/ +/** + * IID for the nsISupports interface + * {00000000-0000-0000-c000-000000000046} + * + * To maintain binary compatibility with COM's nsIUnknown, we define the IID + * of nsISupports to be the same as that of COM's nsIUnknown. + */ +#define NS_ISUPPORTS_IID \ + { 0x00000000, 0x0000, 0x0000, \ + {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} } + +/** + * Reference count values + * + * This is type of return value from Addref() and Release() in nsISupports. + * nsIUnknown of COM returns a unsigned long from equivalent functions. + * To maintain binary compatibility of nsISupports with nsIUnknown, we are + * doing this ifdeffing. + */ +#if defined(XP_WIN) && PR_BYTES_PER_LONG == 4 +typedef unsigned long nsrefcnt; +#else +typedef PRUint32 nsrefcnt; +#endif + +/** + * Basic component object model interface. Objects which implement + * this interface support runtime interface discovery (QueryInterface) + * and a reference counted memory model (AddRef/Release). This is + * modelled after the win32 IUnknown API. + */ +class NS_NO_VTABLE nsISupports { +public: + + /** + * @name Methods + */ + + //@{ + /** + * A run time mechanism for interface discovery. + * @param aIID [in] A requested interface IID + * @param aInstancePtr [out] A pointer to an interface pointer to + * receive the result. + * @return NS_OK if the interface is supported by the associated + * instance, NS_NOINTERFACE if it is not. + * NS_ERROR_INVALID_POINTER if aInstancePtr is NULL. + */ + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) = 0; + /** + * Increases the reference count for this interface. + * The associated instance will not be deleted unless + * the reference count is returned to zero. + * + * @return The resulting reference count. + */ + NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; + + /** + * Decreases the reference count for this interface. + * Generally, if the reference count returns to zero, + * the associated instance is deleted. + * + * @return The resulting reference count. + */ + NS_IMETHOD_(nsrefcnt) Release(void) = 0; + + //@} +}; +/*@}*/ +#endif diff --git a/xpcom/base/nsISupportsImpl.h b/xpcom/base/nsISupportsImpl.h new file mode 100644 index 00000000000..b1f0c0effef --- /dev/null +++ b/xpcom/base/nsISupportsImpl.h @@ -0,0 +1,976 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#ifndef nsISupportsImpl_h__ +#define nsISupportsImpl_h__ + +#ifndef nscore_h___ +#include "nscore.h" +#endif + +#ifndef nsISupportsBase_h__ +#include "nsISupportsBase.h" +#endif + +#include "pratom.h" /* needed for PR_AtomicIncrement and PR_AtomicDecrement */ +#include "nsTraceRefcnt.h" + +//////////////////////////////////////////////////////////////////////////////// +// Macros to help detect thread-safety: + +#if defined(NS_DEBUG) && defined(NS_MT_SUPPORTED) + +extern "C" NS_EXPORT void* NS_CurrentThread(void); +extern "C" NS_EXPORT void NS_CheckThreadSafe(void* owningThread, + const char* msg); + +#define NS_DECL_OWNINGTHREAD void* _mOwningThread; +#define NS_IMPL_OWNINGTHREAD() (_mOwningThread = NS_CurrentThread()) +#define NS_ASSERT_OWNINGTHREAD(_class) NS_CheckThreadSafe(_mOwningThread, \ + #_class \ + " not thread-safe") + +#else // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) + +#define NS_DECL_OWNINGTHREAD /* nothing */ +#define NS_IMPL_OWNINGTHREAD() ((void)0) +#define NS_ASSERT_OWNINGTHREAD(_class) ((void)0) + +#endif // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Declare the reference count variable and the implementations of the + * AddRef and QueryInterface methods. + */ + +#define NS_DECL_ISUPPORTS \ +public: \ + NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_IMETHOD_(nsrefcnt) Release(void); \ +protected: \ + nsrefcnt mRefCnt; \ + NS_DECL_OWNINGTHREAD \ +public: + + +/////////////////////////////////////////////////////////////////////////////// + +/** + * Initialize the reference count variable. Add this to each and every + * constructor you implement. + */ +#define NS_INIT_ISUPPORTS() (mRefCnt = 0, NS_IMPL_OWNINGTHREAD()) + +/** + * Use this macro to implement the AddRef method for a given _class + * @param _class The name of the class implementing the method + */ +#define NS_IMPL_ADDREF(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ +{ \ + NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ + NS_ASSERT_OWNINGTHREAD(_class); \ + ++mRefCnt; \ + NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \ + return mRefCnt; \ +} + +/** + * Use this macro to implement the Release method for a given + * _class. + * @param _class The name of the class implementing the method + * @param _destroy A statement that is executed when the object's + * refcount drops to zero. + * + * For example, + * + * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this)) + * + * will cause + * + * Destroy(this); + * + * to be invoked when the object's refcount drops to zero. This + * allows for arbitrary teardown activity to occur (e.g., deallocation + * of object allocated with placement new). + */ +#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \ +NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ +{ \ + NS_PRECONDITION(0 != mRefCnt, "dup release"); \ + NS_ASSERT_OWNINGTHREAD(_class); \ + --mRefCnt; \ + NS_LOG_RELEASE(this, mRefCnt, #_class); \ + if (mRefCnt == 0) { \ + mRefCnt = 1; /* stabilize */ \ + _destroy; \ + return 0; \ + } \ + return mRefCnt; \ +} + +/** + * Use this macro to implement the Release method for a given _class + * @param _class The name of the class implementing the method + * + * A note on the 'stabilization' of the refcnt to one. At that point, + * the object's refcount will have gone to zero. The object's + * destructor may trigger code that attempts to QueryInterface() and + * Release() 'this' again. Doing so will temporarily increment and + * decrement the refcount. (Only a logic error would make one try to + * keep a permanent hold on 'this'.) To prevent re-entering the + * destructor, we make sure that no balanced refcounting can return + * the refcount to |0|. + */ +#define NS_IMPL_RELEASE(_class) \ + NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this)) + + +/////////////////////////////////////////////////////////////////////////////// + +/* + * Some convenience macros for implementing QueryInterface + */ + +/** + * This implements query interface with two assumptions: First, the + * class in question implements nsISupports and its own interface and + * nothing else. Second, the implementation of the class's primary + * inheritance chain leads to its own interface. + * + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ + +#define NS_IMPL_QUERY_HEAD(_class) \ +NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ +{ \ + NS_ASSERTION(aInstancePtr, \ + "QueryInterface requires a non-NULL destination!"); \ + if ( !aInstancePtr ) \ + return NS_ERROR_NULL_POINTER; \ + nsISupports* foundInterface; + +#define NS_IMPL_QUERY_BODY(_interface) \ + if ( aIID.Equals(NS_GET_IID(_interface)) ) \ + foundInterface = NS_STATIC_CAST(_interface*, this); \ + else + +#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) \ + if ( aIID.Equals(NS_GET_IID(_interface)) ) \ + foundInterface = NS_STATIC_CAST(_interface*, \ + NS_STATIC_CAST(_implClass*, this)); \ + else + +#define NS_IMPL_QUERY_TAIL_GUTS \ + foundInterface = 0; \ + nsresult status; \ + if ( !foundInterface ) \ + status = NS_NOINTERFACE; \ + else \ + { \ + NS_ADDREF(foundInterface); \ + status = NS_OK; \ + } \ + *aInstancePtr = foundInterface; \ + return status; \ +} + +#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \ + foundInterface = 0; \ + nsresult status; \ + if ( !foundInterface ) \ + status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \ + else \ + { \ + NS_ADDREF(foundInterface); \ + status = NS_OK; \ + } \ + *aInstancePtr = foundInterface; \ + return status; \ +} + +#define NS_IMPL_QUERY_TAIL(_supports_interface) \ + NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \ + NS_IMPL_QUERY_TAIL_GUTS + + + /* + This is the new scheme. Using this notation now will allow us to switch to + a table driven mechanism when it's ready. Note the difference between this + and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism. You must + explicitly mention |nsISupports| when using the interface maps. + */ +#define NS_INTERFACE_MAP_BEGIN(_implClass) NS_IMPL_QUERY_HEAD(_implClass) +#define NS_INTERFACE_MAP_ENTRY(_interface) NS_IMPL_QUERY_BODY(_interface) +#define NS_INTERFACE_MAP_END NS_IMPL_QUERY_TAIL_GUTS +#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass) \ + NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) +#define NS_INTERFACE_MAP_END_INHERITING(_baseClass) \ + NS_IMPL_QUERY_TAIL_INHERITING(_baseClass) + +#define NS_IMPL_QUERY_INTERFACE0(_class) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(nsISupports) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE1(_class, _i1) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY(_i10) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0 NS_IMPL_QUERY_INTERFACE0 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1 NS_IMPL_QUERY_INTERFACE1 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2 NS_IMPL_QUERY_INTERFACE2 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3 NS_IMPL_QUERY_INTERFACE3 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4 NS_IMPL_QUERY_INTERFACE4 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5 NS_IMPL_QUERY_INTERFACE5 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6 NS_IMPL_QUERY_INTERFACE6 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7 NS_IMPL_QUERY_INTERFACE7 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8 NS_IMPL_QUERY_INTERFACE8 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9 NS_IMPL_QUERY_INTERFACE9 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10 NS_IMPL_QUERY_INTERFACE10 + +/** + * Declare that you're going to inherit from something that already + * implements nsISupports, but also implements an additional interface, thus + * causing an ambiguity. In this case you don't need another mRefCnt, you + * just need to forward the definitions to the appropriate superclass. E.g. + * + * class Bar : public Foo, public nsIBar { // both provide nsISupports + * public: + * NS_DECL_ISUPPORTS_INHERITED + * ...other nsIBar and Bar methods... + * }; + */ +#define NS_DECL_ISUPPORTS_INHERITED \ +public: \ + NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_IMETHOD_(nsrefcnt) Release(void); \ + +/** + * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED + * to implement the nsISupports methods, forwarding the invocations to a + * superclass that already implements nsISupports. + * + * Note that I didn't make these inlined because they're virtual methods. + */ + +#define NS_IMPL_ADDREF_INHERITED(Class, Super) \ +NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \ +{ \ + return Super::AddRef(); \ +} \ + +#define NS_IMPL_RELEASE_INHERITED(Class, Super) \ +NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \ +{ \ + return Super::Release(); \ +} \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_BODY(i5) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_BODY(i5) \ + NS_IMPL_QUERY_BODY(i6) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, i1) \ + NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ + +#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \ + NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ + NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ + NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ + NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +/////////////////////////////////////////////////////////////////////////////// +/** + * + * Threadsafe implementations of the ISupports convenience macros + * + */ + +#if defined(NS_MT_SUPPORTED) + +/** + * Use this macro to implement the AddRef method for a given _class + * @param _class The name of the class implementing the method + */ + +#define NS_IMPL_THREADSAFE_ADDREF(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ +{ \ + NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ + nsrefcnt count; \ + count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \ + NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \ + return count; \ +} + +/** + * Use this macro to implement the Release method for a given _class + * @param _class The name of the class implementing the method + */ + +#define NS_IMPL_THREADSAFE_RELEASE(_class) \ +nsrefcnt _class::Release(void) \ +{ \ + nsrefcnt count; \ + NS_PRECONDITION(0 != mRefCnt, "dup release"); \ + count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \ + NS_LOG_RELEASE(this, count, #_class); \ + if (0 == count) { \ + mRefCnt = 1; /* stabilize */ \ + /* enable this to find non-threadsafe destructors: */ \ + /* NS_ASSERT_OWNINGTHREAD(_class); */ \ + NS_DELETEXPCOM(this); \ + return 0; \ + } \ + return count; \ +} + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ +NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ +{ \ + if (NULL == aInstancePtr) { \ + return NS_ERROR_NULL_POINTER; \ + } \ + \ + *aInstancePtr = NULL; \ + \ + if (aIID.Equals(NS_GET_IID(nsISupports))) { \ + *aInstancePtr = (void*) ((nsISupports*)this); \ + NS_ADDREF_THIS(); \ + return NS_OK; \ + } \ + return NS_NOINTERFACE; \ +} + +#else // defined(NS_MT_SUPPORTED) + +/** + * Convenience macro for implementing all nsISupports methods for + * a simple class. + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ + +#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) + +#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class) + +#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class) + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ + NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) + +#endif /* !NS_MT_SUPPORTED */ + +#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) + +#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface) + +#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) + +#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) + +#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) + +#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) + +#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) + +#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) + +#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) + +#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) + +#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for implementing nsIClassInfo-related stuff. +/////////////////////////////////////////////////////////////////////////////// + +// include here instead of at the top because it requires the nsISupport decl +#include "nsIClassInfo.h" + +#define NS_CLASSINFO_NAME(_class) _class##_classInfoGlobal +#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper + +#define NS_DECL_CI_INTERFACE_GETTER(_class) \ + extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *, \ + nsIID ***); + +#define NS_DECL_CLASSINFO(_class) \ + NS_DECL_CI_INTERFACE_GETTER(_class) \ + nsIClassInfo *NS_CLASSINFO_NAME(_class); + +#define NS_IMPL_QUERY_CLASSINFO(_class) \ + if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) { \ + extern nsIClassInfo *NS_CLASSINFO_NAME(_class); \ + foundInterface = NS_STATIC_CAST(nsIClassInfo*, NS_CLASSINFO_NAME(_class));\ + } else + +#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \ +NS_IMETHODIMP \ +NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *count, nsIID ***array) \ +{ \ + *count = _c; \ + *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c); + +#define NS_CLASSINFO_HELPER_ENTRY(_i, _interface) \ + (*array)[_i] = (nsIID *)nsMemory::Clone(&NS_GET_IID(_interface), \ + sizeof(nsIID)); + +#define NS_CLASSINFO_HELPER_END \ + return NS_OK; \ +} + +#define NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 1) \ + NS_CLASSINFO_HELPER_ENTRY(0, _interface) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE1_CI(_class, _i1) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS1_CI(_class, _interface) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface) \ + NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) + +#define NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 2) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS2_CI(_class, _i1, _i2) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ + NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) + +#define NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 3) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS3_CI(_class, _i1, _i2, _i3) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ + NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) + +#define NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 4) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) + +#define NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 5) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) + +#define NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 6) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) + +#define NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 7) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) + +#define NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 8) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ + NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) + +#define NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 9) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) \ + NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) + +#define NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 10) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ + NS_CLASSINFO_HELPER_ENTRY(9, _i10) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY(_i10) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) \ + NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) + +#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS + +#endif diff --git a/xpcom/base/nsISupportsObsolete.h b/xpcom/base/nsISupportsObsolete.h new file mode 100644 index 00000000000..8ec749a6b24 --- /dev/null +++ b/xpcom/base/nsISupportsObsolete.h @@ -0,0 +1,478 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#ifndef nsISupportsObsolete_h__ +#define nsISupportsObsolete_h__ + +#if defined(NS_MT_SUPPORTED) +#include "prcmon.h" +#endif /* NS_MT_SUPPORTED */ +/////////////////////////////////////////////////////////////////////////////// + + +#define NS_INIT_REFCNT() NS_INIT_ISUPPORTS() + + +#define NS_DECL_ISUPPORTS_EXPORTED \ +public: \ + NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \ +protected: \ + nsrefcnt mRefCnt; \ + NS_DECL_OWNINGTHREAD \ +public: + + +#ifdef NS_DEBUG + +/* + * Adding this debug-only function as per bug #26803. If you are debugging + * and this function returns wrong refcounts, fix the objects |AddRef()| and + * |Release()| to do the right thing. + * + * Of course, this function is only available for debug builds. + */ + +inline +nsrefcnt +NS_DebugGetRefCount( nsISupports* obj ) + // Warning: don't apply this to an object whose refcount is + // |0| or not yet initialized ... it may be destroyed. + { + nsrefcnt ref_count = 0; + + if ( obj ) + { + // |AddRef()| and |Release()| are supposed to return + // the new refcount of the object + obj->AddRef(); + ref_count = obj->Release(); + // Can't use |NS_[ADDREF|RELEASE]| since (a) they _don't_ return + // the refcount, and (b) we don't want to log these guaranteed + // balanced calls. + + NS_ASSERTION(ref_count, + "Oops! Calling |NS_DebugGetRefCount()| probably just " + "destroyed this object."); + } + + return ref_count; + } + +#endif // NS_DEBUG + +/** + * Macro to free an array of pointers to nsISupports (or classes + * derived from it). A convenience wrapper around + * NS_FREE_XPCOM_POINTER_ARRAY. + * + * Note that if you know that none of your nsISupports pointers are + * going to be 0, you can gain a bit of speed by calling + * NS_FREE_XPCOM_POINTER_ARRAY directly and using NS_RELEASE as your + * free function. + * + * @param size Number of elements in the array. If not a constant, this + * should be a PRInt32. Note that this means this macro + * will not work if size >= 2^31. + * @param array The array to be freed. + */ +#define NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(size, array) \ + NS_FREE_XPCOM_POINTER_ARRAY((size), (array), NS_IF_RELEASE) + + +/////////////////////////////////////////////////////////////////////////////// + +/* use these functions to associate get/set methods with a + C++ member variable +*/ + +#define NS_METHOD_GETTER(_method, _type, _member) \ +_method(_type* aResult) \ +{\ + if (!aResult) return NS_ERROR_NULL_POINTER; \ + *aResult = _member; \ + return NS_OK; \ +} + +#define NS_METHOD_SETTER(_method, _type, _member) \ +_method(_type aResult) \ +{ \ + _member = aResult; \ + return NS_OK; \ +} + +/* + * special for strings to get/set char* strings + * using PL_strdup and PR_FREEIF + */ +#define NS_METHOD_GETTER_STR(_method,_member) \ +_method(char* *aString)\ +{\ + if (!aString) return NS_ERROR_NULL_POINTER; \ + *aString = PL_strdup(_member); \ + return NS_OK; \ +} + +#define NS_METHOD_SETTER_STR(_method, _member) \ +_method(const char *aString)\ +{\ + PR_FREEIF(_member);\ + if (aString) _member = PL_strdup(aString); \ + else _member = nsnull;\ + return NS_OK; \ +} + +/* Getter/Setter macros. + Usage: + NS_IMPL_[CLASS_]GETTER[_](method, [type,] member); + NS_IMPL_[CLASS_]SETTER[_](method, [type,] member); + NS_IMPL_[CLASS_]GETSET[_]([class, ]postfix, [type,] member); + + where: + CLASS_ - implementation is inside a class definition + (otherwise the class name is needed) + Do NOT use in publicly exported header files, because + the implementation may be included many times over. + Instead, use the non-CLASS_ version. + _ - For more complex (STR, IFACE) data types + (otherwise the simple data type is needed) + method - name of the method, such as GetWidth or SetColor + type - simple data type if required + member - class member variable such as m_width or mColor + class - the class name, such as Window or MyObject + postfix - Method part after Get/Set such as "Width" for "GetWidth" + + Example: + class Window { + public: + NS_IMPL_CLASS_GETSET(Width, int, m_width); + NS_IMPL_CLASS_GETTER_STR(GetColor, m_color); + NS_IMETHOD SetColor(char *color); + + private: + int m_width; // read/write + char *m_color; // readonly + }; + + // defined outside of class + NS_IMPL_SETTER_STR(Window::GetColor, m_color); + + Questions/Comments to alecf@netscape.com +*/ + + +/* + * Getter/Setter implementation within a class definition + */ + +/* simple data types */ +#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \ +NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member) + +#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \ +NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member) + +#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \ +NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \ +NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member) + +/* strings */ +#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \ +NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member) + +#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \ +NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member) + +#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \ +NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \ +NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member) + +/* Getter/Setter implementation outside of a class definition */ + +/* simple data types */ +#define NS_IMPL_GETTER(_method, _type, _member) \ +NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member) + +#define NS_IMPL_SETTER(_method, _type, _member) \ +NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member) + +#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \ +NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \ +NS_IMPL_SETTER(_class::Set##_postfix, _type, _member) + +/* strings */ +#define NS_IMPL_GETTER_STR(_method, _member) \ +NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member) + +#define NS_IMPL_SETTER_STR(_method, _member) \ +NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member) + +#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \ +NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \ +NS_IMPL_SETTER_STR(_class::Set##_postfix, _member) + +/** + * IID for the nsIsThreadsafe interface + * {88210890-47a6-11d2-bec3-00805f8a66dc} + * + * This interface is *only* used for debugging purposes to determine if + * a given component is threadsafe. + */ +#define NS_ISTHREADSAFE_IID \ + { 0x88210890, 0x47a6, 0x11d2, \ + {0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} } + + +#if defined(NS_MT_SUPPORTED) + +#define NS_LOCK_INSTANCE() \ + PR_CEnterMonitor((void*)this) +#define NS_UNLOCK_INSTANCE() \ + PR_CExitMonitor((void*)this) + +#else + +#define NS_LOCK_INSTANCE() +#define NS_UNLOCK_INSTANCE() + +#endif + +/** + * This implements query interface with two assumptions: First, the + * class in question implements nsISupports and its own interface and + * nothing else. Second, the implementation of the class's primary + * inheritance chain leads to its own interface. + * + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ +#if defined(NS_DEBUG) +#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \ + if (NULL != (_iface)) { \ + nsISupports* tmp; \ + static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ + NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \ + (void**)&tmp)), \ + "Interface is not threadsafe"); \ + } +#else +#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) +#endif + + +/* + The following macro is deprecated. We need to switch all instances + to |NS_IMPL_QUERY_INTERFACE1|, or |NS_IMPL_QUERY_INTERFACE0| depending + on how they were using it. +*/ + +#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \ +NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ +{ \ + if (NULL == aInstancePtr) { \ + return NS_ERROR_NULL_POINTER; \ + } \ + \ + *aInstancePtr = NULL; \ + \ + static NS_DEFINE_IID(kClassIID, _classiiddef); \ + if (aIID.Equals(kClassIID)) { \ + *aInstancePtr = (void*) this; \ + NS_ADDREF_THIS(); \ + return NS_OK; \ + } \ + if (aIID.Equals(NS_GET_IID(nsISupports))) { \ + *aInstancePtr = (void*) ((nsISupports*)this); \ + NS_ADDREF_THIS(); \ + return NS_OK; \ + } \ + return NS_NOINTERFACE; \ + +/** + * Convenience macro for implementing all nsISupports methods for + * a simple class. + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ + +#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) + +#define NS_IMPL_ISUPPORTS0(_class) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE0(_class) + +#define NS_IMPL_ISUPPORTS1(_class, _interface) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE1(_class, _interface) + +#define NS_IMPL_ISUPPORTS2(_class, _i1, _i2) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) + +#define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) + +#define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) + +#define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) + +#define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) + +#define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) + +#define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) + +#define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ + _i9) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9) + +#define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ + _i9, _i10) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ + _i9, _i10) + +//////////////////////////////////////////////////////////////////////////////// + + +#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, i1) \ + NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) + + +// below should go into nsIMemoryUtils.h or something similar. + +/** + * Macro to free all elements of an XPCOM array of a given size using + * freeFunc, then frees the array itself using nsMemory::Free(). + * + * Note that this macro (and its wrappers) can be used to deallocate a + * partially- or completely-built array while unwinding an error + * condition inside the XPCOM routine that was going to return the + * array. For this to work on a partially-built array, your code + * needs to be building the array from index 0 upwards, and simply + * pass the number of elements that have already been built (and thus + * need to be freed) as |size|. + * + * Thanks to for suggesting this form, which + * allows the macro to be used with NS_RELEASE / NS_RELEASE_IF in + * addition to nsMemory::Free. + * + * @param size Number of elements in the array. If not a constant, this + * should be a PRInt32. Note that this means this macro + * will not work if size >= 2^31. + * @param array The array to be freed. + * @param freeFunc The function or macro to be used to free it. + * For arrays of nsISupports (or any class derived + * from it), NS_IF_RELEASE (or NS_RELEASE) should be + * passed as freeFunc. For most (all?) other pointer + * types (including XPCOM strings and wstrings), + * nsMemory::Free should be used, since the + * shared-allocator (nsMemory) is what will have been + * used to allocate the memory. + */ +#define NS_FREE_XPCOM_POINTER_ARRAY(size, array, freeFunc) \ + PR_BEGIN_MACRO \ + PRInt32 iter_ = PRInt32(size); \ + while (--iter_ >= 0) \ + freeFunc((array)[iter_]); \ + nsMemory::Free((array)); \ + PR_END_MACRO + +// convenience macros for commonly used calls. mmmmm. syntactic sugar. + +/** + * Macro to free arrays of non-refcounted objects allocated by the + * shared allocator (nsMemory) such as strings and wstrings. A + * convenience wrapper around NS_FREE_XPCOM_POINTER_ARRAY. + * + * @param size Number of elements in the array. If not a constant, this + * should be a PRInt32. Note that this means this macro + * will not work if size >= 2^31. + * @param array The array to be freed. + */ +#define NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(size, array) \ + NS_FREE_XPCOM_POINTER_ARRAY((size), (array), nsMemory::Free) + + +/** + * Macro to free an array of pointers to nsISupports (or classes + * derived from it). A convenience wrapper around + * NS_FREE_XPCOM_POINTER_ARRAY. + * + * Note that if you know that none of your nsISupports pointers are + * going to be 0, you can gain a bit of speed by calling + * NS_FREE_XPCOM_POINTER_ARRAY directly and using NS_RELEASE as your + * free function. + * + * @param size Number of elements in the array. If not a constant, this + * should be a PRInt32. Note that this means this macro + * will not work if size >= 2^31. + * @param array The array to be freed. + */ +#define NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(size, array) \ + NS_FREE_XPCOM_POINTER_ARRAY((size), (array), NS_IF_RELEASE) + +#endif diff --git a/xpcom/base/nsISupportsUtils.h b/xpcom/base/nsISupportsUtils.h index 7bc23f18ef4..d5919d7c386 100644 --- a/xpcom/base/nsISupportsUtils.h +++ b/xpcom/base/nsISupportsUtils.h @@ -23,1118 +23,33 @@ * Dan Mosedale */ -#ifndef __nsISupportsUtils_h -#define __nsISupportsUtils_h - -/***************************************************************************/ -/* this section copied from the hand written nsISupports.h */ +#ifndef nsISupportsUtils_h__ +#define nsISupportsUtils_h__ +#ifndef nscore_h___ #include "nscore.h" - // for |NS_SPECIALIZE_TEMPLATE|, and the casts, et al +#endif -#include "nsDebug.h" -#include "nsID.h" -#include "nsIID.h" +#ifndef nsISupportsBase_h__ +#include "nsISupportsBase.h" +#endif + +#ifndef nsError_h__ #include "nsError.h" -#include "pratom.h" /* needed for PR_AtomicIncrement and PR_AtomicDecrement */ - -#if defined(NS_MT_SUPPORTED) -#include "prcmon.h" -#endif /* NS_MT_SUPPORTED */ - -/*@{*/ - -/////////////////////////////////////////////////////////////////////////////// - -/** - * IID for the nsISupports interface - * {00000000-0000-0000-c000-000000000046} - * - * To maintain binary compatibility with COM's nsIUnknown, we define the IID - * of nsISupports to be the same as that of COM's nsIUnknown. - */ -#define NS_ISUPPORTS_IID \ - { 0x00000000, 0x0000, 0x0000, \ - {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} } - -/** - * Reference count values - * - * This is type of return value from Addref() and Release() in nsISupports. - * nsIUnknown of COM returns a unsigned long from equivalent functions. - * To maintain binary compatibility of nsISupports with nsIUnknown, we are - * doing this ifdeffing. - */ -#if defined(XP_WIN) && PR_BYTES_PER_LONG == 4 -typedef unsigned long nsrefcnt; -#else -typedef PRUint32 nsrefcnt; #endif -/** - * NS_NO_VTABLE is emitted by xpidl in interface declarations whenever - * xpidl can determine that the interface can't contain a constructor. - * This results in some space savings and possible runtime savings - - * see bug 49416. We undefine it first, as xpidl-generated headers - * define it for IDL uses that don't include this file. - */ -#ifdef NS_NO_VTABLE -#undef NS_NO_VTABLE -#endif -#if defined(_MSC_VER) && _MSC_VER >= 1100 -#define NS_NO_VTABLE __declspec(novtable) -#else -#define NS_NO_VTABLE +#ifndef nsDebug_h___ +#include "nsDebug.h" #endif -#include "nsTraceRefcnt.h" - -/** - * Basic component object model interface. Objects which implement - * this interface support runtime interface discovery (QueryInterface) - * and a reference counted memory model (AddRef/Release). This is - * modelled after the win32 IUnknown API. - */ -class NS_NO_VTABLE nsISupports { -public: - - /** - * @name Methods - */ - - //@{ - /** - * A run time mechanism for interface discovery. - * @param aIID [in] A requested interface IID - * @param aInstancePtr [out] A pointer to an interface pointer to - * receive the result. - * @return NS_OK if the interface is supported by the associated - * instance, NS_NOINTERFACE if it is not. - * NS_ERROR_INVALID_POINTER if aInstancePtr is NULL. - */ - NS_IMETHOD QueryInterface(REFNSIID aIID, - void** aInstancePtr) = 0; - /** - * Increases the reference count for this interface. - * The associated instance will not be deleted unless - * the reference count is returned to zero. - * - * @return The resulting reference count. - */ - NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; - - /** - * Decreases the reference count for this interface. - * Generally, if the reference count returns to zero, - * the associated instance is deleted. - * - * @return The resulting reference count. - */ - NS_IMETHOD_(nsrefcnt) Release(void) = 0; - - //@} -}; - -/*@}*/ - -/***************************************************************************/ - -/** - * A macro to build the static const IID accessor method - */ - -#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \ - static const nsIID& GetIID() {static const nsIID iid = the_iid; return iid;} - -/** - * A macro to build the static const CID accessor method - */ - -#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \ - static const nsID& GetCID() {static const nsID cid = the_cid; return cid;} - -//////////////////////////////////////////////////////////////////////////////// -// Macros to help detect thread-safety: - -#if defined(NS_DEBUG) && defined(NS_MT_SUPPORTED) - -extern "C" NS_EXPORT void* NS_CurrentThread(void); -extern "C" NS_EXPORT void NS_CheckThreadSafe(void* owningThread, - const char* msg); - -#define NS_DECL_OWNINGTHREAD void* _mOwningThread; -#define NS_IMPL_OWNINGTHREAD() (_mOwningThread = NS_CurrentThread()) -#define NS_ASSERT_OWNINGTHREAD(_class) NS_CheckThreadSafe(_mOwningThread, \ - #_class \ - " not thread-safe") - -#else // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) - -#define NS_DECL_OWNINGTHREAD /* nothing */ -#define NS_IMPL_OWNINGTHREAD() ((void)0) -#define NS_ASSERT_OWNINGTHREAD(_class) ((void)0) - -#endif // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Some convenience macros for implementing AddRef and Release - */ - -/** - * Declare the reference count variable and the implementations of the - * AddRef and QueryInterface methods. - */ - -#define NS_DECL_ISUPPORTS \ -public: \ - NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_IMETHOD_(nsrefcnt) Release(void); \ -protected: \ - nsrefcnt mRefCnt; \ - NS_DECL_OWNINGTHREAD \ -public: - -#define NS_DECL_ISUPPORTS_EXPORTED \ -public: \ - NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \ -protected: \ - nsrefcnt mRefCnt; \ - NS_DECL_OWNINGTHREAD \ -public: - -/////////////////////////////////////////////////////////////////////////////// - -/** - * Initialize the reference count variable. Add this to each and every - * constructor you implement. - */ -#define NS_INIT_REFCNT() (mRefCnt = 0, NS_IMPL_OWNINGTHREAD()) -#define NS_INIT_ISUPPORTS() NS_INIT_REFCNT() // what it should have been called in the first place - -/** - * Use this macro to implement the AddRef method for a given _class - * @param _class The name of the class implementing the method - */ -#define NS_IMPL_ADDREF(_class) \ -NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ -{ \ - NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ - NS_ASSERT_OWNINGTHREAD(_class); \ - ++mRefCnt; \ - NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \ - return mRefCnt; \ -} - -/** - * Use this macro to implement the Release method for a given - * _class. - * @param _class The name of the class implementing the method - * @param _destroy A statement that is executed when the object's - * refcount drops to zero. - * - * For example, - * - * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this)) - * - * will cause - * - * Destroy(this); - * - * to be invoked when the object's refcount drops to zero. This - * allows for arbitrary teardown activity to occur (e.g., deallocation - * of object allocated with placement new). - */ -#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \ -NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ -{ \ - NS_PRECONDITION(0 != mRefCnt, "dup release"); \ - NS_ASSERT_OWNINGTHREAD(_class); \ - --mRefCnt; \ - NS_LOG_RELEASE(this, mRefCnt, #_class); \ - if (mRefCnt == 0) { \ - mRefCnt = 1; /* stabilize */ \ - _destroy; \ - return 0; \ - } \ - return mRefCnt; \ -} - -/** - * Use this macro to implement the Release method for a given _class - * @param _class The name of the class implementing the method - * - * A note on the 'stabilization' of the refcnt to one. At that point, - * the object's refcount will have gone to zero. The object's - * destructor may trigger code that attempts to QueryInterface() and - * Release() 'this' again. Doing so will temporarily increment and - * decrement the refcount. (Only a logic error would make one try to - * keep a permanent hold on 'this'.) To prevent re-entering the - * destructor, we make sure that no balanced refcounting can return - * the refcount to |0|. - */ -#define NS_IMPL_RELEASE(_class) \ - NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this)) - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Often you have to cast an implementation pointer, e.g., |this|, to an - * |nsISupports*|, but because you have multiple inheritance, a simple cast - * is ambiguous. One could simply say, e.g., (given a base |nsIBase|), - * |NS_STATIC_CAST(nsIBase*, this)|; but that disguises the fact that what - * you are really doing is disambiguating the |nsISupports|. You could make - * that more obvious with a double cast, e.g., |NS_STATIC_CAST(nsISupports*, - * NS_STATIC_CAST(nsIBase*, this))|, but that is bulky and harder to read... - * - * The following macro is clean, short, and obvious. In the example above, - * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|. - */ - -#define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \ - NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(__unambiguousBase, __expr)) - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef NS_DEBUG - -/* - * Adding this debug-only function as per bug #26803. If you are debugging - * and this function returns wrong refcounts, fix the objects |AddRef()| and - * |Release()| to do the right thing. - * - * Of course, this function is only available for debug builds. - */ - -inline -nsrefcnt -NS_DebugGetRefCount( nsISupports* obj ) - // Warning: don't apply this to an object whose refcount is - // |0| or not yet initialized ... it may be destroyed. - { - nsrefcnt ref_count = 0; - - if ( obj ) - { - // |AddRef()| and |Release()| are supposed to return - // the new refcount of the object - obj->AddRef(); - ref_count = obj->Release(); - // Can't use |NS_[ADDREF|RELEASE]| since (a) they _don't_ return - // the refcount, and (b) we don't want to log these guaranteed - // balanced calls. - - NS_ASSERTION(ref_count, - "Oops! Calling |NS_DebugGetRefCount()| probably just " - "destroyed this object."); - } - - return ref_count; - } - +#ifndef nsISupportsImpl_h__ +#include "nsISupportsImpl.h" #endif - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Some convenience macros for implementing QueryInterface - */ - -/** - * This implements query interface with two assumptions: First, the - * class in question implements nsISupports and its own interface and - * nothing else. Second, the implementation of the class's primary - * inheritance chain leads to its own interface. - * - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_QUERY_HEAD(_class) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - NS_ASSERTION(aInstancePtr, \ - "QueryInterface requires a non-NULL destination!"); \ - if ( !aInstancePtr ) \ - return NS_ERROR_NULL_POINTER; \ - nsISupports* foundInterface; - -#define NS_IMPL_QUERY_BODY(_interface) \ - if ( aIID.Equals(NS_GET_IID(_interface)) ) \ - foundInterface = NS_STATIC_CAST(_interface*, this); \ - else - -#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) \ - if ( aIID.Equals(NS_GET_IID(_interface)) ) \ - foundInterface = NS_STATIC_CAST(_interface*, \ - NS_STATIC_CAST(_implClass*, this)); \ - else - -#define NS_IMPL_QUERY_TAIL_GUTS \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - status = NS_NOINTERFACE; \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#define NS_IMPL_QUERY_TAIL(_supports_interface) \ - NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \ - NS_IMPL_QUERY_TAIL_GUTS - - - /* - This is the new scheme. Using this notation now will allow us to switch to - a table driven mechanism when it's ready. Note the difference between this - and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism. You must - explicitly mention |nsISupports| when using the interface maps. - */ -#define NS_INTERFACE_MAP_BEGIN(_implClass) NS_IMPL_QUERY_HEAD(_implClass) -#define NS_INTERFACE_MAP_ENTRY(_interface) NS_IMPL_QUERY_BODY(_interface) -#define NS_INTERFACE_MAP_END NS_IMPL_QUERY_TAIL_GUTS -#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass) \ - NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) -#define NS_INTERFACE_MAP_END_INHERITING(_baseClass) \ - NS_IMPL_QUERY_TAIL_INHERITING(_baseClass) - -#define NS_IMPL_QUERY_INTERFACE0(_class) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(nsISupports) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE1(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -/* - The following macro is deprecated. We need to switch all instances - to |NS_IMPL_QUERY_INTERFACE1|, or |NS_IMPL_QUERY_INTERFACE0| depending - on how they were using it. -*/ - -#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - if (NULL == aInstancePtr) { \ - return NS_ERROR_NULL_POINTER; \ - } \ - \ - *aInstancePtr = NULL; \ - \ - static NS_DEFINE_IID(kClassIID, _classiiddef); \ - if (aIID.Equals(kClassIID)) { \ - *aInstancePtr = (void*) this; \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(NS_GET_IID(nsISupports))) { \ - *aInstancePtr = (void*) ((nsISupports*)this); \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - return NS_NOINTERFACE; \ -} - -/** - * Convenience macro for implementing all nsISupports methods for - * a simple class. - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) - -#define NS_IMPL_ISUPPORTS0(_class) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE0(_class) - -#define NS_IMPL_ISUPPORTS1(_class, _interface) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE1(_class, _interface) - -#define NS_IMPL_ISUPPORTS2(_class, _i1, _i2) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) - -#define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) - -#define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) - -#define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) - -#define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9) - -#define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9, _i10) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9, _i10) - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Declare that you're going to inherit from something that already - * implements nsISupports, but also implements an additional interface, thus - * causing an ambiguity. In this case you don't need another mRefCnt, you - * just need to forward the definitions to the appropriate superclass. E.g. - * - * class Bar : public Foo, public nsIBar { // both provide nsISupports - * public: - * NS_DECL_ISUPPORTS_INHERITED - * ...other nsIBar and Bar methods... - * }; - */ -#define NS_DECL_ISUPPORTS_INHERITED \ -public: \ - NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_IMETHOD_(nsrefcnt) Release(void); \ - -/** - * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED - * to implement the nsISupports methods, forwarding the invocations to a - * superclass that already implements nsISupports. - * - * Note that I didn't make these inlined because they're virtual methods. - */ - -#define NS_IMPL_ADDREF_INHERITED(Class, Super) \ -NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \ -{ \ - return Super::AddRef(); \ -} \ - -#define NS_IMPL_RELEASE_INHERITED(Class, Super) \ -NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \ -{ \ - return Super::Release(); \ -} \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, i1) \ - NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_BODY(i5) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_BODY(i5) \ - NS_IMPL_QUERY_BODY(i6) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, i1) \ - NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ - -#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \ - NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ - NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ - NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ - NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -/////////////////////////////////////////////////////////////////////////////// - -/** - * - * Threadsafe implementations of the ISupports convenience macros - * - */ - -/** - * IID for the nsIsThreadsafe interface - * {88210890-47a6-11d2-bec3-00805f8a66dc} - * - * This interface is *only* used for debugging purposes to determine if - * a given component is threadsafe. - */ -#define NS_ISTHREADSAFE_IID \ - { 0x88210890, 0x47a6, 0x11d2, \ - {0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} } - -#if defined(NS_MT_SUPPORTED) - -#define NS_LOCK_INSTANCE() \ - PR_CEnterMonitor((void*)this) - -#define NS_UNLOCK_INSTANCE() \ - PR_CExitMonitor((void*)this) - -/** - * Use this macro to implement the AddRef method for a given _class - * @param _class The name of the class implementing the method - */ - -#define NS_IMPL_THREADSAFE_ADDREF(_class) \ -NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ -{ \ - NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ - nsrefcnt count; \ - count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \ - NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \ - return count; \ -} - -/** - * Use this macro to implement the Release method for a given _class - * @param _class The name of the class implementing the method - */ - -#define NS_IMPL_THREADSAFE_RELEASE(_class) \ -nsrefcnt _class::Release(void) \ -{ \ - nsrefcnt count; \ - NS_PRECONDITION(0 != mRefCnt, "dup release"); \ - count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \ - NS_LOG_RELEASE(this, count, #_class); \ - if (0 == count) { \ - mRefCnt = 1; /* stabilize */ \ - /* enable this to find non-threadsafe destructors: */ \ - /* NS_ASSERT_OWNINGTHREAD(_class); */ \ - NS_DELETEXPCOM(this); \ - return 0; \ - } \ - return count; \ -} - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Some convenience macros for implementing QueryInterface - */ - -/** - * This implements query interface with two assumptions: First, the - * class in question implements nsISupports and its own interface and - * nothing else. Second, the implementation of the class's primary - * inheritance chain leads to its own interface. - * - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ -#if defined(NS_DEBUG) -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \ - if (NULL != (_iface)) { \ - nsISupports* tmp; \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \ - (void**)&tmp)), \ - "Interface is not threadsafe"); \ - } - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - if (NULL == aInstancePtr) { \ - return NS_ERROR_NULL_POINTER; \ - } \ - \ - *aInstancePtr = NULL; \ - \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - static NS_DEFINE_IID(kClassIID, _classiiddef); \ - if (aIID.Equals(kClassIID)) { \ - *aInstancePtr = (void*) this; \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(NS_GET_IID(nsISupports))) { \ - *aInstancePtr = (void*) ((nsISupports*)this); \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(kIsThreadsafeIID)) { \ - return NS_OK; \ - } \ - return NS_NOINTERFACE; \ -} - -#else /* !NS_DEBUG */ - -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ - NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) - -#endif /* !NS_DEBUG */ - -/** - * Convenience macro for implementing all nsISupports methods for - * a simple class. - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) - -#else /* !NS_MT_SUPPORTED */ - -#define NS_LOCK_INSTANCE() - -#define NS_UNLOCK_INSTANCE() - -#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class) - -#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class) - -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ - NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) - -#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) - -#endif /* !NS_MT_SUPPORTED */ - -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_QUERY_TAIL_GUTS_THREADSAFE \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - { \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - status = aIID.Equals(kIsThreadsafeIID) ? NS_OK : NS_NOINTERFACE; \ - } \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#ifdef NS_DEBUG -#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS_THREADSAFE -#else -#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS +#ifndef nsISupportsObsolete_h__ +#include "nsISupportsObsolete.h" #endif -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(nsISupports) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) - -#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface) - -#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) - -#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) - -#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) - -#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) - -#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) - -#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) - -/////////////////////////////////////////////////////////////////////////////// -// Debugging Macros -/////////////////////////////////////////////////////////////////////////////// - /** * Macro for instantiating a new object that implements nsISupports. * Use this in your factory methods to allow for refcnt tracing. @@ -1160,8 +75,6 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ delete (_ptr); \ PR_END_MACRO - - /** * Macro for adding a reference to an interface. * @param _ptr The interface pointer. @@ -1179,7 +92,6 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ NS_LOG_ADDREF_CALL(this, AddRef(), __FILE__, __LINE__) - extern "C++" { // ...because some one is accidentally including this file inside // an |extern "C"| @@ -1195,23 +107,19 @@ ns_if_addref( T expr ) return expr ? expr->AddRef() : 0; } - } /* extern "C++" */ - -#ifdef NS_BUILD_REFCNT_LOGGING +} /* extern "C++" */ /** * Macro for adding a reference to an interface that checks for NULL. * @param _expr The interface pointer. */ +#ifdef NS_BUILD_REFCNT_LOGGING #define NS_IF_ADDREF(_expr) \ ((0 != (_expr)) \ ? NS_LOG_ADDREF_CALL((_expr), ns_if_addref(_expr), __FILE__, __LINE__) \ : 0) - #else - #define NS_IF_ADDREF(_expr) ns_if_addref(_expr) - #endif /* @@ -1293,7 +201,24 @@ ns_if_addref( T expr ) } \ PR_END_MACRO -/////////////////////////////////////////////////////////////////////////////// +/* + * Often you have to cast an implementation pointer, e.g., |this|, to an + * |nsISupports*|, but because you have multiple inheritance, a simple cast + * is ambiguous. One could simply say, e.g., (given a base |nsIBase|), + * |NS_STATIC_CAST(nsIBase*, this)|; but that disguises the fact that what + * you are really doing is disambiguating the |nsISupports|. You could make + * that more obvious with a double cast, e.g., |NS_STATIC_CAST(nsISupports*, + * NS_STATIC_CAST(nsIBase*, this))|, but that is bulky and harder to read... + * + * The following macro is clean, short, and obvious. In the example above, + * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|. + */ + +#define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \ + NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(__unambiguousBase, __expr)) + + + extern "C++" { // ...because some one is accidentally including this file inside @@ -1332,450 +257,4 @@ CallQueryInterface( T* aSource, DestinationType** aDestination ) } // extern "C++" -/////////////////////////////////////////////////////////////////////////////// -// Macros for implementing nsIClassInfo-related stuff. -/////////////////////////////////////////////////////////////////////////////// - -// include here instead of at the top because it requires the nsISupport decl -#include "nsIClassInfo.h" - -#define NS_CLASSINFO_NAME(_class) _class##_classInfoGlobal -#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper - -#define NS_DECL_CI_INTERFACE_GETTER(_class) \ - extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *, \ - nsIID ***); - -#define NS_DECL_CLASSINFO(_class) \ - NS_DECL_CI_INTERFACE_GETTER(_class) \ - nsIClassInfo *NS_CLASSINFO_NAME(_class); - -#define NS_IMPL_QUERY_CLASSINFO(_class) \ - if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) { \ - extern nsIClassInfo *NS_CLASSINFO_NAME(_class); \ - foundInterface = NS_STATIC_CAST(nsIClassInfo*, NS_CLASSINFO_NAME(_class));\ - } else - -#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \ -NS_IMETHODIMP \ -NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *count, nsIID ***array) \ -{ \ - *count = _c; \ - *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c); - -#define NS_CLASSINFO_HELPER_ENTRY(_i, _interface) \ - (*array)[_i] = (nsIID *)nsMemory::Clone(&NS_GET_IID(_interface), \ - sizeof(nsIID)); - -#define NS_CLASSINFO_HELPER_END \ - return NS_OK; \ -} - -#define NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 1) \ - NS_CLASSINFO_HELPER_ENTRY(0, _interface) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE1_CI(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS1_CI(_class, _interface) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface) \ - NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) - -#define NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 2) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS2_CI(_class, _i1, _i2) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ - NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) - -#define NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 3) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS3_CI(_class, _i1, _i2, _i3) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ - NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) - -#define NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 4) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 5) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 6) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 7) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) - -#define NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 8) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) - -#define NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 9) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) \ - NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) - -#define NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 10) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ - NS_CLASSINFO_HELPER_ENTRY(9, _i10) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) \ - NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking the trueness of an expression passed in within an -// interface implementation. -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_TRUE(x, ret) \ - PR_BEGIN_MACRO \ - if(NS_WARN_IF_FALSE(x, "NS_ENSURE_TRUE(" #x ") failed")) \ - return ret; \ - PR_END_MACRO - -#define NS_ENSURE_FALSE(x, ret) \ - NS_ENSURE_TRUE(!(x), ret) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking results -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_SUCCESS(res, ret) \ - NS_ENSURE_TRUE(NS_SUCCEEDED(res), ret) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking state and arguments upon entering interface boundaries -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_ARG(arg) \ - NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_POINTER(arg) \ - NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER) - -#define NS_ENSURE_ARG_MIN(arg, min) \ - NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_MAX(arg, max) \ - NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_RANGE(arg, min, max) \ - NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_STATE(state) \ - NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED) - -#define NS_ENSURE_NO_AGGREGATION(outer) \ - NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION) - -#define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \ - NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG) - - -/** - * Macro to free all elements of an XPCOM array of a given size using - * freeFunc, then frees the array itself using nsMemory::Free(). - * - * Note that this macro (and its wrappers) can be used to deallocate a - * partially- or completely-built array while unwinding an error - * condition inside the XPCOM routine that was going to return the - * array. For this to work on a partially-built array, your code - * needs to be building the array from index 0 upwards, and simply - * pass the number of elements that have already been built (and thus - * need to be freed) as |size|. - * - * Thanks to for suggesting this form, which - * allows the macro to be used with NS_RELEASE / NS_RELEASE_IF in - * addition to nsMemory::Free. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - * @param freeFunc The function or macro to be used to free it. - * For arrays of nsISupports (or any class derived - * from it), NS_IF_RELEASE (or NS_RELEASE) should be - * passed as freeFunc. For most (all?) other pointer - * types (including XPCOM strings and wstrings), - * nsMemory::Free should be used, since the - * shared-allocator (nsMemory) is what will have been - * used to allocate the memory. - */ -#define NS_FREE_XPCOM_POINTER_ARRAY(size, array, freeFunc) \ - PR_BEGIN_MACRO \ - PRInt32 iter_ = PRInt32(size); \ - while (--iter_ >= 0) \ - freeFunc((array)[iter_]); \ - nsMemory::Free((array)); \ - PR_END_MACRO - -// convenience macros for commonly used calls. mmmmm. syntactic sugar. - -/** - * Macro to free arrays of non-refcounted objects allocated by the - * shared allocator (nsMemory) such as strings and wstrings. A - * convenience wrapper around NS_FREE_XPCOM_POINTER_ARRAY. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - */ -#define NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(size, array) \ - NS_FREE_XPCOM_POINTER_ARRAY((size), (array), nsMemory::Free) - -/** - * Macro to free an array of pointers to nsISupports (or classes - * derived from it). A convenience wrapper around - * NS_FREE_XPCOM_POINTER_ARRAY. - * - * Note that if you know that none of your nsISupports pointers are - * going to be 0, you can gain a bit of speed by calling - * NS_FREE_XPCOM_POINTER_ARRAY directly and using NS_RELEASE as your - * free function. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - */ -#define NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(size, array) \ - NS_FREE_XPCOM_POINTER_ARRAY((size), (array), NS_IF_RELEASE) - - -/////////////////////////////////////////////////////////////////////////////// - #endif /* __nsISupportsUtils_h */ diff --git a/xpcom/base/nscore.h b/xpcom/base/nscore.h index 27a1a7a2d8b..b827c7a7be9 100644 --- a/xpcom/base/nscore.h +++ b/xpcom/base/nscore.h @@ -22,124 +22,118 @@ #ifndef nscore_h___ #define nscore_h___ -#ifdef _WIN32 -#define NS_WIN32 1 -#endif - -#if defined(__unix) -#define NS_UNIX 1 -#endif - -#if defined(XP_OS2) -#define NS_OS2 1 -#endif - +/** + * Incorporate the core NSPR data types which XPCOM uses. + */ #include "prtypes.h" -#ifdef __cplusplus -#include "nsDebug.h" + +/* Core XPCOM declarations. */ + +/** + * Macros defining the target platform... + */ +#ifdef _WIN32 +#define NS_WIN32 1 + +#elif defined(__unix) +#define NS_UNIX 1 + +#elif defined(XP_OS2) +#define NS_OS2 1 #endif - -/* The preferred symbol for null. */ -#define nsnull 0 - -/* Define brackets for protecting C code from C++ */ -#ifdef __cplusplus -#define NS_BEGIN_EXTERN_C extern "C" { -#define NS_END_EXTERN_C } -#else -#define NS_BEGIN_EXTERN_C -#define NS_END_EXTERN_C -#endif - /*----------------------------------------------------------------------*/ /* Import/export defines */ #ifdef NS_WIN32 + #define NS_IMPORT _declspec(dllimport) #define NS_IMPORT_(type) type _declspec(dllimport) __stdcall #define NS_EXPORT _declspec(dllexport) -/* XXX NS_EXPORT_ defined in nsCOm.h (xpcom) differs in where the __declspec - is placed. It needs to be done this way to make the 4.x compiler happy... */ -#undef NS_EXPORT_ #define NS_EXPORT_(type) type _declspec(dllexport) __stdcall +#define NS_IMETHOD_(type) virtual type __stdcall +#define NS_IMETHODIMP_(type) type __stdcall +#define NS_METHOD_(type) type __stdcall +#define NS_CALLBACK_(_type, _name) _type (__stdcall * _name) + #elif defined(XP_MAC) #define NS_IMPORT #define NS_IMPORT_(type) type - -/* XXX NS_EXPORT_ defined in nsCom.h actually does an export. Here it's just sugar. */ -#undef NS_EXPORT -#undef NS_EXPORT_ - #define NS_EXPORT __declspec(export) #define NS_EXPORT_(type) __declspec(export) type +#define NS_IMETHOD_(type) virtual type +#define NS_IMETHODIMP_(type) type +#define NS_METHOD_(type) type +#define NS_CALLBACK_(_type, _name) _type (* _name) + +#elif defined(XP_OS2) -#else -/* XXX do something useful? */ #define NS_IMPORT #define NS_IMPORT_(type) type #define NS_EXPORT #define NS_EXPORT_(type) type +#define NS_IMETHOD_(type) virtual type +#define NS_IMETHODIMP_(type) type +#define NS_METHOD_(type) type +#define NS_CALLBACK_(_type, _name) _type ( _System * _name) + +#else + +#define NS_IMPORT +#define NS_IMPORT_(type) type +#define NS_EXPORT +#define NS_EXPORT_(type) type +#define NS_IMETHOD_(type) virtual type +#define NS_IMETHODIMP_(type) type +#define NS_METHOD_(type) type +#define NS_CALLBACK_(_type, _name) _type (* _name) #endif -#ifdef _IMPL_NS_BASE -#define NS_BASE NS_EXPORT +/** + * Generic API modifiers which return the standard XPCOM nsresult type + */ +#define NS_IMETHOD NS_IMETHOD_(nsresult) +#define NS_IMETHODIMP NS_IMETHODIMP_(nsresult) +#define NS_METHOD NS_METHOD_(nsresult) +#define NS_CALLBACK(_name) NS_CALLBACK_(nsresult, _name) + +/** + * Import/Export macros for XPCOM APIs + */ + +#ifdef _IMPL_NS_COM +#define NS_COM NS_EXPORT #else -#define NS_BASE NS_IMPORT +#define NS_COM NS_IMPORT #endif -#ifdef _IMPL_NS_NET -#define NS_NET NS_EXPORT +/** + * NS_NO_VTABLE is emitted by xpidl in interface declarations whenever + * xpidl can determine that the interface can't contain a constructor. + * This results in some space savings and possible runtime savings - + * see bug 49416. We undefine it first, as xpidl-generated headers + * define it for IDL uses that don't include this file. + */ +#ifdef NS_NO_VTABLE +#undef NS_NO_VTABLE +#endif +#if defined(_MSC_VER) && _MSC_VER >= 1100 +#define NS_NO_VTABLE __declspec(novtable) #else -#define NS_NET NS_IMPORT +#define NS_NO_VTABLE #endif -#ifdef _IMPL_NS_DOM -#define NS_DOM NS_EXPORT -#else -#define NS_DOM NS_IMPORT -#endif -#ifdef _IMPL_NS_WIDGET -#define NS_WIDGET NS_EXPORT -#else -#define NS_WIDGET NS_IMPORT -#endif +/** + * Generic XPCOM result data type + */ +typedef PRUint32 nsresult; -#ifdef _IMPL_NS_VIEW -#define NS_VIEW NS_EXPORT -#else -#define NS_VIEW NS_IMPORT -#endif - -#ifdef _IMPL_NS_GFXNONXP -#define NS_GFXNONXP NS_EXPORT -#define NS_GFXNONXP_(type) NS_EXPORT_(type) -#else -#define NS_GFXNONXP NS_IMPORT -#define NS_GFXNONXP_(type) NS_IMPORT_(type) -#endif - -#ifdef _IMPL_NS_GFX -#define NS_GFX NS_EXPORT -#define NS_GFX_(type) NS_EXPORT_(type) -#else -#define NS_GFX NS_IMPORT -#define NS_GFX_(type) NS_IMPORT_(type) -#endif - -#ifdef _IMPL_NS_PLUGIN -#define NS_PLUGIN NS_EXPORT -#else -#define NS_PLUGIN NS_IMPORT -#endif - -#ifdef _IMPL_NS_APPSHELL -#define NS_APPSHELL NS_EXPORT -#else -#define NS_APPSHELL NS_IMPORT -#endif +/** + * The preferred symbol for null. + */ +#define nsnull 0 /* ------------------------------------------------------------------------ */ @@ -207,7 +201,7 @@ * commercial build. When this is fixed there will be no need for the * |NS_REINTERPRET_CAST| in nsLiteralString.h either. */ - #if defined(HAVE_CPP_2BYTE_WCHAR_T) && (defined(XP_WIN) || defined(XP_MAC)) + #if defined(HAVE_CPP_2BYTE_WCHAR_T) && (defined(NS_WIN32) || defined(XP_MAC)) typedef wchar_t PRUnichar; #else typedef PRUint16 PRUnichar; @@ -283,7 +277,7 @@ "straight", no macro. */ #endif - + /* * Use these macros to do 64bit safe pointer conversions. */ @@ -291,4 +285,11 @@ #define NS_PTR_TO_INT32(x) ((char *)(x) - (char *)0) #define NS_INT32_TO_PTR(x) ((void *)((char *)0 + (x))) +/* Include depricated APIs... */ + +#ifndef nsComObsolete_h__ +#include "nsComObsolete.h" +#endif + #endif /* nscore_h___ */ + diff --git a/xpcom/base/nsrootidl.idl b/xpcom/base/nsrootidl.idl index 4a677fd9f2b..28b7fed9447 100644 --- a/xpcom/base/nsrootidl.idl +++ b/xpcom/base/nsrootidl.idl @@ -21,7 +21,10 @@ * Dan Rosen */ -/* Root idl declarations to be used by all. */ +/** + * Root idl declarations to be used by all. + * @status FROZEN + */ %{C++ diff --git a/xpcom/glue/nsDebug.h b/xpcom/glue/nsDebug.h index 144f67d95bf..60b977a7a33 100644 --- a/xpcom/glue/nsDebug.h +++ b/xpcom/glue/nsDebug.h @@ -23,8 +23,13 @@ #ifndef nsDebug_h___ #define nsDebug_h___ -#include "nsCom.h" -#include "prtypes.h" +#ifndef nscore_h___ +#include "nscore.h" +#endif + +#ifndef nsError_h__ +#include "nsError.h" +#endif #ifdef DEBUG #define NS_DEBUG @@ -299,4 +304,56 @@ if (!(expr)) \ #endif /* ! NS_DEBUG */ #endif /* __cplusplus */ + +// Macros for checking the trueness of an expression passed in within an +// interface implementation. These need to be compiled regardless of the +// NS_DEBUG flag +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_TRUE(x, ret) \ + PR_BEGIN_MACRO \ + if(NS_WARN_IF_FALSE(x, "NS_ENSURE_TRUE(" #x ") failed")) \ + return ret; \ + PR_END_MACRO + +#define NS_ENSURE_FALSE(x, ret) \ + NS_ENSURE_TRUE(!(x), ret) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for checking results +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_SUCCESS(res, ret) \ + NS_ENSURE_TRUE(NS_SUCCEEDED(res), ret) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for checking state and arguments upon entering interface boundaries +/////////////////////////////////////////////////////////////////////////////// + +#define NS_ENSURE_ARG(arg) \ + NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_POINTER(arg) \ + NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER) + +#define NS_ENSURE_ARG_MIN(arg, min) \ + NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_MAX(arg, max) \ + NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_ARG_RANGE(arg, min, max) \ + NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG) + +#define NS_ENSURE_STATE(state) \ + NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED) + +#define NS_ENSURE_NO_AGGREGATION(outer) \ + NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION) + +#define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \ + NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG) + +/////////////////////////////////////////////////////////////////////////////// + #endif /* nsDebug_h___ */ diff --git a/xpcom/glue/nsISupportsImpl.h b/xpcom/glue/nsISupportsImpl.h new file mode 100644 index 00000000000..b1f0c0effef --- /dev/null +++ b/xpcom/glue/nsISupportsImpl.h @@ -0,0 +1,976 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#ifndef nsISupportsImpl_h__ +#define nsISupportsImpl_h__ + +#ifndef nscore_h___ +#include "nscore.h" +#endif + +#ifndef nsISupportsBase_h__ +#include "nsISupportsBase.h" +#endif + +#include "pratom.h" /* needed for PR_AtomicIncrement and PR_AtomicDecrement */ +#include "nsTraceRefcnt.h" + +//////////////////////////////////////////////////////////////////////////////// +// Macros to help detect thread-safety: + +#if defined(NS_DEBUG) && defined(NS_MT_SUPPORTED) + +extern "C" NS_EXPORT void* NS_CurrentThread(void); +extern "C" NS_EXPORT void NS_CheckThreadSafe(void* owningThread, + const char* msg); + +#define NS_DECL_OWNINGTHREAD void* _mOwningThread; +#define NS_IMPL_OWNINGTHREAD() (_mOwningThread = NS_CurrentThread()) +#define NS_ASSERT_OWNINGTHREAD(_class) NS_CheckThreadSafe(_mOwningThread, \ + #_class \ + " not thread-safe") + +#else // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) + +#define NS_DECL_OWNINGTHREAD /* nothing */ +#define NS_IMPL_OWNINGTHREAD() ((void)0) +#define NS_ASSERT_OWNINGTHREAD(_class) ((void)0) + +#endif // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Declare the reference count variable and the implementations of the + * AddRef and QueryInterface methods. + */ + +#define NS_DECL_ISUPPORTS \ +public: \ + NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_IMETHOD_(nsrefcnt) Release(void); \ +protected: \ + nsrefcnt mRefCnt; \ + NS_DECL_OWNINGTHREAD \ +public: + + +/////////////////////////////////////////////////////////////////////////////// + +/** + * Initialize the reference count variable. Add this to each and every + * constructor you implement. + */ +#define NS_INIT_ISUPPORTS() (mRefCnt = 0, NS_IMPL_OWNINGTHREAD()) + +/** + * Use this macro to implement the AddRef method for a given _class + * @param _class The name of the class implementing the method + */ +#define NS_IMPL_ADDREF(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ +{ \ + NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ + NS_ASSERT_OWNINGTHREAD(_class); \ + ++mRefCnt; \ + NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \ + return mRefCnt; \ +} + +/** + * Use this macro to implement the Release method for a given + * _class. + * @param _class The name of the class implementing the method + * @param _destroy A statement that is executed when the object's + * refcount drops to zero. + * + * For example, + * + * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this)) + * + * will cause + * + * Destroy(this); + * + * to be invoked when the object's refcount drops to zero. This + * allows for arbitrary teardown activity to occur (e.g., deallocation + * of object allocated with placement new). + */ +#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \ +NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ +{ \ + NS_PRECONDITION(0 != mRefCnt, "dup release"); \ + NS_ASSERT_OWNINGTHREAD(_class); \ + --mRefCnt; \ + NS_LOG_RELEASE(this, mRefCnt, #_class); \ + if (mRefCnt == 0) { \ + mRefCnt = 1; /* stabilize */ \ + _destroy; \ + return 0; \ + } \ + return mRefCnt; \ +} + +/** + * Use this macro to implement the Release method for a given _class + * @param _class The name of the class implementing the method + * + * A note on the 'stabilization' of the refcnt to one. At that point, + * the object's refcount will have gone to zero. The object's + * destructor may trigger code that attempts to QueryInterface() and + * Release() 'this' again. Doing so will temporarily increment and + * decrement the refcount. (Only a logic error would make one try to + * keep a permanent hold on 'this'.) To prevent re-entering the + * destructor, we make sure that no balanced refcounting can return + * the refcount to |0|. + */ +#define NS_IMPL_RELEASE(_class) \ + NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this)) + + +/////////////////////////////////////////////////////////////////////////////// + +/* + * Some convenience macros for implementing QueryInterface + */ + +/** + * This implements query interface with two assumptions: First, the + * class in question implements nsISupports and its own interface and + * nothing else. Second, the implementation of the class's primary + * inheritance chain leads to its own interface. + * + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ + +#define NS_IMPL_QUERY_HEAD(_class) \ +NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ +{ \ + NS_ASSERTION(aInstancePtr, \ + "QueryInterface requires a non-NULL destination!"); \ + if ( !aInstancePtr ) \ + return NS_ERROR_NULL_POINTER; \ + nsISupports* foundInterface; + +#define NS_IMPL_QUERY_BODY(_interface) \ + if ( aIID.Equals(NS_GET_IID(_interface)) ) \ + foundInterface = NS_STATIC_CAST(_interface*, this); \ + else + +#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) \ + if ( aIID.Equals(NS_GET_IID(_interface)) ) \ + foundInterface = NS_STATIC_CAST(_interface*, \ + NS_STATIC_CAST(_implClass*, this)); \ + else + +#define NS_IMPL_QUERY_TAIL_GUTS \ + foundInterface = 0; \ + nsresult status; \ + if ( !foundInterface ) \ + status = NS_NOINTERFACE; \ + else \ + { \ + NS_ADDREF(foundInterface); \ + status = NS_OK; \ + } \ + *aInstancePtr = foundInterface; \ + return status; \ +} + +#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \ + foundInterface = 0; \ + nsresult status; \ + if ( !foundInterface ) \ + status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \ + else \ + { \ + NS_ADDREF(foundInterface); \ + status = NS_OK; \ + } \ + *aInstancePtr = foundInterface; \ + return status; \ +} + +#define NS_IMPL_QUERY_TAIL(_supports_interface) \ + NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \ + NS_IMPL_QUERY_TAIL_GUTS + + + /* + This is the new scheme. Using this notation now will allow us to switch to + a table driven mechanism when it's ready. Note the difference between this + and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism. You must + explicitly mention |nsISupports| when using the interface maps. + */ +#define NS_INTERFACE_MAP_BEGIN(_implClass) NS_IMPL_QUERY_HEAD(_implClass) +#define NS_INTERFACE_MAP_ENTRY(_interface) NS_IMPL_QUERY_BODY(_interface) +#define NS_INTERFACE_MAP_END NS_IMPL_QUERY_TAIL_GUTS +#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass) \ + NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) +#define NS_INTERFACE_MAP_END_INHERITING(_baseClass) \ + NS_IMPL_QUERY_TAIL_INHERITING(_baseClass) + +#define NS_IMPL_QUERY_INTERFACE0(_class) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(nsISupports) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE1(_class, _i1) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY(_i10) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0 NS_IMPL_QUERY_INTERFACE0 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1 NS_IMPL_QUERY_INTERFACE1 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2 NS_IMPL_QUERY_INTERFACE2 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3 NS_IMPL_QUERY_INTERFACE3 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4 NS_IMPL_QUERY_INTERFACE4 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5 NS_IMPL_QUERY_INTERFACE5 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6 NS_IMPL_QUERY_INTERFACE6 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7 NS_IMPL_QUERY_INTERFACE7 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8 NS_IMPL_QUERY_INTERFACE8 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9 NS_IMPL_QUERY_INTERFACE9 +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10 NS_IMPL_QUERY_INTERFACE10 + +/** + * Declare that you're going to inherit from something that already + * implements nsISupports, but also implements an additional interface, thus + * causing an ambiguity. In this case you don't need another mRefCnt, you + * just need to forward the definitions to the appropriate superclass. E.g. + * + * class Bar : public Foo, public nsIBar { // both provide nsISupports + * public: + * NS_DECL_ISUPPORTS_INHERITED + * ...other nsIBar and Bar methods... + * }; + */ +#define NS_DECL_ISUPPORTS_INHERITED \ +public: \ + NS_IMETHOD QueryInterface(REFNSIID aIID, \ + void** aInstancePtr); \ + NS_IMETHOD_(nsrefcnt) AddRef(void); \ + NS_IMETHOD_(nsrefcnt) Release(void); \ + +/** + * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED + * to implement the nsISupports methods, forwarding the invocations to a + * superclass that already implements nsISupports. + * + * Note that I didn't make these inlined because they're virtual methods. + */ + +#define NS_IMPL_ADDREF_INHERITED(Class, Super) \ +NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \ +{ \ + return Super::AddRef(); \ +} \ + +#define NS_IMPL_RELEASE_INHERITED(Class, Super) \ +NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \ +{ \ + return Super::Release(); \ +} \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_BODY(i5) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \ + NS_IMPL_QUERY_HEAD(Class) \ + NS_IMPL_QUERY_BODY(i1) \ + NS_IMPL_QUERY_BODY(i2) \ + NS_IMPL_QUERY_BODY(i3) \ + NS_IMPL_QUERY_BODY(i4) \ + NS_IMPL_QUERY_BODY(i5) \ + NS_IMPL_QUERY_BODY(i6) \ + NS_IMPL_QUERY_TAIL_INHERITING(Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, i1) \ + NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ + +#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \ + NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ + NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ + NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ + NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ + NS_IMPL_ADDREF_INHERITED(Class, Super) \ + NS_IMPL_RELEASE_INHERITED(Class, Super) \ + +/////////////////////////////////////////////////////////////////////////////// +/** + * + * Threadsafe implementations of the ISupports convenience macros + * + */ + +#if defined(NS_MT_SUPPORTED) + +/** + * Use this macro to implement the AddRef method for a given _class + * @param _class The name of the class implementing the method + */ + +#define NS_IMPL_THREADSAFE_ADDREF(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ +{ \ + NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ + nsrefcnt count; \ + count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \ + NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \ + return count; \ +} + +/** + * Use this macro to implement the Release method for a given _class + * @param _class The name of the class implementing the method + */ + +#define NS_IMPL_THREADSAFE_RELEASE(_class) \ +nsrefcnt _class::Release(void) \ +{ \ + nsrefcnt count; \ + NS_PRECONDITION(0 != mRefCnt, "dup release"); \ + count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \ + NS_LOG_RELEASE(this, count, #_class); \ + if (0 == count) { \ + mRefCnt = 1; /* stabilize */ \ + /* enable this to find non-threadsafe destructors: */ \ + /* NS_ASSERT_OWNINGTHREAD(_class); */ \ + NS_DELETEXPCOM(this); \ + return 0; \ + } \ + return count; \ +} + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ +NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ +{ \ + if (NULL == aInstancePtr) { \ + return NS_ERROR_NULL_POINTER; \ + } \ + \ + *aInstancePtr = NULL; \ + \ + if (aIID.Equals(NS_GET_IID(nsISupports))) { \ + *aInstancePtr = (void*) ((nsISupports*)this); \ + NS_ADDREF_THIS(); \ + return NS_OK; \ + } \ + return NS_NOINTERFACE; \ +} + +#else // defined(NS_MT_SUPPORTED) + +/** + * Convenience macro for implementing all nsISupports methods for + * a simple class. + * @param _class The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + */ + +#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) + +#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class) + +#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class) + +#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ + NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) + +#endif /* !NS_MT_SUPPORTED */ + +#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) + +#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface) + +#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) + +#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) + +#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) + +#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) + +#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) + +#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) + +#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) + +#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) + +#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_IMPL_THREADSAFE_ADDREF(_class) \ + NS_IMPL_THREADSAFE_RELEASE(_class) \ + NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) + +/////////////////////////////////////////////////////////////////////////////// +// Macros for implementing nsIClassInfo-related stuff. +/////////////////////////////////////////////////////////////////////////////// + +// include here instead of at the top because it requires the nsISupport decl +#include "nsIClassInfo.h" + +#define NS_CLASSINFO_NAME(_class) _class##_classInfoGlobal +#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper + +#define NS_DECL_CI_INTERFACE_GETTER(_class) \ + extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *, \ + nsIID ***); + +#define NS_DECL_CLASSINFO(_class) \ + NS_DECL_CI_INTERFACE_GETTER(_class) \ + nsIClassInfo *NS_CLASSINFO_NAME(_class); + +#define NS_IMPL_QUERY_CLASSINFO(_class) \ + if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) { \ + extern nsIClassInfo *NS_CLASSINFO_NAME(_class); \ + foundInterface = NS_STATIC_CAST(nsIClassInfo*, NS_CLASSINFO_NAME(_class));\ + } else + +#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \ +NS_IMETHODIMP \ +NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *count, nsIID ***array) \ +{ \ + *count = _c; \ + *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c); + +#define NS_CLASSINFO_HELPER_ENTRY(_i, _interface) \ + (*array)[_i] = (nsIID *)nsMemory::Clone(&NS_GET_IID(_interface), \ + sizeof(nsIID)); + +#define NS_CLASSINFO_HELPER_END \ + return NS_OK; \ +} + +#define NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 1) \ + NS_CLASSINFO_HELPER_ENTRY(0, _interface) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE1_CI(_class, _i1) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS1_CI(_class, _interface) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface) \ + NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) + +#define NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 2) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS2_CI(_class, _i1, _i2) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ + NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) + +#define NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 3) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS3_CI(_class, _i1, _i2, _i3) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ + NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) + +#define NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 4) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ + NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) + +#define NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 5) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ + NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) + +#define NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 6) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ + NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) + +#define NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 7) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ + NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) + +#define NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 8) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ + NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) + +#define NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 9) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) \ + NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9) + +#define NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_CLASSINFO_HELPER_BEGIN(_class, 10) \ + NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ + NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ + NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ + NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ + NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ + NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ + NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ + NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ + NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ + NS_CLASSINFO_HELPER_ENTRY(9, _i10) \ + NS_CLASSINFO_HELPER_END + +#define NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ + _i7, _i8, _i9, _i10) \ + NS_INTERFACE_MAP_BEGIN(_class) \ + NS_INTERFACE_MAP_ENTRY(_i1) \ + NS_INTERFACE_MAP_ENTRY(_i2) \ + NS_INTERFACE_MAP_ENTRY(_i3) \ + NS_INTERFACE_MAP_ENTRY(_i4) \ + NS_INTERFACE_MAP_ENTRY(_i5) \ + NS_INTERFACE_MAP_ENTRY(_i6) \ + NS_INTERFACE_MAP_ENTRY(_i7) \ + NS_INTERFACE_MAP_ENTRY(_i8) \ + NS_INTERFACE_MAP_ENTRY(_i9) \ + NS_INTERFACE_MAP_ENTRY(_i10) \ + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ + NS_IMPL_QUERY_CLASSINFO(_class) \ + NS_INTERFACE_MAP_END + +#define NS_IMPL_ISUPPORTS10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) \ + NS_IMPL_ADDREF(_class) \ + NS_IMPL_RELEASE(_class) \ + NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) \ + NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ + _i8, _i9, _i10) + +#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS + +#endif diff --git a/xpcom/glue/nsISupportsUtils.h b/xpcom/glue/nsISupportsUtils.h index 7bc23f18ef4..d5919d7c386 100644 --- a/xpcom/glue/nsISupportsUtils.h +++ b/xpcom/glue/nsISupportsUtils.h @@ -23,1118 +23,33 @@ * Dan Mosedale */ -#ifndef __nsISupportsUtils_h -#define __nsISupportsUtils_h - -/***************************************************************************/ -/* this section copied from the hand written nsISupports.h */ +#ifndef nsISupportsUtils_h__ +#define nsISupportsUtils_h__ +#ifndef nscore_h___ #include "nscore.h" - // for |NS_SPECIALIZE_TEMPLATE|, and the casts, et al +#endif -#include "nsDebug.h" -#include "nsID.h" -#include "nsIID.h" +#ifndef nsISupportsBase_h__ +#include "nsISupportsBase.h" +#endif + +#ifndef nsError_h__ #include "nsError.h" -#include "pratom.h" /* needed for PR_AtomicIncrement and PR_AtomicDecrement */ - -#if defined(NS_MT_SUPPORTED) -#include "prcmon.h" -#endif /* NS_MT_SUPPORTED */ - -/*@{*/ - -/////////////////////////////////////////////////////////////////////////////// - -/** - * IID for the nsISupports interface - * {00000000-0000-0000-c000-000000000046} - * - * To maintain binary compatibility with COM's nsIUnknown, we define the IID - * of nsISupports to be the same as that of COM's nsIUnknown. - */ -#define NS_ISUPPORTS_IID \ - { 0x00000000, 0x0000, 0x0000, \ - {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} } - -/** - * Reference count values - * - * This is type of return value from Addref() and Release() in nsISupports. - * nsIUnknown of COM returns a unsigned long from equivalent functions. - * To maintain binary compatibility of nsISupports with nsIUnknown, we are - * doing this ifdeffing. - */ -#if defined(XP_WIN) && PR_BYTES_PER_LONG == 4 -typedef unsigned long nsrefcnt; -#else -typedef PRUint32 nsrefcnt; #endif -/** - * NS_NO_VTABLE is emitted by xpidl in interface declarations whenever - * xpidl can determine that the interface can't contain a constructor. - * This results in some space savings and possible runtime savings - - * see bug 49416. We undefine it first, as xpidl-generated headers - * define it for IDL uses that don't include this file. - */ -#ifdef NS_NO_VTABLE -#undef NS_NO_VTABLE -#endif -#if defined(_MSC_VER) && _MSC_VER >= 1100 -#define NS_NO_VTABLE __declspec(novtable) -#else -#define NS_NO_VTABLE +#ifndef nsDebug_h___ +#include "nsDebug.h" #endif -#include "nsTraceRefcnt.h" - -/** - * Basic component object model interface. Objects which implement - * this interface support runtime interface discovery (QueryInterface) - * and a reference counted memory model (AddRef/Release). This is - * modelled after the win32 IUnknown API. - */ -class NS_NO_VTABLE nsISupports { -public: - - /** - * @name Methods - */ - - //@{ - /** - * A run time mechanism for interface discovery. - * @param aIID [in] A requested interface IID - * @param aInstancePtr [out] A pointer to an interface pointer to - * receive the result. - * @return NS_OK if the interface is supported by the associated - * instance, NS_NOINTERFACE if it is not. - * NS_ERROR_INVALID_POINTER if aInstancePtr is NULL. - */ - NS_IMETHOD QueryInterface(REFNSIID aIID, - void** aInstancePtr) = 0; - /** - * Increases the reference count for this interface. - * The associated instance will not be deleted unless - * the reference count is returned to zero. - * - * @return The resulting reference count. - */ - NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; - - /** - * Decreases the reference count for this interface. - * Generally, if the reference count returns to zero, - * the associated instance is deleted. - * - * @return The resulting reference count. - */ - NS_IMETHOD_(nsrefcnt) Release(void) = 0; - - //@} -}; - -/*@}*/ - -/***************************************************************************/ - -/** - * A macro to build the static const IID accessor method - */ - -#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \ - static const nsIID& GetIID() {static const nsIID iid = the_iid; return iid;} - -/** - * A macro to build the static const CID accessor method - */ - -#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \ - static const nsID& GetCID() {static const nsID cid = the_cid; return cid;} - -//////////////////////////////////////////////////////////////////////////////// -// Macros to help detect thread-safety: - -#if defined(NS_DEBUG) && defined(NS_MT_SUPPORTED) - -extern "C" NS_EXPORT void* NS_CurrentThread(void); -extern "C" NS_EXPORT void NS_CheckThreadSafe(void* owningThread, - const char* msg); - -#define NS_DECL_OWNINGTHREAD void* _mOwningThread; -#define NS_IMPL_OWNINGTHREAD() (_mOwningThread = NS_CurrentThread()) -#define NS_ASSERT_OWNINGTHREAD(_class) NS_CheckThreadSafe(_mOwningThread, \ - #_class \ - " not thread-safe") - -#else // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) - -#define NS_DECL_OWNINGTHREAD /* nothing */ -#define NS_IMPL_OWNINGTHREAD() ((void)0) -#define NS_ASSERT_OWNINGTHREAD(_class) ((void)0) - -#endif // !(defined(NS_DEBUG) && defined(NS_MT_SUPPORTED)) - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Some convenience macros for implementing AddRef and Release - */ - -/** - * Declare the reference count variable and the implementations of the - * AddRef and QueryInterface methods. - */ - -#define NS_DECL_ISUPPORTS \ -public: \ - NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_IMETHOD_(nsrefcnt) Release(void); \ -protected: \ - nsrefcnt mRefCnt; \ - NS_DECL_OWNINGTHREAD \ -public: - -#define NS_DECL_ISUPPORTS_EXPORTED \ -public: \ - NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \ -protected: \ - nsrefcnt mRefCnt; \ - NS_DECL_OWNINGTHREAD \ -public: - -/////////////////////////////////////////////////////////////////////////////// - -/** - * Initialize the reference count variable. Add this to each and every - * constructor you implement. - */ -#define NS_INIT_REFCNT() (mRefCnt = 0, NS_IMPL_OWNINGTHREAD()) -#define NS_INIT_ISUPPORTS() NS_INIT_REFCNT() // what it should have been called in the first place - -/** - * Use this macro to implement the AddRef method for a given _class - * @param _class The name of the class implementing the method - */ -#define NS_IMPL_ADDREF(_class) \ -NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ -{ \ - NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ - NS_ASSERT_OWNINGTHREAD(_class); \ - ++mRefCnt; \ - NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \ - return mRefCnt; \ -} - -/** - * Use this macro to implement the Release method for a given - * _class. - * @param _class The name of the class implementing the method - * @param _destroy A statement that is executed when the object's - * refcount drops to zero. - * - * For example, - * - * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this)) - * - * will cause - * - * Destroy(this); - * - * to be invoked when the object's refcount drops to zero. This - * allows for arbitrary teardown activity to occur (e.g., deallocation - * of object allocated with placement new). - */ -#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \ -NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ -{ \ - NS_PRECONDITION(0 != mRefCnt, "dup release"); \ - NS_ASSERT_OWNINGTHREAD(_class); \ - --mRefCnt; \ - NS_LOG_RELEASE(this, mRefCnt, #_class); \ - if (mRefCnt == 0) { \ - mRefCnt = 1; /* stabilize */ \ - _destroy; \ - return 0; \ - } \ - return mRefCnt; \ -} - -/** - * Use this macro to implement the Release method for a given _class - * @param _class The name of the class implementing the method - * - * A note on the 'stabilization' of the refcnt to one. At that point, - * the object's refcount will have gone to zero. The object's - * destructor may trigger code that attempts to QueryInterface() and - * Release() 'this' again. Doing so will temporarily increment and - * decrement the refcount. (Only a logic error would make one try to - * keep a permanent hold on 'this'.) To prevent re-entering the - * destructor, we make sure that no balanced refcounting can return - * the refcount to |0|. - */ -#define NS_IMPL_RELEASE(_class) \ - NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this)) - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Often you have to cast an implementation pointer, e.g., |this|, to an - * |nsISupports*|, but because you have multiple inheritance, a simple cast - * is ambiguous. One could simply say, e.g., (given a base |nsIBase|), - * |NS_STATIC_CAST(nsIBase*, this)|; but that disguises the fact that what - * you are really doing is disambiguating the |nsISupports|. You could make - * that more obvious with a double cast, e.g., |NS_STATIC_CAST(nsISupports*, - * NS_STATIC_CAST(nsIBase*, this))|, but that is bulky and harder to read... - * - * The following macro is clean, short, and obvious. In the example above, - * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|. - */ - -#define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \ - NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(__unambiguousBase, __expr)) - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef NS_DEBUG - -/* - * Adding this debug-only function as per bug #26803. If you are debugging - * and this function returns wrong refcounts, fix the objects |AddRef()| and - * |Release()| to do the right thing. - * - * Of course, this function is only available for debug builds. - */ - -inline -nsrefcnt -NS_DebugGetRefCount( nsISupports* obj ) - // Warning: don't apply this to an object whose refcount is - // |0| or not yet initialized ... it may be destroyed. - { - nsrefcnt ref_count = 0; - - if ( obj ) - { - // |AddRef()| and |Release()| are supposed to return - // the new refcount of the object - obj->AddRef(); - ref_count = obj->Release(); - // Can't use |NS_[ADDREF|RELEASE]| since (a) they _don't_ return - // the refcount, and (b) we don't want to log these guaranteed - // balanced calls. - - NS_ASSERTION(ref_count, - "Oops! Calling |NS_DebugGetRefCount()| probably just " - "destroyed this object."); - } - - return ref_count; - } - +#ifndef nsISupportsImpl_h__ +#include "nsISupportsImpl.h" #endif - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Some convenience macros for implementing QueryInterface - */ - -/** - * This implements query interface with two assumptions: First, the - * class in question implements nsISupports and its own interface and - * nothing else. Second, the implementation of the class's primary - * inheritance chain leads to its own interface. - * - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_QUERY_HEAD(_class) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - NS_ASSERTION(aInstancePtr, \ - "QueryInterface requires a non-NULL destination!"); \ - if ( !aInstancePtr ) \ - return NS_ERROR_NULL_POINTER; \ - nsISupports* foundInterface; - -#define NS_IMPL_QUERY_BODY(_interface) \ - if ( aIID.Equals(NS_GET_IID(_interface)) ) \ - foundInterface = NS_STATIC_CAST(_interface*, this); \ - else - -#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) \ - if ( aIID.Equals(NS_GET_IID(_interface)) ) \ - foundInterface = NS_STATIC_CAST(_interface*, \ - NS_STATIC_CAST(_implClass*, this)); \ - else - -#define NS_IMPL_QUERY_TAIL_GUTS \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - status = NS_NOINTERFACE; \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#define NS_IMPL_QUERY_TAIL(_supports_interface) \ - NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \ - NS_IMPL_QUERY_TAIL_GUTS - - - /* - This is the new scheme. Using this notation now will allow us to switch to - a table driven mechanism when it's ready. Note the difference between this - and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism. You must - explicitly mention |nsISupports| when using the interface maps. - */ -#define NS_INTERFACE_MAP_BEGIN(_implClass) NS_IMPL_QUERY_HEAD(_implClass) -#define NS_INTERFACE_MAP_ENTRY(_interface) NS_IMPL_QUERY_BODY(_interface) -#define NS_INTERFACE_MAP_END NS_IMPL_QUERY_TAIL_GUTS -#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass) \ - NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) -#define NS_INTERFACE_MAP_END_INHERITING(_baseClass) \ - NS_IMPL_QUERY_TAIL_INHERITING(_baseClass) - -#define NS_IMPL_QUERY_INTERFACE0(_class) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(nsISupports) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE1(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END - -/* - The following macro is deprecated. We need to switch all instances - to |NS_IMPL_QUERY_INTERFACE1|, or |NS_IMPL_QUERY_INTERFACE0| depending - on how they were using it. -*/ - -#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - if (NULL == aInstancePtr) { \ - return NS_ERROR_NULL_POINTER; \ - } \ - \ - *aInstancePtr = NULL; \ - \ - static NS_DEFINE_IID(kClassIID, _classiiddef); \ - if (aIID.Equals(kClassIID)) { \ - *aInstancePtr = (void*) this; \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(NS_GET_IID(nsISupports))) { \ - *aInstancePtr = (void*) ((nsISupports*)this); \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - return NS_NOINTERFACE; \ -} - -/** - * Convenience macro for implementing all nsISupports methods for - * a simple class. - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) - -#define NS_IMPL_ISUPPORTS0(_class) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE0(_class) - -#define NS_IMPL_ISUPPORTS1(_class, _interface) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE1(_class, _interface) - -#define NS_IMPL_ISUPPORTS2(_class, _i1, _i2) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) - -#define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) - -#define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) - -#define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) - -#define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9) - -#define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9, _i10) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \ - _i9, _i10) - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Declare that you're going to inherit from something that already - * implements nsISupports, but also implements an additional interface, thus - * causing an ambiguity. In this case you don't need another mRefCnt, you - * just need to forward the definitions to the appropriate superclass. E.g. - * - * class Bar : public Foo, public nsIBar { // both provide nsISupports - * public: - * NS_DECL_ISUPPORTS_INHERITED - * ...other nsIBar and Bar methods... - * }; - */ -#define NS_DECL_ISUPPORTS_INHERITED \ -public: \ - NS_IMETHOD QueryInterface(REFNSIID aIID, \ - void** aInstancePtr); \ - NS_IMETHOD_(nsrefcnt) AddRef(void); \ - NS_IMETHOD_(nsrefcnt) Release(void); \ - -/** - * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED - * to implement the nsISupports methods, forwarding the invocations to a - * superclass that already implements nsISupports. - * - * Note that I didn't make these inlined because they're virtual methods. - */ - -#define NS_IMPL_ADDREF_INHERITED(Class, Super) \ -NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \ -{ \ - return Super::AddRef(); \ -} \ - -#define NS_IMPL_RELEASE_INHERITED(Class, Super) \ -NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \ -{ \ - return Super::Release(); \ -} \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, i1) \ - NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_BODY(i5) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \ - NS_IMPL_QUERY_HEAD(Class) \ - NS_IMPL_QUERY_BODY(i1) \ - NS_IMPL_QUERY_BODY(i2) \ - NS_IMPL_QUERY_BODY(i3) \ - NS_IMPL_QUERY_BODY(i4) \ - NS_IMPL_QUERY_BODY(i5) \ - NS_IMPL_QUERY_BODY(i6) \ - NS_IMPL_QUERY_TAIL_INHERITING(Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, i1) \ - NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ - -#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \ - NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \ - NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ - NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ - NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \ - NS_IMPL_ADDREF_INHERITED(Class, Super) \ - NS_IMPL_RELEASE_INHERITED(Class, Super) \ - -/////////////////////////////////////////////////////////////////////////////// - -/** - * - * Threadsafe implementations of the ISupports convenience macros - * - */ - -/** - * IID for the nsIsThreadsafe interface - * {88210890-47a6-11d2-bec3-00805f8a66dc} - * - * This interface is *only* used for debugging purposes to determine if - * a given component is threadsafe. - */ -#define NS_ISTHREADSAFE_IID \ - { 0x88210890, 0x47a6, 0x11d2, \ - {0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} } - -#if defined(NS_MT_SUPPORTED) - -#define NS_LOCK_INSTANCE() \ - PR_CEnterMonitor((void*)this) - -#define NS_UNLOCK_INSTANCE() \ - PR_CExitMonitor((void*)this) - -/** - * Use this macro to implement the AddRef method for a given _class - * @param _class The name of the class implementing the method - */ - -#define NS_IMPL_THREADSAFE_ADDREF(_class) \ -NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ -{ \ - NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ - nsrefcnt count; \ - count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \ - NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \ - return count; \ -} - -/** - * Use this macro to implement the Release method for a given _class - * @param _class The name of the class implementing the method - */ - -#define NS_IMPL_THREADSAFE_RELEASE(_class) \ -nsrefcnt _class::Release(void) \ -{ \ - nsrefcnt count; \ - NS_PRECONDITION(0 != mRefCnt, "dup release"); \ - count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \ - NS_LOG_RELEASE(this, count, #_class); \ - if (0 == count) { \ - mRefCnt = 1; /* stabilize */ \ - /* enable this to find non-threadsafe destructors: */ \ - /* NS_ASSERT_OWNINGTHREAD(_class); */ \ - NS_DELETEXPCOM(this); \ - return 0; \ - } \ - return count; \ -} - -/////////////////////////////////////////////////////////////////////////////// - -/* - * Some convenience macros for implementing QueryInterface - */ - -/** - * This implements query interface with two assumptions: First, the - * class in question implements nsISupports and its own interface and - * nothing else. Second, the implementation of the class's primary - * inheritance chain leads to its own interface. - * - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ -#if defined(NS_DEBUG) -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \ - if (NULL != (_iface)) { \ - nsISupports* tmp; \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \ - (void**)&tmp)), \ - "Interface is not threadsafe"); \ - } - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ -NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ -{ \ - if (NULL == aInstancePtr) { \ - return NS_ERROR_NULL_POINTER; \ - } \ - \ - *aInstancePtr = NULL; \ - \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - static NS_DEFINE_IID(kClassIID, _classiiddef); \ - if (aIID.Equals(kClassIID)) { \ - *aInstancePtr = (void*) this; \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(NS_GET_IID(nsISupports))) { \ - *aInstancePtr = (void*) ((nsISupports*)this); \ - NS_ADDREF_THIS(); \ - return NS_OK; \ - } \ - if (aIID.Equals(kIsThreadsafeIID)) { \ - return NS_OK; \ - } \ - return NS_NOINTERFACE; \ -} - -#else /* !NS_DEBUG */ - -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ - NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) - -#endif /* !NS_DEBUG */ - -/** - * Convenience macro for implementing all nsISupports methods for - * a simple class. - * @param _class The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - */ - -#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) - -#else /* !NS_MT_SUPPORTED */ - -#define NS_LOCK_INSTANCE() - -#define NS_UNLOCK_INSTANCE() - -#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class) - -#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class) - -#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \ - NS_IMPL_QUERY_INTERFACE(_class, _classiiddef) - -#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) - -#endif /* !NS_MT_SUPPORTED */ - -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_QUERY_TAIL_GUTS_THREADSAFE \ - foundInterface = 0; \ - nsresult status; \ - if ( !foundInterface ) \ - { \ - static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \ - status = aIID.Equals(kIsThreadsafeIID) ? NS_OK : NS_NOINTERFACE; \ - } \ - else \ - { \ - NS_ADDREF(foundInterface); \ - status = NS_OK; \ - } \ - *aInstancePtr = foundInterface; \ - return status; \ -} - -#ifdef NS_DEBUG -#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS_THREADSAFE -#else -#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS +#ifndef nsISupportsObsolete_h__ +#include "nsISupportsObsolete.h" #endif -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(nsISupports) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_INTERFACE_MAP_END_THREADSAFE - -//////////////////////////////////////////////////////////////////////////////// - -#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class) - -#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface) - -#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2) - -#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3) - -#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) - -#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) - -#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) - -#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_IMPL_THREADSAFE_ADDREF(_class) \ - NS_IMPL_THREADSAFE_RELEASE(_class) \ - NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) - -/////////////////////////////////////////////////////////////////////////////// -// Debugging Macros -/////////////////////////////////////////////////////////////////////////////// - /** * Macro for instantiating a new object that implements nsISupports. * Use this in your factory methods to allow for refcnt tracing. @@ -1160,8 +75,6 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ delete (_ptr); \ PR_END_MACRO - - /** * Macro for adding a reference to an interface. * @param _ptr The interface pointer. @@ -1179,7 +92,6 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \ NS_LOG_ADDREF_CALL(this, AddRef(), __FILE__, __LINE__) - extern "C++" { // ...because some one is accidentally including this file inside // an |extern "C"| @@ -1195,23 +107,19 @@ ns_if_addref( T expr ) return expr ? expr->AddRef() : 0; } - } /* extern "C++" */ - -#ifdef NS_BUILD_REFCNT_LOGGING +} /* extern "C++" */ /** * Macro for adding a reference to an interface that checks for NULL. * @param _expr The interface pointer. */ +#ifdef NS_BUILD_REFCNT_LOGGING #define NS_IF_ADDREF(_expr) \ ((0 != (_expr)) \ ? NS_LOG_ADDREF_CALL((_expr), ns_if_addref(_expr), __FILE__, __LINE__) \ : 0) - #else - #define NS_IF_ADDREF(_expr) ns_if_addref(_expr) - #endif /* @@ -1293,7 +201,24 @@ ns_if_addref( T expr ) } \ PR_END_MACRO -/////////////////////////////////////////////////////////////////////////////// +/* + * Often you have to cast an implementation pointer, e.g., |this|, to an + * |nsISupports*|, but because you have multiple inheritance, a simple cast + * is ambiguous. One could simply say, e.g., (given a base |nsIBase|), + * |NS_STATIC_CAST(nsIBase*, this)|; but that disguises the fact that what + * you are really doing is disambiguating the |nsISupports|. You could make + * that more obvious with a double cast, e.g., |NS_STATIC_CAST(nsISupports*, + * NS_STATIC_CAST(nsIBase*, this))|, but that is bulky and harder to read... + * + * The following macro is clean, short, and obvious. In the example above, + * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|. + */ + +#define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \ + NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(__unambiguousBase, __expr)) + + + extern "C++" { // ...because some one is accidentally including this file inside @@ -1332,450 +257,4 @@ CallQueryInterface( T* aSource, DestinationType** aDestination ) } // extern "C++" -/////////////////////////////////////////////////////////////////////////////// -// Macros for implementing nsIClassInfo-related stuff. -/////////////////////////////////////////////////////////////////////////////// - -// include here instead of at the top because it requires the nsISupport decl -#include "nsIClassInfo.h" - -#define NS_CLASSINFO_NAME(_class) _class##_classInfoGlobal -#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper - -#define NS_DECL_CI_INTERFACE_GETTER(_class) \ - extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *, \ - nsIID ***); - -#define NS_DECL_CLASSINFO(_class) \ - NS_DECL_CI_INTERFACE_GETTER(_class) \ - nsIClassInfo *NS_CLASSINFO_NAME(_class); - -#define NS_IMPL_QUERY_CLASSINFO(_class) \ - if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) { \ - extern nsIClassInfo *NS_CLASSINFO_NAME(_class); \ - foundInterface = NS_STATIC_CAST(nsIClassInfo*, NS_CLASSINFO_NAME(_class));\ - } else - -#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \ -NS_IMETHODIMP \ -NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *count, nsIID ***array) \ -{ \ - *count = _c; \ - *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c); - -#define NS_CLASSINFO_HELPER_ENTRY(_i, _interface) \ - (*array)[_i] = (nsIID *)nsMemory::Clone(&NS_GET_IID(_interface), \ - sizeof(nsIID)); - -#define NS_CLASSINFO_HELPER_END \ - return NS_OK; \ -} - -#define NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 1) \ - NS_CLASSINFO_HELPER_ENTRY(0, _interface) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE1_CI(_class, _i1) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS1_CI(_class, _interface) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface) \ - NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) - -#define NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 2) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS2_CI(_class, _i1, _i2) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \ - NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) - -#define NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 3) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS3_CI(_class, _i1, _i2, _i3) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \ - NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) - -#define NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 4) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \ - NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) - -#define NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 5) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \ - NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) - -#define NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 6) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \ - NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) - -#define NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 7) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \ - NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) - -#define NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 8) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \ - NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) - -#define NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 9) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) \ - NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9) - -#define NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_CLASSINFO_HELPER_BEGIN(_class, 10) \ - NS_CLASSINFO_HELPER_ENTRY(0, _i1) \ - NS_CLASSINFO_HELPER_ENTRY(1, _i2) \ - NS_CLASSINFO_HELPER_ENTRY(2, _i3) \ - NS_CLASSINFO_HELPER_ENTRY(3, _i4) \ - NS_CLASSINFO_HELPER_ENTRY(4, _i5) \ - NS_CLASSINFO_HELPER_ENTRY(5, _i6) \ - NS_CLASSINFO_HELPER_ENTRY(6, _i7) \ - NS_CLASSINFO_HELPER_ENTRY(7, _i8) \ - NS_CLASSINFO_HELPER_ENTRY(8, _i9) \ - NS_CLASSINFO_HELPER_ENTRY(9, _i10) \ - NS_CLASSINFO_HELPER_END - -#define NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \ - _i7, _i8, _i9, _i10) \ - NS_INTERFACE_MAP_BEGIN(_class) \ - NS_INTERFACE_MAP_ENTRY(_i1) \ - NS_INTERFACE_MAP_ENTRY(_i2) \ - NS_INTERFACE_MAP_ENTRY(_i3) \ - NS_INTERFACE_MAP_ENTRY(_i4) \ - NS_INTERFACE_MAP_ENTRY(_i5) \ - NS_INTERFACE_MAP_ENTRY(_i6) \ - NS_INTERFACE_MAP_ENTRY(_i7) \ - NS_INTERFACE_MAP_ENTRY(_i8) \ - NS_INTERFACE_MAP_ENTRY(_i9) \ - NS_INTERFACE_MAP_ENTRY(_i10) \ - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \ - NS_IMPL_QUERY_CLASSINFO(_class) \ - NS_INTERFACE_MAP_END - -#define NS_IMPL_ISUPPORTS10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) \ - NS_IMPL_ADDREF(_class) \ - NS_IMPL_RELEASE(_class) \ - NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) \ - NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \ - _i8, _i9, _i10) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking the trueness of an expression passed in within an -// interface implementation. -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_TRUE(x, ret) \ - PR_BEGIN_MACRO \ - if(NS_WARN_IF_FALSE(x, "NS_ENSURE_TRUE(" #x ") failed")) \ - return ret; \ - PR_END_MACRO - -#define NS_ENSURE_FALSE(x, ret) \ - NS_ENSURE_TRUE(!(x), ret) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking results -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_SUCCESS(res, ret) \ - NS_ENSURE_TRUE(NS_SUCCEEDED(res), ret) - -/////////////////////////////////////////////////////////////////////////////// -// Macros for checking state and arguments upon entering interface boundaries -/////////////////////////////////////////////////////////////////////////////// - -#define NS_ENSURE_ARG(arg) \ - NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_POINTER(arg) \ - NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER) - -#define NS_ENSURE_ARG_MIN(arg, min) \ - NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_MAX(arg, max) \ - NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_ARG_RANGE(arg, min, max) \ - NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG) - -#define NS_ENSURE_STATE(state) \ - NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED) - -#define NS_ENSURE_NO_AGGREGATION(outer) \ - NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION) - -#define NS_ENSURE_PROPER_AGGREGATION(outer, iid) \ - NS_ENSURE_FALSE(outer && !iid.Equals(NS_GET_IID(nsISupports)), NS_ERROR_INVALID_ARG) - - -/** - * Macro to free all elements of an XPCOM array of a given size using - * freeFunc, then frees the array itself using nsMemory::Free(). - * - * Note that this macro (and its wrappers) can be used to deallocate a - * partially- or completely-built array while unwinding an error - * condition inside the XPCOM routine that was going to return the - * array. For this to work on a partially-built array, your code - * needs to be building the array from index 0 upwards, and simply - * pass the number of elements that have already been built (and thus - * need to be freed) as |size|. - * - * Thanks to for suggesting this form, which - * allows the macro to be used with NS_RELEASE / NS_RELEASE_IF in - * addition to nsMemory::Free. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - * @param freeFunc The function or macro to be used to free it. - * For arrays of nsISupports (or any class derived - * from it), NS_IF_RELEASE (or NS_RELEASE) should be - * passed as freeFunc. For most (all?) other pointer - * types (including XPCOM strings and wstrings), - * nsMemory::Free should be used, since the - * shared-allocator (nsMemory) is what will have been - * used to allocate the memory. - */ -#define NS_FREE_XPCOM_POINTER_ARRAY(size, array, freeFunc) \ - PR_BEGIN_MACRO \ - PRInt32 iter_ = PRInt32(size); \ - while (--iter_ >= 0) \ - freeFunc((array)[iter_]); \ - nsMemory::Free((array)); \ - PR_END_MACRO - -// convenience macros for commonly used calls. mmmmm. syntactic sugar. - -/** - * Macro to free arrays of non-refcounted objects allocated by the - * shared allocator (nsMemory) such as strings and wstrings. A - * convenience wrapper around NS_FREE_XPCOM_POINTER_ARRAY. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - */ -#define NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(size, array) \ - NS_FREE_XPCOM_POINTER_ARRAY((size), (array), nsMemory::Free) - -/** - * Macro to free an array of pointers to nsISupports (or classes - * derived from it). A convenience wrapper around - * NS_FREE_XPCOM_POINTER_ARRAY. - * - * Note that if you know that none of your nsISupports pointers are - * going to be 0, you can gain a bit of speed by calling - * NS_FREE_XPCOM_POINTER_ARRAY directly and using NS_RELEASE as your - * free function. - * - * @param size Number of elements in the array. If not a constant, this - * should be a PRInt32. Note that this means this macro - * will not work if size >= 2^31. - * @param array The array to be freed. - */ -#define NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(size, array) \ - NS_FREE_XPCOM_POINTER_ARRAY((size), (array), NS_IF_RELEASE) - - -/////////////////////////////////////////////////////////////////////////////// - #endif /* __nsISupportsUtils_h */ diff --git a/xpinstall/src/nsTopProgressNotifier.cpp b/xpinstall/src/nsTopProgressNotifier.cpp index 2cdce14d272..7aceea64ad6 100644 --- a/xpinstall/src/nsTopProgressNotifier.cpp +++ b/xpinstall/src/nsTopProgressNotifier.cpp @@ -59,7 +59,7 @@ nsTopProgressListener::~nsTopProgressListener() } -NS_IMPL_THREADSAFE_ISUPPORTS(nsTopProgressListener, NS_GET_IID(nsIXPIListener)); +NS_IMPL_THREADSAFE_ISUPPORTS1(nsTopProgressListener, nsIXPIListener); long