From 65b7cd0c03cc298835cba84de1de0cf9d9b645f2 Mon Sep 17 00:00:00 2001 From: "scc%netscape.com" Date: Sun, 31 Oct 1999 00:35:48 +0000 Subject: [PATCH] changed the mechanism underlying |do_QueryInterface| to decouple |nsCOMPtr| from services, |nsIWeakReference|, etc. This change fixes bug #17364, and paves the way for making |nsCOMPtr| cooperate with services. r=valeski (additional builds done by dmose and syd) git-svn-id: svn://10.0.0.236/trunk@52346 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/base/nsCOMPtr.cpp | 30 ++- mozilla/xpcom/base/nsCOMPtr.h | 174 +++++++----------- mozilla/xpcom/base/nsIWeakReference.idl | 33 +++- mozilla/xpcom/base/nsWeakPtr.h | 2 +- mozilla/xpcom/base/nsWeakReference.cpp | 14 ++ .../xpcom/components/nsComponentManager.cpp | 15 ++ mozilla/xpcom/components/nsIFactory.idl | 47 +++++ mozilla/xpcom/glue/nsCOMPtr.cpp | 30 ++- mozilla/xpcom/glue/nsCOMPtr.h | 174 +++++++----------- mozilla/xpcom/glue/nsWeakReference.cpp | 14 ++ 10 files changed, 320 insertions(+), 213 deletions(-) diff --git a/mozilla/xpcom/base/nsCOMPtr.cpp b/mozilla/xpcom/base/nsCOMPtr.cpp index 9dd0b7b2d91..ad26d0bc404 100644 --- a/mozilla/xpcom/base/nsCOMPtr.cpp +++ b/mozilla/xpcom/base/nsCOMPtr.cpp @@ -17,7 +17,21 @@ */ #include "nsCOMPtr.h" -#include "nsIWeakReference.h" +// #include "nsIWeakReference.h" + +nsresult +nsQueryInterface::operator()( const nsIID& aIID, void** answer ) const + { + nsresult status; + if ( mRawPtr ) + status = mRawPtr->QueryInterface(aIID, answer); + else + status = NS_ERROR_NULL_POINTER; + + if ( mErrorPtr ) + *mErrorPtr = status; + return status; + } #ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR nsCOMPtr_base::~nsCOMPtr_base() @@ -37,6 +51,19 @@ nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr ) mRawPtr = rawPtr; } +void +nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& iid ) + { + nsISupports* newRawPtr; + if ( !NS_SUCCEEDED( helper(iid, NSCAP_REINTERPRET_CAST(void**, &newRawPtr)) ) ) + newRawPtr = 0; + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = newRawPtr; + } + + +#if 0 void nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result ) { @@ -70,6 +97,7 @@ nsCOMPtr_base::assign_with_QueryReferent( nsIWeakReference* weakPtr, const nsIID if ( result ) *result = status; } +#endif void** nsCOMPtr_base::begin_assignment() diff --git a/mozilla/xpcom/base/nsCOMPtr.h b/mozilla/xpcom/base/nsCOMPtr.h index 3c2d7f3f7a6..9cfc20d65c4 100644 --- a/mozilla/xpcom/base/nsCOMPtr.h +++ b/mozilla/xpcom/base/nsCOMPtr.h @@ -32,10 +32,10 @@ // for |nsresult|, |NS_ADDREF|, et al #endif -#ifndef __gen_nsIWeakReference_h__ -#include "nsIWeakReference.h" - // for |nsIWeakReference| -#endif +// #ifndef __gen_nsIWeakReference_h__ +// #include "nsIWeakReference.h" +// // for |nsIWeakReference| +// #endif /* Public things defined in this file: @@ -52,9 +52,6 @@ getter_AddRefs( T* ) smartTptr = getter_AddRefs( SomeGetter() ); dont_AddRef( T* ) smartTptr = dont_AddRef(rawTptr); - do_QueryReferent( nsIWeakReference* ) - do_QueryReferent( nsIWeakReference*, nsresult* ) - SameCOMIdentity( nsISupports*, nsISupports* ) if ( SameCOMIdentity(rawTptr, rawUptr) ) ... @@ -299,25 +296,44 @@ dont_QueryInterface( T* aRawPtr ) } -template -struct -nsCOMPtrQueryRequest - { - T* mRawPtr; - nsresult* mErrorPtr; - explicit - nsCOMPtrQueryRequest( T* aRawPtr, nsresult* error = 0 ) - : mRawPtr(aRawPtr), - mErrorPtr(error) - { - // nothing else to do here - } - }; +class nsCOMPtr_helper + /* + An |nsCOMPtr_helper| transforms commonly called getters into typesafe forms + that are more convenient to call, and more efficient to use with |nsCOMPtr|s. + Good candidates for helpers are |QueryInterface()|, |CreateInstance()|, etc. -typedef nsCOMPtrQueryRequest nsQueryInterface; -typedef nsCOMPtrQueryRequest nsQueryReferent; + Here are the rules for a helper: + - it implements operator() to produce an interface pointer + - (except for its name) operator() is a valid [XP]COM `getter' + - that interface pointer it returns is already |AddRef()|ed (as from any good getter) + - it matches the type requested with the supplied |nsIID| argument + - it's constructor provides an optional |nsresult*| that |operator()| can fill + in with an error when it is executed + + See |class nsQueryInterface| for an example. + */ + { + public: + virtual nsresult operator()( const nsIID&, void** ) const = 0; + }; +class NS_EXPORT nsQueryInterface : public nsCOMPtr_helper + { + public: + nsQueryInterface( nsISupports* aRawPtr, nsresult* error ) + : mRawPtr(aRawPtr), + mErrorPtr(error) + { + // nothing else to do here + } + + virtual nsresult operator()( const nsIID& aIID, void** ) const; + + private: + nsISupports* mRawPtr; + nsresult* mErrorPtr; + }; inline const nsQueryInterface @@ -326,12 +342,6 @@ do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 ) return nsQueryInterface(aRawPtr, error); } -inline -const nsQueryReferent -do_QueryReferent( nsIWeakReference* aRawPtr, nsresult* error = 0 ) - { - return nsQueryReferent(aRawPtr, error); - } /** @@ -416,8 +426,7 @@ class nsCOMPtr_base #endif NS_EXPORT void assign_with_AddRef( nsISupports* ); - NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); - NS_EXPORT void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); + NS_EXPORT void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); NS_EXPORT void** begin_assignment(); protected: @@ -435,8 +444,9 @@ class nsCOMPtr #ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES private: void assign_with_AddRef( nsISupports* ); - void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); - void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); + void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); +// void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); +// void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); void** begin_assignment(); private: @@ -464,17 +474,11 @@ class nsCOMPtr // nothing else to do here } - nsCOMPtr( const nsQueryInterface& aSmartPtr ) - : NSCAP_CTOR_BASE(0) - { - assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo::GetIID(), aSmartPtr.mErrorPtr); - } - - nsCOMPtr( const nsQueryReferent& aSmartPtr ) - : NSCAP_CTOR_BASE(0) - { - assign_with_QueryReferent(aSmartPtr.mRawPtr, nsCOMTypeInfo::GetIID(), aSmartPtr.mErrorPtr); - } + nsCOMPtr( const nsCOMPtr_helper& helper ) + : NSCAP_CTOR_BASE(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + } #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES void @@ -534,19 +538,12 @@ class nsCOMPtr return *this; } - nsCOMPtr& - operator=( const nsQueryInterface& rhs ) - { - assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo::GetIID(), rhs.mErrorPtr); - return *this; - } - - nsCOMPtr& - operator=( const nsQueryReferent& rhs ) - { - assign_with_QueryReferent(rhs.mRawPtr, nsCOMTypeInfo::GetIID(), rhs.mErrorPtr); - return *this; - } + nsCOMPtr& + operator=( const nsCOMPtr_helper& rhs ) + { + assign_from_helper(rhs, NS_GET_IID(T)); + return *this; + } nsCOMPtr& operator=( const nsDontAddRef& rhs ) @@ -635,39 +632,15 @@ nsCOMPtr::assign_with_AddRef( nsISupports* rawPtr ) template void -nsCOMPtr::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - T* newPtr; - if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &newPtr)) ) ) - newPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = newPtr; - - if ( result ) - *result = status; - } - -template -void -nsCOMPtr::assign_with_QueryReferent( nsIWeakReference* rawPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - T* newPtr; - if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryReferent(iid, NSCAP_REINTERPRET_CAST(void**, &newPtr)) ) ) - newPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = newPtr; - - if ( result ) - *result = status; - } +nsCOMPtr::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& aIID ) + { + T* newRawPtr; + if ( !NS_SUCCEEDED( helper(aIID, NSCAP_REINTERPRET_CAST(void**, &newRawPtr)) ) ) + newRawPtr = 0; + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = newRawPtr; + } template void** @@ -712,6 +685,13 @@ class nsGetterAddRefs // nothing else to do } +#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES + ~nsGetterAddRefs() + { + // mTargetSmartPtr.Assert_NoQueryNeeded(); + } +#endif + operator void**() { return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment()); @@ -838,18 +818,4 @@ SameCOMIdentity( nsISupports* lhs, nsISupports* rhs ) return nsCOMPtr( do_QueryInterface(lhs) ) == nsCOMPtr( do_QueryInterface(rhs) ); } - -#if 0 - // We don't really need this routine, and it confuses Solaris ... so out it goes - template - inline - nsresult - CallQueryInterface( nsISupports* aSource, nsCOMPtr* aDestination ) - // a type-safe shortcut for calling the |QueryInterface()| member function - { - return CallQueryInterface(aSource, getter_AddRefs(*aDestination)); - // this calls the _other_ |CallQueryInterface| - } -#endif - #endif // !defined(nsCOMPtr_h___) diff --git a/mozilla/xpcom/base/nsIWeakReference.idl b/mozilla/xpcom/base/nsIWeakReference.idl index 1cf4b395e9d..d0e252da98f 100644 --- a/mozilla/xpcom/base/nsIWeakReference.idl +++ b/mozilla/xpcom/base/nsIWeakReference.idl @@ -75,8 +75,11 @@ interface nsISupportsWeakReference : nsISupports %{C++ -// typedef nsCOMPtr nsWeakPtr; - // ...this definition had to be moved to nsWeakPtr.h to avoid circular includes, sorry +#ifndef nsCOMPtr_h__ +#include "nsCOMPtr.h" +#endif + +typedef nsCOMPtr nsWeakPtr; /** @@ -105,4 +108,30 @@ CallQueryReferent( nsIWeakReference* aSource, T** aDestination ) return aSource->QueryReferent(nsCOMTypeInfo::GetIID(), (void**)aDestination); } + +class NS_EXPORT nsQueryReferent : public nsCOMPtr_helper + { + public: + nsQueryReferent( nsIWeakReference* aWeakPtr, nsresult* error ) + : mWeakPtr(aWeakPtr), + mErrorPtr(error) + { + // nothing else to do here + } + + virtual nsresult operator()( const nsIID& aIID, void** ) const; + + private: + nsIWeakReference* mWeakPtr; + nsresult* mErrorPtr; + }; + +inline +const nsQueryReferent +do_QueryReferent( nsIWeakReference* aRawPtr, nsresult* error = 0 ) + { + return nsQueryReferent(aRawPtr, error); + } + + %} diff --git a/mozilla/xpcom/base/nsWeakPtr.h b/mozilla/xpcom/base/nsWeakPtr.h index 5bae039619c..b911b463b1d 100644 --- a/mozilla/xpcom/base/nsWeakPtr.h +++ b/mozilla/xpcom/base/nsWeakPtr.h @@ -26,6 +26,6 @@ #include "nsIWeakReference.h" #include "nsCOMPtr.h" -typedef nsCOMPtr nsWeakPtr; +// typedef nsCOMPtr nsWeakPtr; #endif diff --git a/mozilla/xpcom/base/nsWeakReference.cpp b/mozilla/xpcom/base/nsWeakReference.cpp index 7b2f2550e61..a6676f13813 100644 --- a/mozilla/xpcom/base/nsWeakReference.cpp +++ b/mozilla/xpcom/base/nsWeakReference.cpp @@ -25,6 +25,20 @@ #include "nsWeakReference.h" #include "nsCOMPtr.h" +nsresult +nsQueryReferent::operator()( const nsIID& aIID, void** answer ) const + { + nsresult status; + if ( mWeakPtr ) + status = mWeakPtr->QueryReferent(aIID, answer); + else + status = NS_ERROR_NULL_POINTER; + + if ( mErrorPtr ) + *mErrorPtr = status; + return status; + } + NS_COM nsIWeakReference * NS_GetWeakReference( nsISupports* aInstance, nsresult* aResult ) { diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index dd1a13acf62..2c813752d29 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -90,6 +90,21 @@ static NS_DEFINE_CID(kNoCID, NS_NO_CID); #define USE_REGISTRY #endif /* USE_NSREG */ + +nsresult +nsCreateInstance::operator()( const nsIID& aIID, void** answer ) const + { + nsresult status; + if ( mFactory ) + status = mFactory->CreateInstance(mOuter, aIID, answer); + else + status = NS_ERROR_NULL_POINTER; + + if ( mErrorPtr ) + *mErrorPtr = status; + return status; + } + /* prototypes for the Mac */ PRBool nsFactoryEntry_Destroy(nsHashKey *aKey, void *aData, void* closure); diff --git a/mozilla/xpcom/components/nsIFactory.idl b/mozilla/xpcom/components/nsIFactory.idl index 305ab32f3e6..c71701cd41e 100644 --- a/mozilla/xpcom/components/nsIFactory.idl +++ b/mozilla/xpcom/components/nsIFactory.idl @@ -27,3 +27,50 @@ interface nsIFactory : nsISupports { void LockFactory(in PRBool lock); }; +%{C++ + +#ifndef nsCOMPtr_h__ +#include "nsCOMPtr.h" +#endif + +#ifndef class_nsCreateInstance__ +#define class_nsCreateInstance__ + // Have to protect this section with a #define because it gets built from + // two different IDL files (nsIComponentManager.idl #includes this file) + +class NS_EXPORT nsCreateInstance : public nsCOMPtr_helper + { + public: + nsCreateInstance( nsIFactory* aFactory, nsISupports* aOuter, nsresult* error ) + : mFactory(aFactory), + mOuter(aOuter), + mErrorPtr(error) + { + // nothing else to do here + } + + virtual nsresult operator()( const nsIID& aIID, void** answer ) const; + + private: + nsIFactory* mFactory; + nsISupports* mOuter; + nsresult* mErrorPtr; + }; + +inline +const nsCreateInstance +do_CreateInstance( nsIFactory* aFactory, nsresult* error = 0 ) + { + return nsCreateInstance(aFactory, 0, error); + } + +inline +const nsCreateInstance +do_CreateInstance( nsIFactory* aFactory, nsISupports* aOuter, nsresult* error = 0 ) + { + return nsCreateInstance(aFactory, aOuter, error); + } + +#endif // !defined(class_nsCreateInstance__) + +%} \ No newline at end of file diff --git a/mozilla/xpcom/glue/nsCOMPtr.cpp b/mozilla/xpcom/glue/nsCOMPtr.cpp index 9dd0b7b2d91..ad26d0bc404 100644 --- a/mozilla/xpcom/glue/nsCOMPtr.cpp +++ b/mozilla/xpcom/glue/nsCOMPtr.cpp @@ -17,7 +17,21 @@ */ #include "nsCOMPtr.h" -#include "nsIWeakReference.h" +// #include "nsIWeakReference.h" + +nsresult +nsQueryInterface::operator()( const nsIID& aIID, void** answer ) const + { + nsresult status; + if ( mRawPtr ) + status = mRawPtr->QueryInterface(aIID, answer); + else + status = NS_ERROR_NULL_POINTER; + + if ( mErrorPtr ) + *mErrorPtr = status; + return status; + } #ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR nsCOMPtr_base::~nsCOMPtr_base() @@ -37,6 +51,19 @@ nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr ) mRawPtr = rawPtr; } +void +nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& iid ) + { + nsISupports* newRawPtr; + if ( !NS_SUCCEEDED( helper(iid, NSCAP_REINTERPRET_CAST(void**, &newRawPtr)) ) ) + newRawPtr = 0; + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = newRawPtr; + } + + +#if 0 void nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result ) { @@ -70,6 +97,7 @@ nsCOMPtr_base::assign_with_QueryReferent( nsIWeakReference* weakPtr, const nsIID if ( result ) *result = status; } +#endif void** nsCOMPtr_base::begin_assignment() diff --git a/mozilla/xpcom/glue/nsCOMPtr.h b/mozilla/xpcom/glue/nsCOMPtr.h index 3c2d7f3f7a6..9cfc20d65c4 100644 --- a/mozilla/xpcom/glue/nsCOMPtr.h +++ b/mozilla/xpcom/glue/nsCOMPtr.h @@ -32,10 +32,10 @@ // for |nsresult|, |NS_ADDREF|, et al #endif -#ifndef __gen_nsIWeakReference_h__ -#include "nsIWeakReference.h" - // for |nsIWeakReference| -#endif +// #ifndef __gen_nsIWeakReference_h__ +// #include "nsIWeakReference.h" +// // for |nsIWeakReference| +// #endif /* Public things defined in this file: @@ -52,9 +52,6 @@ getter_AddRefs( T* ) smartTptr = getter_AddRefs( SomeGetter() ); dont_AddRef( T* ) smartTptr = dont_AddRef(rawTptr); - do_QueryReferent( nsIWeakReference* ) - do_QueryReferent( nsIWeakReference*, nsresult* ) - SameCOMIdentity( nsISupports*, nsISupports* ) if ( SameCOMIdentity(rawTptr, rawUptr) ) ... @@ -299,25 +296,44 @@ dont_QueryInterface( T* aRawPtr ) } -template -struct -nsCOMPtrQueryRequest - { - T* mRawPtr; - nsresult* mErrorPtr; - explicit - nsCOMPtrQueryRequest( T* aRawPtr, nsresult* error = 0 ) - : mRawPtr(aRawPtr), - mErrorPtr(error) - { - // nothing else to do here - } - }; +class nsCOMPtr_helper + /* + An |nsCOMPtr_helper| transforms commonly called getters into typesafe forms + that are more convenient to call, and more efficient to use with |nsCOMPtr|s. + Good candidates for helpers are |QueryInterface()|, |CreateInstance()|, etc. -typedef nsCOMPtrQueryRequest nsQueryInterface; -typedef nsCOMPtrQueryRequest nsQueryReferent; + Here are the rules for a helper: + - it implements operator() to produce an interface pointer + - (except for its name) operator() is a valid [XP]COM `getter' + - that interface pointer it returns is already |AddRef()|ed (as from any good getter) + - it matches the type requested with the supplied |nsIID| argument + - it's constructor provides an optional |nsresult*| that |operator()| can fill + in with an error when it is executed + + See |class nsQueryInterface| for an example. + */ + { + public: + virtual nsresult operator()( const nsIID&, void** ) const = 0; + }; +class NS_EXPORT nsQueryInterface : public nsCOMPtr_helper + { + public: + nsQueryInterface( nsISupports* aRawPtr, nsresult* error ) + : mRawPtr(aRawPtr), + mErrorPtr(error) + { + // nothing else to do here + } + + virtual nsresult operator()( const nsIID& aIID, void** ) const; + + private: + nsISupports* mRawPtr; + nsresult* mErrorPtr; + }; inline const nsQueryInterface @@ -326,12 +342,6 @@ do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 ) return nsQueryInterface(aRawPtr, error); } -inline -const nsQueryReferent -do_QueryReferent( nsIWeakReference* aRawPtr, nsresult* error = 0 ) - { - return nsQueryReferent(aRawPtr, error); - } /** @@ -416,8 +426,7 @@ class nsCOMPtr_base #endif NS_EXPORT void assign_with_AddRef( nsISupports* ); - NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); - NS_EXPORT void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); + NS_EXPORT void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); NS_EXPORT void** begin_assignment(); protected: @@ -435,8 +444,9 @@ class nsCOMPtr #ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES private: void assign_with_AddRef( nsISupports* ); - void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); - void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); + void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); +// void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); +// void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); void** begin_assignment(); private: @@ -464,17 +474,11 @@ class nsCOMPtr // nothing else to do here } - nsCOMPtr( const nsQueryInterface& aSmartPtr ) - : NSCAP_CTOR_BASE(0) - { - assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo::GetIID(), aSmartPtr.mErrorPtr); - } - - nsCOMPtr( const nsQueryReferent& aSmartPtr ) - : NSCAP_CTOR_BASE(0) - { - assign_with_QueryReferent(aSmartPtr.mRawPtr, nsCOMTypeInfo::GetIID(), aSmartPtr.mErrorPtr); - } + nsCOMPtr( const nsCOMPtr_helper& helper ) + : NSCAP_CTOR_BASE(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + } #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES void @@ -534,19 +538,12 @@ class nsCOMPtr return *this; } - nsCOMPtr& - operator=( const nsQueryInterface& rhs ) - { - assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo::GetIID(), rhs.mErrorPtr); - return *this; - } - - nsCOMPtr& - operator=( const nsQueryReferent& rhs ) - { - assign_with_QueryReferent(rhs.mRawPtr, nsCOMTypeInfo::GetIID(), rhs.mErrorPtr); - return *this; - } + nsCOMPtr& + operator=( const nsCOMPtr_helper& rhs ) + { + assign_from_helper(rhs, NS_GET_IID(T)); + return *this; + } nsCOMPtr& operator=( const nsDontAddRef& rhs ) @@ -635,39 +632,15 @@ nsCOMPtr::assign_with_AddRef( nsISupports* rawPtr ) template void -nsCOMPtr::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - T* newPtr; - if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &newPtr)) ) ) - newPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = newPtr; - - if ( result ) - *result = status; - } - -template -void -nsCOMPtr::assign_with_QueryReferent( nsIWeakReference* rawPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - T* newPtr; - if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryReferent(iid, NSCAP_REINTERPRET_CAST(void**, &newPtr)) ) ) - newPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = newPtr; - - if ( result ) - *result = status; - } +nsCOMPtr::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& aIID ) + { + T* newRawPtr; + if ( !NS_SUCCEEDED( helper(aIID, NSCAP_REINTERPRET_CAST(void**, &newRawPtr)) ) ) + newRawPtr = 0; + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = newRawPtr; + } template void** @@ -712,6 +685,13 @@ class nsGetterAddRefs // nothing else to do } +#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES + ~nsGetterAddRefs() + { + // mTargetSmartPtr.Assert_NoQueryNeeded(); + } +#endif + operator void**() { return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment()); @@ -838,18 +818,4 @@ SameCOMIdentity( nsISupports* lhs, nsISupports* rhs ) return nsCOMPtr( do_QueryInterface(lhs) ) == nsCOMPtr( do_QueryInterface(rhs) ); } - -#if 0 - // We don't really need this routine, and it confuses Solaris ... so out it goes - template - inline - nsresult - CallQueryInterface( nsISupports* aSource, nsCOMPtr* aDestination ) - // a type-safe shortcut for calling the |QueryInterface()| member function - { - return CallQueryInterface(aSource, getter_AddRefs(*aDestination)); - // this calls the _other_ |CallQueryInterface| - } -#endif - #endif // !defined(nsCOMPtr_h___) diff --git a/mozilla/xpcom/glue/nsWeakReference.cpp b/mozilla/xpcom/glue/nsWeakReference.cpp index 7b2f2550e61..a6676f13813 100644 --- a/mozilla/xpcom/glue/nsWeakReference.cpp +++ b/mozilla/xpcom/glue/nsWeakReference.cpp @@ -25,6 +25,20 @@ #include "nsWeakReference.h" #include "nsCOMPtr.h" +nsresult +nsQueryReferent::operator()( const nsIID& aIID, void** answer ) const + { + nsresult status; + if ( mWeakPtr ) + status = mWeakPtr->QueryReferent(aIID, answer); + else + status = NS_ERROR_NULL_POINTER; + + if ( mErrorPtr ) + *mErrorPtr = status; + return status; + } + NS_COM nsIWeakReference * NS_GetWeakReference( nsISupports* aInstance, nsresult* aResult ) {