PyG_Base::QueryInterface(REFNSIID iid, void** ppv) { #ifdef PYXPCOM_DEBUG_FULL { char *sziid = iid.ToString(); LogF("PyGatewayBase::QueryInterface: %s", sziid); Allocator::Free(sziid); } #endif NS_PRECONDITION(ppv, "NULL pointer"); if (ppv==nsnull) return NS_ERROR_NULL_POINTER; *ppv = nsnull;      if ( (m_pBaseObject==NULL || !iid.Equals(NS_GET_IID(nsISupports))) && (*ppv=ThisAsIID(iid)) != NULL ) { AddRef(); return NS_OK; }   if (m_pBaseObject != NULL) return m_pBaseObject->QueryInterface(iid, ppv);   PRBool supports = PR_FALSE; { CEnterLeavePython celp;  PyObject * ob = Py_nsIID::PyObjectFromIID(iid); PyObject * this_interface_ob = Py_nsISupports::PyObjectFromInterface((nsIInternalPython *)this, NS_GET_IID(nsISupports), PR_TRUE, PR_FALSE); if ( !ob || !this_interface_ob) { Py_XDECREF(ob); Py_XDECREF(this_interface_ob); return NS_ERROR_OUT_OF_MEMORY; }  PyObject *result = PyObject_CallMethod(m_pPyObject, "_QueryInterface_", "OO", this_interface_ob, ob); Py_DECREF(ob); Py_DECREF(this_interface_ob);  if ( result ) { if (Py_nsISupports::InterfaceFromPyObject(result, iid, (nsISupports **)ppv, PR_TRUE)) {   supports = (*ppv!=NULL);  } else {    PyXPCOM_LogError("The _QueryInterface_ method returned an object of type '%s', but an interface was expected\n", result->ob_type->tp_name);  } Py_DECREF(result); } else { NS_ABORT_IF_FALSE(PyErr_Occurred(), "Got NULL result, but no Python error flagged!"); NS_WARN_IF_FALSE(!supports, "Have failure with success flag set!"); PyXPCOM_LogError("The _QueryInterface_ processing failed.\n");    PyErr_Clear(); } } if ( !supports ) return NS_ERROR_NO_INTERFACE; return NS_OK; }
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr)      \ {return PyG_Base::QueryInterface(aIID, aInstancePtr);}     \
PyG_Base::QueryInterface(REFNSIID iid, void** ppv){#ifdef PYXPCOM_DEBUG_FULL	{		char *sziid = iid.ToString();		LogF("PyGatewayBase::QueryInterface: %s", sziid);		Allocator::Free(sziid);	}#endif	NS_PRECONDITION(ppv, "NULL pointer");	if (ppv==nsnull)		return NS_ERROR_NULL_POINTER;	*ppv = nsnull;	// If one of our native interfaces (but NOT nsISupports if we have a base)	// return this.	// It is important is that nsISupports come from the base object	// to ensure that we live by XPCOM identity rules (other interfaces need	// not abide by this rule - only nsISupports.)	if ( (m_pBaseObject==NULL || !iid.Equals(NS_GET_IID(nsISupports)))	   && (*ppv=ThisAsIID(iid)) != NULL ) {		AddRef();		return NS_OK;	}	// If we have a "base object", then we need to delegate _every_ remaining 	// QI to it.	if (m_pBaseObject != NULL)		return m_pBaseObject->QueryInterface(iid, ppv);	// Call the Python policy to see if it (says it) supports the interface	PRBool supports = PR_FALSE;	{ // temp scope for Python lock		CEnterLeavePython celp;		PyObject * ob = Py_nsIID::PyObjectFromIID(iid);		PyObject * this_interface_ob = Py_nsISupports::PyObjectFromInterface((nsIInternalPython *)this, NS_GET_IID(nsISupports), PR_TRUE, PR_FALSE);		if ( !ob || !this_interface_ob) {			Py_XDECREF(ob);			Py_XDECREF(this_interface_ob);			return NS_ERROR_OUT_OF_MEMORY;		}		PyObject *result = PyObject_CallMethod(m_pPyObject, "_QueryInterface_",		                                                    "OO", 								    this_interface_ob, ob);		Py_DECREF(ob);		Py_DECREF(this_interface_ob);		if ( result ) {			if (Py_nsISupports::InterfaceFromPyObject(result, iid, (nsISupports **)ppv, PR_TRUE)) {				// If OK, but NULL, _QI_ returned None, which simply means				// "no such interface"				supports = (*ppv!=NULL);				// result has been QI'd and AddRef'd all ready for return.			} else {				// Dump this message and any Python exception before				// reporting the fact that QI failed - this error				// may provide clues!				PyXPCOM_LogError("The _QueryInterface_ method returned an object of type '%s', but an interface was expected\n", result->ob_type->tp_name);				// supports remains false			}			Py_DECREF(result);		} else {			NS_ABORT_IF_FALSE(PyErr_Occurred(), "Got NULL result, but no Python error flagged!");			NS_WARN_IF_FALSE(!supports, "Have failure with success flag set!");			PyXPCOM_LogError("The _QueryInterface_ processing failed.\n");			// supports remains false.			// We have reported the error, and are returning to COM,			// so we should clear it.			PyErr_Clear();		}	} // end of temp scope for Python lock - lock released here!	if ( !supports )		return NS_ERROR_NO_INTERFACE;	return NS_OK;}