зеркало из https://github.com/mozilla/pjs.git
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)
This commit is contained in:
Родитель
b67e1fc39c
Коммит
8f4e7ad8e4
|
@ -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()
|
||||
|
|
|
@ -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 <class T>
|
||||
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<nsISupports> nsQueryInterface;
|
||||
typedef nsCOMPtrQueryRequest<nsIWeakReference> 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<T>::GetIID(), aSmartPtr.mErrorPtr);
|
||||
}
|
||||
|
||||
nsCOMPtr( const nsQueryReferent& aSmartPtr )
|
||||
: NSCAP_CTOR_BASE(0)
|
||||
{
|
||||
assign_with_QueryReferent(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::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<T>&
|
||||
operator=( const nsQueryInterface& rhs )
|
||||
{
|
||||
assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsQueryReferent& rhs )
|
||||
{
|
||||
assign_with_QueryReferent(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
|
||||
return *this;
|
||||
}
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsCOMPtr_helper& rhs )
|
||||
{
|
||||
assign_from_helper(rhs, NS_GET_IID(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsDontAddRef<T>& rhs )
|
||||
|
@ -635,39 +632,15 @@ nsCOMPtr<T>::assign_with_AddRef( nsISupports* rawPtr )
|
|||
|
||||
template <class T>
|
||||
void
|
||||
nsCOMPtr<T>::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 <class T>
|
||||
void
|
||||
nsCOMPtr<T>::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<T>::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 <class T>
|
||||
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<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// We don't really need this routine, and it confuses Solaris ... so out it goes
|
||||
template <class DestinationType>
|
||||
inline
|
||||
nsresult
|
||||
CallQueryInterface( nsISupports* aSource, nsCOMPtr<DestinationType>* 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___)
|
||||
|
|
|
@ -75,8 +75,11 @@ interface nsISupportsWeakReference : nsISupports
|
|||
|
||||
%{C++
|
||||
|
||||
// typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
|
||||
// ...this definition had to be moved to nsWeakPtr.h to avoid circular includes, sorry
|
||||
#ifndef nsCOMPtr_h__
|
||||
#include "nsCOMPtr.h"
|
||||
#endif
|
||||
|
||||
typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -105,4 +108,30 @@ CallQueryReferent( nsIWeakReference* aSource, T** aDestination )
|
|||
return aSource->QueryReferent(nsCOMTypeInfo<T>::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);
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
|
|
|
@ -26,6 +26,6 @@
|
|||
#include "nsIWeakReference.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
|
||||
// typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__)
|
||||
|
||||
%}
|
|
@ -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()
|
||||
|
|
|
@ -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 <class T>
|
||||
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<nsISupports> nsQueryInterface;
|
||||
typedef nsCOMPtrQueryRequest<nsIWeakReference> 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<T>::GetIID(), aSmartPtr.mErrorPtr);
|
||||
}
|
||||
|
||||
nsCOMPtr( const nsQueryReferent& aSmartPtr )
|
||||
: NSCAP_CTOR_BASE(0)
|
||||
{
|
||||
assign_with_QueryReferent(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::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<T>&
|
||||
operator=( const nsQueryInterface& rhs )
|
||||
{
|
||||
assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsQueryReferent& rhs )
|
||||
{
|
||||
assign_with_QueryReferent(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
|
||||
return *this;
|
||||
}
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsCOMPtr_helper& rhs )
|
||||
{
|
||||
assign_from_helper(rhs, NS_GET_IID(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsDontAddRef<T>& rhs )
|
||||
|
@ -635,39 +632,15 @@ nsCOMPtr<T>::assign_with_AddRef( nsISupports* rawPtr )
|
|||
|
||||
template <class T>
|
||||
void
|
||||
nsCOMPtr<T>::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 <class T>
|
||||
void
|
||||
nsCOMPtr<T>::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<T>::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 <class T>
|
||||
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<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// We don't really need this routine, and it confuses Solaris ... so out it goes
|
||||
template <class DestinationType>
|
||||
inline
|
||||
nsresult
|
||||
CallQueryInterface( nsISupports* aSource, nsCOMPtr<DestinationType>* 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___)
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче