Bug 297598 - bring pyxpcom up to speed.
r=alecf, sr=shaver - not used by any builds. git-svn-id: svn://10.0.0.236/trunk@178999 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -41,7 +41,7 @@ from xpcom import xpt, COMException, nsError
|
||||
|
||||
# Suck in stuff from _xpcom we use regularly to prevent a module lookup
|
||||
from xpcom._xpcom import IID_nsISupports, IID_nsIClassInfo, IID_nsISupportsCString, IID_nsISupportsWeakReference, \
|
||||
IID_nsIWeakReference, XPTI_GetInterfaceInfoManager, NS_GetGlobalComponentManager, XPTC_InvokeByIndex
|
||||
IID_nsIWeakReference, XPTI_GetInterfaceInfoManager, GetComponentManager, XPTC_InvokeByIndex
|
||||
|
||||
# Attribute names we may be __getattr__'d for, but know we don't want to delegate
|
||||
# Could maybe just look for startswith("__") but this may screw things for some objects.
|
||||
@@ -211,8 +211,8 @@ class Component(_XPCOMBase):
|
||||
ob_name = None
|
||||
if not hasattr(ob, "IID"):
|
||||
ob_name = ob
|
||||
cm = NS_GetGlobalComponentManager()
|
||||
ob = cm.CreateInstanceByContractID(ob)
|
||||
cm = GetComponentManager()
|
||||
ob = cm.createInstanceByContractID(ob)
|
||||
assert not hasattr(ob, "_comobj_"), "The created object should be a raw nsIWhatever, not a wrapped one"
|
||||
# Keep a reference to the object in the component too
|
||||
self.__dict__['_comobj_'] = ob
|
||||
|
||||
@@ -52,13 +52,16 @@ def _get_good_iid(iid):
|
||||
return iid
|
||||
|
||||
# The "manager" object.
|
||||
manager = xpcom.client.Component(_xpcom.NS_GetGlobalComponentManager(), _xpcom.IID_nsIComponentManager)
|
||||
manager = xpcom.client.Component(_xpcom.GetComponentManager(), _xpcom.IID_nsIComponentManager)
|
||||
|
||||
# The component registrar
|
||||
registrar = xpcom.client.Component(_xpcom.GetComponentManager(), _xpcom.IID_nsIComponentRegistrar)
|
||||
|
||||
# The "interfaceInfoManager" object - JS doesnt have this.
|
||||
interfaceInfoManager = _xpcom.XPTI_GetInterfaceInfoManager()
|
||||
|
||||
# The serviceManager - JS doesnt have this either!
|
||||
serviceManager = _xpcom.GetGlobalServiceManager()
|
||||
serviceManager = _xpcom.GetServiceManager()
|
||||
|
||||
# The "Exception" object
|
||||
Exception = xpcom.COMException
|
||||
@@ -172,7 +175,7 @@ class _Class:
|
||||
self.contractid = contractid
|
||||
def __getattr__(self, attr):
|
||||
if attr == "clsid":
|
||||
rc = manager.contractIDToClassID(self.contractid)
|
||||
rc = registrar.contractIDToCID(self.contractid)
|
||||
# stash it away - it can never change!
|
||||
self.clsid = rc
|
||||
return rc
|
||||
@@ -199,12 +202,12 @@ class _Classes(_ComponentCollection):
|
||||
|
||||
def _build_dict(self):
|
||||
ret = {}
|
||||
enum = manager.EnumerateContractIDs()
|
||||
while not enum.IsDone():
|
||||
enum = registrar.enumerateContractIDs()
|
||||
while enum.hasMoreElements():
|
||||
# Call the Python-specific FetchBlock, to keep the loop in C.
|
||||
items = enum.FetchBlock(500)
|
||||
items = enum.fetchBlock(2000, _xpcom.IID_nsISupportsCString)
|
||||
for item in items:
|
||||
name = str(item)
|
||||
name = str(item.data)
|
||||
ret[name] = _Class(name)
|
||||
return ret
|
||||
|
||||
@@ -221,12 +224,12 @@ ID = _xpcom.IID
|
||||
class _ShutdownObserver:
|
||||
_com_interfaces_ = interfaces.nsIObserver
|
||||
def observe(self, service, topic, extra):
|
||||
global manager, classes, interfaces, interfaceInfoManager, _shutdownObserver, serviceManager, _constants_by_iid_map
|
||||
manager = classes = interfaces = interfaceInfoManager = _shutdownObserver = serviceManager = _constants_by_iid_map = None
|
||||
global manager, registrar, classes, interfaces, interfaceInfoManager, _shutdownObserver, serviceManager, _constants_by_iid_map
|
||||
manager = registrar = classes = interfaces = interfaceInfoManager = _shutdownObserver = serviceManager = _constants_by_iid_map = None
|
||||
xpcom.client._shutdown()
|
||||
xpcom.server._shutdown()
|
||||
|
||||
svc = _xpcom.GetGlobalServiceManager().getServiceByContractID("@mozilla.org/observer-service;1", interfaces.nsIObserverService)
|
||||
svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/observer-service;1", interfaces.nsIObserverService)
|
||||
# Observers will be QI'd for a weak-reference, so we must keep the
|
||||
# observer alive ourself, and must keep the COM object alive,
|
||||
# _not_ just the Python instance!!!
|
||||
|
||||
@@ -68,7 +68,7 @@ def FindCOMComponents(py_module):
|
||||
def register_self(klass, compMgr, location, registryLocation, componentType):
|
||||
pcl = PythonComponentLoader
|
||||
from xpcom import _xpcom
|
||||
svc = _xpcom.GetGlobalServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager)
|
||||
svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager)
|
||||
svc.addCategoryEntry("component-loader", pcl._reg_component_type_, pcl._reg_contractid_, 1, 1)
|
||||
|
||||
class PythonComponentLoader:
|
||||
@@ -111,7 +111,9 @@ class PythonComponentLoader:
|
||||
def getFactory(self, clsid, location, type):
|
||||
# return the factory
|
||||
assert type == self._reg_component_type_, "Being asked to create an object not of my type:%s" % (type,)
|
||||
file_interface = components.manager.specForRegistryLocation(location)
|
||||
# FIXME: how to do this without obsolete component manager?
|
||||
cmo = components.manager.queryInterface(components.interfaces.nsIComponentManagerObsolete)
|
||||
file_interface = cmo.specForRegistryLocation(location)
|
||||
# delegate to the module.
|
||||
m = self._getCOMModuleForLocation(file_interface)
|
||||
return m.getClassObject(components.manager, clsid, components.interfaces.nsIFactory)
|
||||
|
||||
@@ -68,6 +68,7 @@ CPPSRCS= \
|
||||
PyGWeakReference.cpp \
|
||||
PyIClassInfo.cpp \
|
||||
PyIComponentManager.cpp \
|
||||
PyIComponentManagerObsolete.cpp \
|
||||
PyIInputStream.cpp \
|
||||
PyIEnumerator.cpp \
|
||||
PyIID.cpp \
|
||||
|
||||
@@ -187,7 +187,7 @@ void *PyG_Base::ThisAsIID( const nsIID &iid )
|
||||
if (iid.Equals(NS_GET_IID(nsIInternalPython)))
|
||||
return (nsISupports *)(nsIInternalPython *)this;
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
// Call back into Python, passing a Python instance, and get back
|
||||
// an interface object that wraps the instance.
|
||||
|
||||
@@ -61,10 +61,7 @@ public:
|
||||
PyG_nsIModule(PyObject *instance) : PyG_Base(instance, NS_GET_IID(nsIModule)) {;}
|
||||
PYGATEWAY_BASE_SUPPORT(nsIModule, PyG_Base);
|
||||
|
||||
NS_IMETHOD GetClassObject(nsIComponentManager *aCompMgr, const nsCID & aClass, const nsIID & aIID, void * *result);
|
||||
NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr, nsIFile *location, const char *registryLocation, const char *componentType);
|
||||
NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr, nsIFile *location, const char *registryLocation);
|
||||
NS_IMETHOD CanUnload(nsIComponentManager *aCompMgr, PRBool *_retval);
|
||||
NS_DECL_NSIMODULE
|
||||
};
|
||||
|
||||
PyG_Base *MakePyG_nsIModule(PyObject *instance)
|
||||
@@ -83,7 +80,7 @@ PyG_nsIModule::GetClassObject(nsIComponentManager *aCompMgr,
|
||||
NS_PRECONDITION(r_classObj, "null pointer");
|
||||
*r_classObj = nsnull;
|
||||
CEnterLeavePython _celp;
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE);
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
|
||||
PyObject *iid = Py_nsIID::PyObjectFromIID(aIID);
|
||||
PyObject *clsid = Py_nsIID::PyObjectFromIID(aClass);
|
||||
const char *methodName = "getClassObject";
|
||||
@@ -113,7 +110,7 @@ PyG_nsIModule::RegisterSelf(nsIComponentManager *aCompMgr,
|
||||
NS_PRECONDITION(aCompMgr, "null pointer");
|
||||
NS_PRECONDITION(aPath, "null pointer");
|
||||
CEnterLeavePython _celp;
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE);
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
|
||||
PyObject *path = Py_nsISupports::PyObjectFromInterface(aPath, NS_GET_IID(nsIFile), PR_TRUE);
|
||||
const char *methodName = "registerSelf";
|
||||
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OOzz", cm, path, registryLocation, componentType);
|
||||
@@ -130,7 +127,7 @@ PyG_nsIModule::UnregisterSelf(nsIComponentManager* aCompMgr,
|
||||
NS_PRECONDITION(aCompMgr, "null pointer");
|
||||
NS_PRECONDITION(aPath, "null pointer");
|
||||
CEnterLeavePython _celp;
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE);
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
|
||||
PyObject *path = Py_nsISupports::PyObjectFromInterface(aPath, NS_GET_IID(nsIFile), PR_TRUE);
|
||||
const char *methodName = "unregisterSelf";
|
||||
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OOz", cm, path, registryLocation);
|
||||
@@ -146,7 +143,7 @@ PyG_nsIModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
|
||||
NS_PRECONDITION(okToUnload, "null pointer");
|
||||
CEnterLeavePython _celp;
|
||||
// we are shutting down - don't ask for a nice wrapped object.
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE, PR_FALSE);
|
||||
PyObject *cm = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE, PR_FALSE);
|
||||
const char *methodName = "canUnload";
|
||||
PyObject *ret = NULL;
|
||||
nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "O", cm);
|
||||
@@ -202,7 +199,7 @@ NS_IMETHODIMP PyG_nsIComponentLoader::Init(nsIComponentManager *aCompMgr, nsISup
|
||||
{
|
||||
CEnterLeavePython _celp;
|
||||
const char *methodName = "init";
|
||||
PyObject *c = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE);
|
||||
PyObject *c = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
|
||||
PyObject *r = Py_nsISupports::PyObjectFromInterface(aRegistry, NS_GET_IID(nsISupports), PR_TRUE);
|
||||
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OO", c, r);
|
||||
Py_XDECREF(c);
|
||||
@@ -298,5 +295,3 @@ NS_IMETHODIMP PyG_nsIComponentLoader::UnloadAll(PRInt32 aWhen)
|
||||
const char *methodName = "unloadAll";
|
||||
return InvokeNativeViaPolicy(methodName, NULL, "i", aWhen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,20 +46,22 @@
|
||||
// (c) 2000, ActiveState corp.
|
||||
|
||||
#include "PyXPCOM_std.h"
|
||||
#include <nsIComponentManagerObsolete.h>
|
||||
|
||||
static nsIComponentManagerObsolete *GetI(PyObject *self) {
|
||||
static const nsIID iid = NS_GET_IID(nsIComponentManagerObsolete);
|
||||
static nsIComponentManager *GetI(PyObject *self) {
|
||||
static const nsIID iid = NS_GET_IID(nsIComponentManager);
|
||||
|
||||
if (!Py_nsISupports::Check(self, iid)) {
|
||||
PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
|
||||
return NULL;
|
||||
}
|
||||
return (nsIComponentManagerObsolete *)Py_nsISupports::GetI(self);
|
||||
return NS_STATIC_CAST(nsIComponentManager*, Py_nsISupports::GetI(self));
|
||||
}
|
||||
|
||||
static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
|
||||
{
|
||||
// second arg to CreateInstanceByContractID is a "delegate" - we
|
||||
// aren't sure of the semantics of this yet and it seems rarely used,
|
||||
// so we just punt for now.
|
||||
char *pid, *notyet = NULL;
|
||||
PyObject *obIID = NULL;
|
||||
if (!PyArg_ParseTuple(args, "s|zO", &pid, ¬yet, &obIID))
|
||||
@@ -68,7 +70,7 @@ static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
|
||||
PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
|
||||
return NULL;
|
||||
}
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
nsIComponentManager *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -91,109 +93,46 @@ static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
|
||||
return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyContractIDToClassID(PyObject *self, PyObject *args)
|
||||
static PyObject *PyCreateInstance(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *pid;
|
||||
if (!PyArg_ParseTuple(args, "s", &pid))
|
||||
char *notyet = NULL;
|
||||
PyObject *obClassID = NULL, *obIID = NULL;
|
||||
if (!PyArg_ParseTuple(args, "O|zO", &obClassID, ¬yet, &obIID))
|
||||
return NULL;
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (notyet != NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
|
||||
return NULL;
|
||||
}
|
||||
nsIComponentManager *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIID classID;
|
||||
if (!Py_nsIID::IIDFromPyObject(obClassID, &classID))
|
||||
return NULL;
|
||||
nsIID iid;
|
||||
if (obIID==NULL)
|
||||
iid = NS_GET_IID(nsISupports);
|
||||
else
|
||||
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
|
||||
return NULL;
|
||||
|
||||
nsISupports *pis;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->ContractIDToClassID(pid, &iid);
|
||||
r = pI->CreateInstance(classID, NULL, iid, (void **)&pis);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsIID::PyObjectFromIID(iid);
|
||||
}
|
||||
|
||||
static PyObject *PyCLSIDToContractID(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *obIID;
|
||||
if (!PyArg_ParseTuple(args, "O", &obIID))
|
||||
return NULL;
|
||||
|
||||
nsIID iid;
|
||||
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
|
||||
return NULL;
|
||||
char *ret_pid = nsnull;
|
||||
char *ret_class = nsnull;
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->CLSIDToContractID(iid, &ret_class, &ret_pid);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
PyObject *ob_pid = PyString_FromString(ret_pid);
|
||||
PyObject *ob_class = PyString_FromString(ret_class);
|
||||
PyObject *ret = Py_BuildValue("OO", ob_pid, ob_class);
|
||||
nsMemory::Free(ret_pid);
|
||||
nsMemory::Free(ret_class);
|
||||
Py_XDECREF(ob_pid);
|
||||
Py_XDECREF(ob_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *PyEnumerateCLSIDs(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIEnumerator *pRet;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->EnumerateCLSIDs(&pRet);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyEnumerateContractIDs(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIEnumerator *pRet;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->EnumerateContractIDs(&pRet);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
|
||||
/* Return a type based on the IID (with no extra ref) */
|
||||
return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
struct PyMethodDef
|
||||
PyMethods_IComponentManager[] =
|
||||
{
|
||||
{ "CreateInstanceByContractID", PyCreateInstanceByContractID, 1},
|
||||
{ "createInstanceByContractID", PyCreateInstanceByContractID, 1},
|
||||
{ "EnumerateCLSIDs", PyEnumerateCLSIDs, 1},
|
||||
{ "enumerateCLSIDs", PyEnumerateCLSIDs, 1},
|
||||
{ "EnumerateContractIDs", PyEnumerateContractIDs, 1},
|
||||
{ "enumerateContractIDs", PyEnumerateContractIDs, 1},
|
||||
{ "ContractIDToClassID", PyContractIDToClassID, 1},
|
||||
{ "contractIDToClassID", PyContractIDToClassID, 1},
|
||||
{ "CLSIDToContractID", PyCLSIDToContractID, 1},
|
||||
{ "createInstance", PyCreateInstance, 1},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/* ***** 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 the Python XPCOM language bindings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* ActiveState Tool Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mark Hammond <mhammond@skippinet.com.au> (original author)
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
//
|
||||
// This code is part of the XPCOM extensions for Python.
|
||||
//
|
||||
// Written May 2000 by Mark Hammond.
|
||||
//
|
||||
// Based heavily on the Python COM support, which is
|
||||
// (c) Mark Hammond and Greg Stein.
|
||||
//
|
||||
// (c) 2000, ActiveState corp.
|
||||
|
||||
#include "PyXPCOM_std.h"
|
||||
|
||||
static nsIComponentManagerObsolete *GetI(PyObject *self) {
|
||||
static const nsIID iid = NS_GET_IID(nsIComponentManagerObsolete);
|
||||
|
||||
if (!Py_nsISupports::Check(self, iid)) {
|
||||
PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
|
||||
return NULL;
|
||||
}
|
||||
return (nsIComponentManagerObsolete *)Py_nsISupports::GetI(self);
|
||||
}
|
||||
|
||||
static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *pid, *notyet = NULL;
|
||||
PyObject *obIID = NULL;
|
||||
if (!PyArg_ParseTuple(args, "s|zO", &pid, ¬yet, &obIID))
|
||||
return NULL;
|
||||
if (notyet != NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
|
||||
return NULL;
|
||||
}
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIID iid;
|
||||
if (obIID==NULL)
|
||||
iid = NS_GET_IID(nsISupports);
|
||||
else
|
||||
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
|
||||
return NULL;
|
||||
|
||||
nsISupports *pis;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->CreateInstanceByContractID(pid, NULL, iid, (void **)&pis);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
/* Return a type based on the IID (with no extra ref) */
|
||||
return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyContractIDToClassID(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *pid;
|
||||
if (!PyArg_ParseTuple(args, "s", &pid))
|
||||
return NULL;
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIID iid;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->ContractIDToClassID(pid, &iid);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsIID::PyObjectFromIID(iid);
|
||||
}
|
||||
|
||||
static PyObject *PyCLSIDToContractID(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *obIID;
|
||||
if (!PyArg_ParseTuple(args, "O", &obIID))
|
||||
return NULL;
|
||||
|
||||
nsIID iid;
|
||||
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
|
||||
return NULL;
|
||||
char *ret_pid = nsnull;
|
||||
char *ret_class = nsnull;
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->CLSIDToContractID(iid, &ret_class, &ret_pid);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
PyObject *ob_pid = PyString_FromString(ret_pid);
|
||||
PyObject *ob_class = PyString_FromString(ret_class);
|
||||
PyObject *ret = Py_BuildValue("OO", ob_pid, ob_class);
|
||||
nsMemory::Free(ret_pid);
|
||||
nsMemory::Free(ret_class);
|
||||
Py_XDECREF(ob_pid);
|
||||
Py_XDECREF(ob_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *PyEnumerateCLSIDs(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIEnumerator *pRet;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->EnumerateCLSIDs(&pRet);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *PyEnumerateContractIDs(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
|
||||
nsIComponentManagerObsolete *pI = GetI(self);
|
||||
if (pI==NULL)
|
||||
return NULL;
|
||||
|
||||
nsIEnumerator *pRet;
|
||||
nsresult r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = pI->EnumerateContractIDs(&pRet);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(r) )
|
||||
return PyXPCOM_BuildPyException(r);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
|
||||
}
|
||||
|
||||
struct PyMethodDef
|
||||
PyMethods_IComponentManagerObsolete[] =
|
||||
{
|
||||
{ "CreateInstanceByContractID", PyCreateInstanceByContractID, 1},
|
||||
{ "createInstanceByContractID", PyCreateInstanceByContractID, 1},
|
||||
{ "EnumerateCLSIDs", PyEnumerateCLSIDs, 1},
|
||||
{ "enumerateCLSIDs", PyEnumerateCLSIDs, 1},
|
||||
{ "EnumerateContractIDs", PyEnumerateContractIDs, 1},
|
||||
{ "enumerateContractIDs", PyEnumerateContractIDs, 1},
|
||||
{ "ContractIDToClassID", PyContractIDToClassID, 1},
|
||||
{ "contractIDToClassID", PyContractIDToClassID, 1},
|
||||
{ "CLSIDToContractID", PyCLSIDToContractID, 1},
|
||||
{NULL}
|
||||
};
|
||||
@@ -306,6 +306,10 @@ Py_nsISupports::PyObjectFromInterface(nsISupports *pis,
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
// FIXME: if !bAddRef, in all error cases, do NS_RELEASE(pis) before return
|
||||
// since that means we have a spare reference
|
||||
|
||||
PyTypeObject *createType = NULL;
|
||||
// If the IID is for nsISupports, dont bother with
|
||||
// a map lookup as we know the type!
|
||||
@@ -352,7 +356,6 @@ Py_nsISupports::MakeInterfaceResult(PyObject *pyis,
|
||||
NS_PRECONDITION(pyis, "NULL pyobject!");
|
||||
PyObject *obIID = NULL;
|
||||
PyObject *args = NULL;
|
||||
PyObject *func = NULL;
|
||||
PyObject *mod = NULL;
|
||||
PyObject *ret = NULL;
|
||||
|
||||
|
||||
@@ -64,10 +64,10 @@ static PyObject *MyChar( char c) {
|
||||
return PyString_FromStringAndSize(&c, 1);
|
||||
}
|
||||
static PyObject *MyUChar( PRUnichar c) {
|
||||
return PyUnicodeUCS2_FromUnicode(&c, 1);
|
||||
return PyUnicode_FromPRUnichar(&c, 1);
|
||||
}
|
||||
static PyObject *MyUnicode( PRUnichar *p) {
|
||||
return PyUnicodeUCS2_FromUnicode(p, nsCRT::strlen(p));
|
||||
return PyUnicode_FromPRUnichar(p, nsCRT::strlen(p));
|
||||
}
|
||||
static PyObject *MyISupports( nsISupports *p) {
|
||||
return Py_nsISupports::PyObjectFromInterface(p, NS_GET_IID(nsISupports), PR_FALSE);
|
||||
@@ -110,26 +110,26 @@ static PyObject *FuncGet(PyObject *self, PyObject *args) { \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
GET_SIMPLE(PRUint8, GetAsInt8, PyInt_FromLong);
|
||||
GET_SIMPLE(PRUint8, GetAsUint8, PyInt_FromLong);
|
||||
GET_SIMPLE(PRInt16, GetAsInt16, PyInt_FromLong);
|
||||
GET_SIMPLE(PRUint16, GetAsUint16, PyInt_FromLong);
|
||||
GET_SIMPLE(PRInt32, GetAsInt32, PyInt_FromLong);
|
||||
GET_SIMPLE(PRUint32, GetAsUint32, PyInt_FromLong);
|
||||
GET_SIMPLE(PRInt64, GetAsInt64, PyLong_FromLongLong);
|
||||
GET_SIMPLE(PRUint64, GetAsUint64, PyLong_FromUnsignedLongLong);
|
||||
GET_SIMPLE(float, GetAsFloat, PyFloat_FromDouble);
|
||||
GET_SIMPLE(double, GetAsDouble, PyFloat_FromDouble);
|
||||
GET_SIMPLE(PRBool, GetAsBool, MyBool);
|
||||
GET_SIMPLE(char, GetAsChar, MyChar);
|
||||
GET_SIMPLE(PRUnichar, GetAsWChar, MyUChar);
|
||||
GET_SIMPLE(nsISupports *, GetAsISupports, MyISupports);
|
||||
GET_SIMPLE(nsIID, GetAsID, Py_nsIID::PyObjectFromIID);
|
||||
GET_SIMPLE(PRUint8, GetAsInt8, PyInt_FromLong)
|
||||
GET_SIMPLE(PRUint8, GetAsUint8, PyInt_FromLong)
|
||||
GET_SIMPLE(PRInt16, GetAsInt16, PyInt_FromLong)
|
||||
GET_SIMPLE(PRUint16, GetAsUint16, PyInt_FromLong)
|
||||
GET_SIMPLE(PRInt32, GetAsInt32, PyInt_FromLong)
|
||||
GET_SIMPLE(PRUint32, GetAsUint32, PyInt_FromLong)
|
||||
GET_SIMPLE(PRInt64, GetAsInt64, PyLong_FromLongLong)
|
||||
GET_SIMPLE(PRUint64, GetAsUint64, PyLong_FromUnsignedLongLong)
|
||||
GET_SIMPLE(float, GetAsFloat, PyFloat_FromDouble)
|
||||
GET_SIMPLE(double, GetAsDouble, PyFloat_FromDouble)
|
||||
GET_SIMPLE(PRBool, GetAsBool, MyBool)
|
||||
GET_SIMPLE(char, GetAsChar, MyChar)
|
||||
GET_SIMPLE(PRUnichar, GetAsWChar, MyUChar)
|
||||
GET_SIMPLE(nsISupports *, GetAsISupports, MyISupports)
|
||||
GET_SIMPLE(nsIID, GetAsID, Py_nsIID::PyObjectFromIID)
|
||||
|
||||
GET_ALLOCATED(char *, GetAsString, PyString_FromString, nsMemory::Free);
|
||||
GET_ALLOCATED(PRUnichar *, GetAsWString, MyUnicode, nsMemory::Free);
|
||||
GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyString_FromStringAndSize, nsMemory::Free);
|
||||
GET_ALLOCATED_SIZE(PRUnichar *, GetAsWStringWithSize, PyUnicodeUCS2_FromUnicode, nsMemory::Free);
|
||||
GET_ALLOCATED(char *, GetAsString, PyString_FromString, nsMemory::Free)
|
||||
GET_ALLOCATED(PRUnichar *, GetAsWString, MyUnicode, nsMemory::Free)
|
||||
GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyString_FromStringAndSize, nsMemory::Free)
|
||||
GET_ALLOCATED_SIZE(PRUnichar *, GetAsWStringWithSize, PyUnicode_FromPRUnichar, nsMemory::Free)
|
||||
|
||||
static PyObject *GetAsInterface(PyObject *self, PyObject *args) {
|
||||
nsIVariant *pI = GetI(self);
|
||||
|
||||
@@ -117,6 +117,10 @@ PYXPCOM_EXPORT void PyXPCOM_LogDebug(const char *fmt, ...);
|
||||
#define PYXPCOM_LOG_DEBUG()
|
||||
#endif // DEBUG
|
||||
|
||||
// Create a Unicode Object from the PRUnichar buffer src of the given size
|
||||
#define PyUnicode_FromPRUnichar(src, size) \
|
||||
PyUnicode_DecodeUTF16((char*)(src),sizeof(PRUnichar)*(size),NULL,NULL)
|
||||
|
||||
/*************************************************************************
|
||||
**************************************************************************
|
||||
|
||||
@@ -466,7 +470,7 @@ public:
|
||||
PyXPCOM_GatewayWeakReference(PyG_Base *base);
|
||||
virtual ~PyXPCOM_GatewayWeakReference();
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEAKREFERENCE;
|
||||
NS_DECL_NSIWEAKREFERENCE
|
||||
PyG_Base *m_pBase; // NO REF COUNT!!!
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
char refcntLogRepr[41];
|
||||
@@ -724,14 +728,15 @@ PyXPCOM_TypeObject *ClassName::type = NULL;
|
||||
|
||||
|
||||
// And the classes
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManager, nsIComponentManagerObsolete, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIServiceManager, nsIServiceManager, PyMethods_IServiceManager)
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
|
||||
PyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
|
||||
PyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
|
||||
// deprecated, but retained for backward compatibility:
|
||||
PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
|
||||
|
||||
#endif // __PYXPCOM_H__
|
||||
|
||||
@@ -49,16 +49,24 @@
|
||||
//
|
||||
// (c) 2000, ActiveState corp.
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
// Mozilla also defines this - we undefine it to
|
||||
// prevent a compiler warning.
|
||||
# undef HAVE_LONG_LONG
|
||||
#endif // HAVE_LONG_LONG
|
||||
|
||||
#include "nsIAllocator.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIComponentManagerObsolete.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "xptcall.h"
|
||||
@@ -68,11 +76,4 @@
|
||||
// we can use it to trigger "exports"
|
||||
#define BUILD_PYXPCOM
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
// Mozilla also defines this - we undefine it to
|
||||
// prevent a compiler warning.
|
||||
# undef HAVE_LONG_LONG
|
||||
#endif // HAVE_LONG_LONG
|
||||
|
||||
#include "Python.h"
|
||||
#include "PyXPCOM.h"
|
||||
|
||||
@@ -152,24 +152,27 @@ PyObject *PyObject_FromXPTConstant( const XPTConstDescriptor *c)
|
||||
v = PyString_FromStringAndSize(&c->value.ch, 1);
|
||||
break;
|
||||
case TD_WCHAR:
|
||||
v = PyUnicode_FromUnicode((PRUnichar *)&c->value.wch, 1);
|
||||
v = PyUnicode_FromPRUnichar((PRUnichar *)&c->value.wch, 1);
|
||||
break;
|
||||
// TD_VOID = 13,
|
||||
case TD_PNSIID:
|
||||
v = Py_nsIID::PyObjectFromIID(*c->value.iid);
|
||||
break;
|
||||
// TD_PBSTR = 15,
|
||||
// TD_DOMSTRING = 15,
|
||||
case TD_PSTRING:
|
||||
v = PyString_FromString(c->value.str);
|
||||
break;
|
||||
case TD_PWSTRING:
|
||||
v = PyUnicode_FromUnicode((PRUnichar *)c->value.wstr, nsCRT::strlen((PRUnichar *)c->value.wstr));
|
||||
v = PyUnicode_FromPRUnichar((PRUnichar *)c->value.wstr, nsCRT::strlen((PRUnichar *)c->value.wstr));
|
||||
break;
|
||||
// TD_INTERFACE_TYPE = 18,
|
||||
// TD_INTERFACE_IS_TYPE = 19,
|
||||
// TD_ARRAY = 20,
|
||||
// TD_PSTRING_SIZE_IS = 21,
|
||||
// TD_PWSTRING_SIZE_IS = 22
|
||||
// TD_UTF8STRING = 23,
|
||||
// TD_CSTRING = 24,
|
||||
// TD_ASTRING = 25
|
||||
default:
|
||||
v = PyString_FromString("Unknown type code!!");
|
||||
break;
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
* Contributor(s):
|
||||
* Mark Hammond <mhammond@skippinet.com.au> (original author)
|
||||
*
|
||||
* Unicode corrections by Shane Hathaway (http://hathawaymix.org),
|
||||
* inspired by Mikhail Sobolev
|
||||
*
|
||||
* 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"),
|
||||
@@ -69,6 +72,38 @@ IsNullDOMString( const nsACString& aString )
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Create a zero-terminated PRUnichar buffer from a Python unicode.
|
||||
// On success, returns 0. On failure, returns -1 and sets an exception.
|
||||
// dest_out must not be null. size_out may be null.
|
||||
static int
|
||||
PyUnicode_AsPRUnichar(PyObject *obj, PRUnichar **dest_out, PRUint32 *size_out)
|
||||
{
|
||||
PRUint32 size;
|
||||
PyObject *s;
|
||||
PRUnichar *dest;
|
||||
|
||||
s = PyUnicode_AsUTF16String(obj);
|
||||
if (!s)
|
||||
return -1;
|
||||
size = (PyString_GET_SIZE(s) - 2) / sizeof(PRUnichar);
|
||||
dest = (PRUnichar *)nsMemory::Alloc(sizeof(PRUnichar) * (size + 1));
|
||||
if (!dest) {
|
||||
PyErr_NoMemory();
|
||||
Py_DECREF(s);
|
||||
return -1;
|
||||
}
|
||||
// Drop the UTF-16 byte order mark at the beginning of
|
||||
// the string. (See the docs on PyUnicode_AsUTF16String.)
|
||||
// Some Mozilla libraries don't like the mark.
|
||||
memcpy(dest, PyString_AS_STRING(s) + 2, sizeof(PRUnichar) * size);
|
||||
Py_DECREF(s);
|
||||
dest[size] = 0;
|
||||
*dest_out = dest;
|
||||
if (size_out)
|
||||
*size_out = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *PyObject_FromNSString( const nsACString &s, PRBool bAssumeUTF8 = PR_FALSE )
|
||||
{
|
||||
PyObject *ret;
|
||||
@@ -77,11 +112,12 @@ PyObject *PyObject_FromNSString( const nsACString &s, PRBool bAssumeUTF8 = PR_FA
|
||||
Py_INCREF(Py_None);
|
||||
} else {
|
||||
if (bAssumeUTF8) {
|
||||
char *temp = ToNewCString(s);
|
||||
ret = PyUnicode_DecodeUTF8(temp, s.Length(), NULL);
|
||||
nsMemory::Free(temp);
|
||||
const nsPromiseFlatCString& temp = PromiseFlatCString(s);
|
||||
ret = PyUnicode_DecodeUTF8(temp.get(), temp.Length(), NULL);
|
||||
} else {
|
||||
ret = PyString_FromStringAndSize(NULL, s.Length());
|
||||
if (!ret)
|
||||
return NULL;
|
||||
// Need "CopyAsciiTo"!?
|
||||
nsACString::const_iterator fromBegin, fromEnd;
|
||||
char* dest = PyString_AS_STRING(ret);
|
||||
@@ -98,8 +134,8 @@ PyObject *PyObject_FromNSString( const nsAString &s )
|
||||
ret = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
} else {
|
||||
ret = PyUnicodeUCS2_FromUnicode( NULL, s.Length() );
|
||||
CopyUnicodeTo(s, 0, PyUnicodeUCS2_AsUnicode(ret), s.Length());
|
||||
const nsPromiseFlatString& temp = PromiseFlatString(s);
|
||||
ret = PyUnicode_FromPRUnichar(temp.get(), temp.Length());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -207,7 +243,7 @@ void FreeSingleArray(void *array_ptr, PRUint32 sequence_size, PRUint8 array_type
|
||||
}
|
||||
}
|
||||
|
||||
#define FILL_SIMPLE_POINTER( type, val ) *((type *)pthis) = (type)(val);
|
||||
#define FILL_SIMPLE_POINTER( type, val ) *((type *)pthis) = (type)(val)
|
||||
#define BREAK_FALSE {rc=PR_FALSE;break;}
|
||||
|
||||
|
||||
@@ -303,9 +339,10 @@ PRBool FillSingleArray(void *array_ptr, PyObject *sequence_ob, PRUint32 sequence
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val)) == NULL)
|
||||
BREAK_FALSE;
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
// Lossy!
|
||||
FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) );
|
||||
break;
|
||||
|
||||
@@ -369,18 +406,11 @@ PRBool FillSingleArray(void *array_ptr, PyObject *sequence_ob, PRUint32 sequence
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
const PRUnichar *sz = PyUnicode_AS_UNICODE(val_use);
|
||||
int nch = PyUnicode_GET_SIZE(val_use);
|
||||
|
||||
*pp = (PRUnichar *)nsMemory::Alloc(sizeof(PRUnichar) * (nch+1));
|
||||
if (*pp==NULL) {
|
||||
PyErr_NoMemory();
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
|
||||
BREAK_FALSE;
|
||||
}
|
||||
memcpy(*pp, sz, sizeof(PRUnichar) * (nch + 1));
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_INTERFACE_IS: // hmm - ignoring the IID can't be good :(
|
||||
@@ -476,8 +506,9 @@ PyObject *UnpackSingleArray(void *array_ptr, PRUint32 sequence_size, PRUint8 arr
|
||||
if (*pp==NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
val = Py_None;
|
||||
} else
|
||||
val = PyUnicodeUCS2_FromUnicode( *pp, nsCRT::strlen(*pp) );
|
||||
} else {
|
||||
val = PyUnicode_FromPRUnichar( *pp, nsCRT::strlen(*pp) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_INTERFACE_IS:
|
||||
@@ -532,8 +563,11 @@ static PRUint16 BestVariantTypeForPyObject( PyObject *ob, BVFTResult *pdata = NU
|
||||
return nsIDataType::VTYPE_STRING_SIZE_IS;
|
||||
if (PyUnicode_Check(ob))
|
||||
return nsIDataType::VTYPE_WSTRING_SIZE_IS;
|
||||
if (PyTuple_Check(ob) || PyList_Check(ob))
|
||||
return PySequence_Length(ob) ? nsIDataType::VTYPE_ARRAY : nsIDataType::VTYPE_EMPTY_ARRAY;
|
||||
if (PyTuple_Check(ob) || PyList_Check(ob)) {
|
||||
if (PySequence_Length(ob))
|
||||
return nsIDataType::VTYPE_ARRAY;
|
||||
return nsIDataType::VTYPE_EMPTY_ARRAY;
|
||||
}
|
||||
// Now do expensive or abstract checks.
|
||||
if (Py_nsISupports::InterfaceFromPyObject(ob, NS_GET_IID(nsISupports), &ps, PR_TRUE)) {
|
||||
if (pdata) {
|
||||
@@ -550,8 +584,11 @@ static PRUint16 BestVariantTypeForPyObject( PyObject *ob, BVFTResult *pdata = NU
|
||||
return nsIDataType::VTYPE_ID;
|
||||
} else
|
||||
PyErr_Clear();
|
||||
if (PySequence_Check(ob))
|
||||
return PySequence_Length(ob) ? nsIDataType::VTYPE_ARRAY : nsIDataType::VTYPE_EMPTY_ARRAY;
|
||||
if (PySequence_Check(ob)) {
|
||||
if (PySequence_Length(ob))
|
||||
return nsIDataType::VTYPE_ARRAY;
|
||||
return nsIDataType::VTYPE_EMPTY_ARRAY;
|
||||
}
|
||||
return (PRUint16)-1;
|
||||
}
|
||||
|
||||
@@ -584,7 +621,19 @@ nsIVariant *PyObject_AsVariant( PyObject *ob)
|
||||
nr = v->SetAsStringWithSize(PyString_Size(ob), PyString_AsString(ob));
|
||||
break;
|
||||
case nsIDataType::VTYPE_WSTRING_SIZE_IS:
|
||||
nr = v->SetAsWStringWithSize(PyUnicodeUCS2_GetSize(ob), PyUnicodeUCS2_AsUnicode(ob));
|
||||
if (PyUnicode_GetSize(ob) == 0) {
|
||||
nr = v->SetAsWStringWithSize(0, (PRUnichar*)NULL);
|
||||
}
|
||||
else {
|
||||
PRUint32 nch;
|
||||
PRUnichar *p;
|
||||
if (PyUnicode_AsPRUnichar(ob, &p, &nch) < 0) {
|
||||
nr = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
nr = v->SetAsWStringWithSize(nch, p);
|
||||
nsMemory::Free(p);
|
||||
}
|
||||
break;
|
||||
case nsIDataType::VTYPE_INTERFACE_IS:
|
||||
{
|
||||
@@ -758,6 +807,8 @@ PyObject *PyObject_FromVariant( nsIVariant *v)
|
||||
if (NS_FAILED(nr=v->GetAsInterface(&iid, (void **)&p))) goto done;
|
||||
ret = Py_nsISupports::PyObjectFromInterface(p, *iid, PR_FALSE);
|
||||
break;
|
||||
// case nsIDataType::VTYPE_WCHAR_STR
|
||||
// case nsIDataType::VTYPE_UTF8STRING
|
||||
}
|
||||
}
|
||||
done:
|
||||
@@ -1143,14 +1194,15 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
// Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a unicode object!");
|
||||
if (PyUnicode_GET_SIZE(val_use) != 1) {
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a unicode object!");
|
||||
if (PyUnicode_GetSize(val_use) != 1) {
|
||||
PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
// Lossy!
|
||||
ns_v.val.wc = *PyUnicode_AS_UNICODE(val_use);
|
||||
break;
|
||||
}
|
||||
@@ -1172,12 +1224,21 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
// Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a unicode object!");
|
||||
ns_v.val.p = new nsString(PyUnicode_AS_UNICODE(val_use),
|
||||
PyUnicode_GET_SIZE(val_use));
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a unicode object!");
|
||||
if (PyUnicode_GET_SIZE(val_use) == 0) {
|
||||
ns_v.val.p = new nsString();
|
||||
}
|
||||
else {
|
||||
PRUint32 nch;
|
||||
PRUnichar *tempo;
|
||||
if (PyUnicode_AsPRUnichar(val_use, &tempo, &nch) < 0)
|
||||
BREAK_FALSE;
|
||||
ns_v.val.p = new nsString(tempo, nch);
|
||||
nsMemory::Free(tempo);
|
||||
}
|
||||
}
|
||||
if (!ns_v.val.p) {
|
||||
PyErr_NoMemory();
|
||||
@@ -1254,22 +1315,19 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
|
||||
ns_v.val.p = nsnull;
|
||||
break;
|
||||
}
|
||||
// If an "in" char *, and we have a PyString, then pass the
|
||||
// pointer (hoping everyone else plays by the rules too.
|
||||
if (!XPT_PD_IS_OUT(td.param_flags) && PyUnicode_Check(val)) {
|
||||
ns_v.val.p = PyUnicode_AS_UNICODE(val);
|
||||
break;
|
||||
}
|
||||
if (!PyString_Check(val) && !PyUnicode_Check(val)) {
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
cb_this_buffer_pointer = (PyUnicode_GET_SIZE(val_use)+1) * sizeof(Py_UNICODE);
|
||||
MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
|
||||
memcpy(this_buffer_pointer, PyUnicode_AS_UNICODE(val_use), cb_this_buffer_pointer);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
PRUnichar *sv;
|
||||
PRUint32 nch;
|
||||
if (PyUnicode_AsPRUnichar(val_use, &sv, &nch) < 0)
|
||||
BREAK_FALSE;
|
||||
cb_this_buffer_pointer = (nch + 1) * sizeof(PRUnichar);
|
||||
this_buffer_pointer = sv;
|
||||
ns_v.val.p = this_buffer_pointer;
|
||||
break;
|
||||
}
|
||||
@@ -1346,16 +1404,18 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
// Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyObject_Unicode didnt return a unicode object!");
|
||||
|
||||
cb_this_buffer_pointer = PyUnicode_GET_SIZE(val_use) * sizeof(PRUnichar);
|
||||
MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
|
||||
memcpy(this_buffer_pointer, PyUnicode_AS_UNICODE(val_use), cb_this_buffer_pointer);
|
||||
PRUnichar *sv;
|
||||
PRUint32 nch;
|
||||
if (PyUnicode_AsPRUnichar(val_use, &sv, &nch) < 0)
|
||||
BREAK_FALSE;
|
||||
cb_this_buffer_pointer = (nch + 1) * sizeof(PRUnichar);
|
||||
this_buffer_pointer = sv;
|
||||
ns_v.val.p = this_buffer_pointer;
|
||||
rc = SetSizeIs(value_index, PR_TRUE, PyUnicode_GET_SIZE(val_use) );
|
||||
rc = SetSizeIs(value_index, PR_TRUE, nch);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_ARRAY: {
|
||||
@@ -1556,7 +1616,7 @@ PyObject *PyXPCOM_InterfaceVariantHelper::MakeSinglePythonResult(int index)
|
||||
break;
|
||||
|
||||
case nsXPTType::T_WCHAR:
|
||||
ret = PyUnicodeUCS2_FromUnicode( ((PRUnichar *)ns_v.ptr), 1 );
|
||||
ret = PyUnicode_FromPRUnichar( ((PRUnichar *)ns_v.ptr), 1 );
|
||||
break;
|
||||
// case nsXPTType::T_VOID:
|
||||
case nsXPTType::T_IID:
|
||||
@@ -1588,8 +1648,9 @@ PyObject *PyXPCOM_InterfaceVariantHelper::MakeSinglePythonResult(int index)
|
||||
if (us == NULL) {
|
||||
ret = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
} else
|
||||
ret = PyUnicodeUCS2_FromUnicode( us, nsCRT::strlen(us));
|
||||
} else {
|
||||
ret = PyUnicode_FromPRUnichar( us, nsCRT::strlen(us));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_INTERFACE: {
|
||||
@@ -1655,7 +1716,7 @@ PyObject *PyXPCOM_InterfaceVariantHelper::MakeSinglePythonResult(int index)
|
||||
Py_INCREF(Py_None);
|
||||
} else {
|
||||
PRUint32 string_size = GetSizeIs(index, PR_TRUE);
|
||||
ret = PyUnicodeUCS2_FromUnicode( *((PRUnichar **)ns_v.ptr), string_size );
|
||||
ret = PyUnicode_FromPRUnichar( *((PRUnichar **)ns_v.ptr), string_size );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1905,7 +1966,7 @@ PyObject *PyXPCOM_GatewayVariantHelper::MakeSingleParam(int index, PythonTypeDes
|
||||
}
|
||||
case nsXPTType::T_WCHAR: {
|
||||
PRUnichar temp = (PRUnichar)DEREF_IN_OR_OUT(ns_v.val.wc, PRUnichar);
|
||||
ret = PyUnicodeUCS2_FromUnicode(&temp, 1);
|
||||
ret = PyUnicode_FromPRUnichar(&temp, 1);
|
||||
break;
|
||||
}
|
||||
// case nsXPTType::T_VOID:
|
||||
@@ -1942,8 +2003,9 @@ PyObject *PyXPCOM_GatewayVariantHelper::MakeSingleParam(int index, PythonTypeDes
|
||||
if (us==NULL) {
|
||||
ret = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
} else
|
||||
ret = PyUnicodeUCS2_FromUnicode( us, nsCRT::strlen(us));
|
||||
} else {
|
||||
ret = PyUnicode_FromPRUnichar( us, nsCRT::strlen(us));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_INTERFACE_IS: // our Python code does it :-)
|
||||
@@ -2000,8 +2062,9 @@ PyObject *PyXPCOM_GatewayVariantHelper::MakeSingleParam(int index, PythonTypeDes
|
||||
if (t==NULL) {
|
||||
ret = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
} else
|
||||
ret = PyUnicodeUCS2_FromUnicode(t, string_size);
|
||||
} else {
|
||||
ret = PyUnicode_FromPRUnichar(t, string_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2082,7 +2145,7 @@ nsIInterfaceInfo *PyXPCOM_GatewayVariantHelper::GetInterfaceInfo()
|
||||
}
|
||||
|
||||
#undef FILL_SIMPLE_POINTER
|
||||
#define FILL_SIMPLE_POINTER( type, ob ) *((type *)ns_v.val.p) = (type)(ob);
|
||||
#define FILL_SIMPLE_POINTER( type, ob ) *((type *)ns_v.val.p) = (type)(ob)
|
||||
|
||||
nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index)
|
||||
{
|
||||
@@ -2160,9 +2223,10 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
if ((val_use = PyUnicodeUCS2_FromObject(val))==NULL)
|
||||
if ((val_use = PyUnicode_FromObject(val))==NULL)
|
||||
BREAK_FALSE;
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
// Lossy!
|
||||
FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) );
|
||||
break;
|
||||
|
||||
@@ -2195,10 +2259,21 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
val_use = PyUnicodeUCS2_FromObject(val);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
const PRUnichar *sz = PyUnicode_AS_UNICODE(val_use);
|
||||
ws->Assign(sz, PyUnicode_GET_SIZE(val_use));
|
||||
val_use = PyUnicode_FromObject(val);
|
||||
if (!val_use)
|
||||
BREAK_FALSE;
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didn't return a Unicode object!");
|
||||
if (PyUnicode_GET_SIZE(val_use) == 0) {
|
||||
ws->Assign((PRUnichar*)NULL, 0);
|
||||
}
|
||||
else {
|
||||
PRUint32 nch;
|
||||
PRUnichar *sz;
|
||||
if (PyUnicode_AsPRUnichar(val_use, &sz, &nch) < 0)
|
||||
BREAK_FALSE;
|
||||
ws->Assign(sz, nch);
|
||||
nsMemory::Free(sz);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2282,17 +2357,10 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
val_use = PyUnicodeUCS2_FromObject(val);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
const PRUnichar *sz = PyUnicode_AS_UNICODE(val_use);
|
||||
int nch = PyUnicode_GET_SIZE(val_use);
|
||||
|
||||
*pp = (PRUnichar *)nsMemory::Alloc(sizeof(PRUnichar) * (nch+1));
|
||||
if (*pp==NULL) {
|
||||
PyErr_NoMemory();
|
||||
val_use = PyUnicode_FromObject(val);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
|
||||
BREAK_FALSE;
|
||||
}
|
||||
memcpy(*pp, sz, sizeof(PRUnichar) * (nch + 1));
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_INTERFACE: {
|
||||
@@ -2399,7 +2467,7 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
}
|
||||
|
||||
case nsXPTType::T_PWSTRING_SIZE_IS: {
|
||||
const PRUnichar *sz = nsnull;
|
||||
PRUnichar *sz = nsnull;
|
||||
PRUint32 nch = 0;
|
||||
PRUint32 nbytes = 0;
|
||||
|
||||
@@ -2408,10 +2476,10 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
|
||||
BREAK_FALSE;
|
||||
}
|
||||
val_use = PyUnicodeUCS2_FromObject(val);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicodeUCS2_FromObject didnt return a Unicode object!");
|
||||
sz = PyUnicode_AS_UNICODE(val_use);
|
||||
nch = PyUnicode_GET_SIZE(val_use);
|
||||
val_use = PyUnicode_FromObject(val);
|
||||
NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
|
||||
if (PyUnicode_AsPRUnichar(val_use, &sz, &nch) < 0)
|
||||
BREAK_FALSE;
|
||||
nbytes = sizeof(PRUnichar) * nch;
|
||||
}
|
||||
PRBool bBackFill = PR_FALSE;
|
||||
@@ -2436,22 +2504,16 @@ nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index
|
||||
PRUnichar **pp = (PRUnichar **)ns_v.val.p;
|
||||
if (*pp && pi->IsIn())
|
||||
nsMemory::Free(*pp);
|
||||
*pp = nsnull;
|
||||
|
||||
if (val == Py_None)
|
||||
break; // Remains NULL.
|
||||
*pp = (PRUnichar *)nsMemory::Alloc(nbytes);
|
||||
if (*pp==NULL) {
|
||||
PyErr_NoMemory();
|
||||
BREAK_FALSE;
|
||||
}
|
||||
memcpy(*pp, sz, nbytes);
|
||||
*pp = sz;
|
||||
sz = nsnull;
|
||||
if (bCanSetSizeIs)
|
||||
rc = SetSizeIs(index, PR_TRUE, nch);
|
||||
else {
|
||||
NS_ABORT_IF_FALSE(GetSizeIs(index, PR_TRUE) == nch, "Can't set sizeis, but string isnt correct size");
|
||||
}
|
||||
}
|
||||
if (sz)
|
||||
nsMemory::Free(sz);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_ARRAY: {
|
||||
|
||||
@@ -43,8 +43,13 @@
|
||||
// the xpcom "components" directory. Simply locates and loads the standard
|
||||
// _xpcom support module and transfers control to that.
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
#undef HAVE_LONG_LONG
|
||||
#endif
|
||||
|
||||
#include "nsIComponentLoader.h"
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
@@ -57,15 +62,8 @@
|
||||
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include <nsFileStream.h> // For console logging.
|
||||
#include "nspr.h" // PR_fprintf
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
#undef HAVE_LONG_LONG
|
||||
#endif
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#if (PY_VERSION_HEX >= 0x02030000)
|
||||
#define PYXPCOM_USE_PYGILSTATE
|
||||
#endif
|
||||
@@ -100,10 +98,10 @@ static void LogDebug(const char *fmt, ...);
|
||||
void AddStandardPaths()
|
||||
{
|
||||
// Put {bin}\Python on the path if it exists.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> aFile;
|
||||
nsCOMPtr<nsILocalFile> aLocalFile;
|
||||
NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile));
|
||||
if (!aFile) {
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
LogError("The Python XPCOM loader could not locate the 'bin' directory\n");
|
||||
return;
|
||||
}
|
||||
@@ -245,9 +243,7 @@ void LogMessage(const char *prefix, const char *pszMessageText)
|
||||
|
||||
void LogMessage(const char *prefix, nsACString &text)
|
||||
{
|
||||
char *c = ToNewCString(text);
|
||||
LogMessage(prefix, c);
|
||||
nsCRT::free(c);
|
||||
LogMessage(prefix, nsPromiseFlatCString(text).get());
|
||||
}
|
||||
|
||||
// A helper for the various logging routines.
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
#include "nsIModule.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#include "nsIComponentManagerObsolete.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
@@ -75,7 +77,7 @@ extern void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
|
||||
extern void PyXPCOM_InterpreterState_Ensure();
|
||||
#endif
|
||||
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManagerObsolete, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
|
||||
@@ -83,6 +85,8 @@ PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInter
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
|
||||
// deprecated, but retained for backward compatibility:
|
||||
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// This is the main entry point called by the Python component
|
||||
@@ -145,30 +149,47 @@ done:
|
||||
// "boot-strap" methods - interfaces we need to get the base
|
||||
// interface support!
|
||||
|
||||
/* deprecated, included for backward compatibility */
|
||||
static PyObject *
|
||||
PyXPCOMMethod_NS_GetGlobalComponentManager(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetComponentManager instead") < 0)
|
||||
return NULL;
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rv = NS_GetComponentManager(&cm);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(rv) )
|
||||
return PyXPCOM_BuildPyException(rv);
|
||||
|
||||
nsCOMPtr<nsIComponentManagerObsolete> ocm(do_QueryInterface(cm, &rv));
|
||||
if ( NS_FAILED(rv) )
|
||||
return PyXPCOM_BuildPyException(rv);
|
||||
|
||||
return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManagerObsolete), PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyXPCOMMethod_GetComponentManager(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rv = NS_GetGlobalComponentManager(&cm);
|
||||
rv = NS_GetComponentManager(&cm);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( NS_FAILED(rv) )
|
||||
return PyXPCOM_BuildPyException(rv);
|
||||
// NOTE - NS_GetGlobalComponentManager DOES NOT ADD A REFCOUNT
|
||||
// (naughty, naughty) - we we explicitly ask our converter to
|
||||
// add one, even tho this is not the common pattern.
|
||||
|
||||
// Return a type based on the IID
|
||||
// Can not auto-wrap the interface info manager as it is critical to
|
||||
// building the support we need for autowrap.
|
||||
return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManagerObsolete), PR_TRUE, PR_FALSE);
|
||||
return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManager), PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args)
|
||||
PyXPCOMMethod_GetServiceManager(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return NULL;
|
||||
@@ -184,8 +205,16 @@ PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args)
|
||||
return Py_nsISupports::PyObjectFromInterface(sm, NS_GET_IID(nsIServiceManager), PR_FALSE);
|
||||
}
|
||||
|
||||
/* deprecated, included for backward compatibility */
|
||||
static PyObject *
|
||||
PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetServiceManager instead") < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
return PyXPCOMMethod_GetComponentManager(self, args);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyXPCOMMethod_XPTI_GetInterfaceInfoManager(PyObject *self, PyObject *args)
|
||||
{
|
||||
@@ -439,10 +468,12 @@ extern PyObject *PyXPCOMMethod_IID(PyObject *self, PyObject *args);
|
||||
|
||||
static struct PyMethodDef xpcom_methods[]=
|
||||
{
|
||||
{"NS_GetGlobalComponentManager", PyXPCOMMethod_NS_GetGlobalComponentManager, 1},
|
||||
{"GetComponentManager", PyXPCOMMethod_GetComponentManager, 1},
|
||||
{"NS_GetGlobalComponentManager", PyXPCOMMethod_NS_GetGlobalComponentManager, 1}, // deprecated
|
||||
{"XPTI_GetInterfaceInfoManager", PyXPCOMMethod_XPTI_GetInterfaceInfoManager, 1},
|
||||
{"XPTC_InvokeByIndex", PyXPCOMMethod_XPTC_InvokeByIndex, 1},
|
||||
{"GetGlobalServiceManager", PyXPCOMMethod_GetGlobalServiceManager, 1},
|
||||
{"GetServiceManager", PyXPCOMMethod_GetServiceManager, 1},
|
||||
{"GetGlobalServiceManager", PyXPCOMMethod_GetGlobalServiceManager, 1}, // deprecated
|
||||
{"IID", PyXPCOMMethod_IID, 1}, // IID is wrong - deprecated - not just IID, but CID, etc.
|
||||
{"ID", PyXPCOMMethod_IID, 1}, // This is the official name.
|
||||
{"NS_ShutdownXPCOM", PyXPCOMMethod_NS_ShutdownXPCOM, 1},
|
||||
@@ -492,15 +523,17 @@ PRBool PyXPCOM_Globals_Ensure()
|
||||
// Is there an official way to determine this?
|
||||
if (NS_FAILED(nsIThread::GetMainThread(getter_AddRefs(thread_check)))) {
|
||||
// not already initialized.
|
||||
|
||||
// We need to locate the Mozilla bin directory.
|
||||
#ifdef XP_WIN
|
||||
// On Windows this by using "xpcom.dll"
|
||||
|
||||
// On Windows, we need to locate the Mozilla bin
|
||||
// directory. This by using locating a Moz DLL we depend
|
||||
// on, and assume it lives in that bin dir. Different
|
||||
// moz build types (eg, xulrunner, suite) package
|
||||
// XPCOM itself differently - but all appear to require
|
||||
// nspr4.dll - so this is what we use.
|
||||
char landmark[MAX_PATH+1];
|
||||
HMODULE hmod = GetModuleHandle("xpcom.dll");
|
||||
HMODULE hmod = GetModuleHandle("nspr4.dll");
|
||||
if (hmod==NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "We dont appear to be linked against xpcom.dll!?!?");
|
||||
PyErr_SetString(PyExc_RuntimeError, "We dont appear to be linked against nspr4.dll.");
|
||||
return PR_FALSE;
|
||||
}
|
||||
GetModuleFileName(hmod, landmark, sizeof(landmark)/sizeof(landmark[0]));
|
||||
@@ -510,7 +543,7 @@ PRBool PyXPCOM_Globals_Ensure()
|
||||
if (end > landmark) *end = '\0';
|
||||
|
||||
nsCOMPtr<nsILocalFile> ns_bin_dir;
|
||||
NS_ConvertASCIItoUCS2 strLandmark(landmark);
|
||||
NS_ConvertASCIItoUCS2 strLandmark(landmark);
|
||||
NS_NewLocalFile(strLandmark, PR_FALSE, getter_AddRefs(ns_bin_dir));
|
||||
nsresult rv = NS_InitXPCOM2(nsnull, ns_bin_dir, nsnull);
|
||||
#else
|
||||
@@ -545,10 +578,7 @@ PRBool PyXPCOM_Globals_Ensure()
|
||||
////////////////////////////////////////////////////////////
|
||||
// The module init code.
|
||||
//
|
||||
extern "C"
|
||||
#ifdef MS_WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
extern "C" NS_EXPORT
|
||||
void
|
||||
init_xpcom() {
|
||||
PyObject *oModule;
|
||||
@@ -588,6 +618,7 @@ init_xpcom() {
|
||||
REGISTER_IID(nsISupportsWeakReference);
|
||||
REGISTER_IID(nsIClassInfo);
|
||||
REGISTER_IID(nsIServiceManager);
|
||||
REGISTER_IID(nsIComponentRegistrar);
|
||||
// Register our custom interfaces.
|
||||
|
||||
Py_nsISupports::InitType();
|
||||
@@ -599,13 +630,8 @@ init_xpcom() {
|
||||
Py_nsIInputStream::InitType(dict);
|
||||
Py_nsIClassInfo::InitType(dict);
|
||||
Py_nsIVariant::InitType(dict);
|
||||
|
||||
// yet another
|
||||
{ // temp scope nsIComponentManagerObsolete hack :(
|
||||
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(NS_GET_IID(nsIComponentManagerObsolete));
|
||||
PyDict_SetItemString(dict, "IID_nsIComponentManager", iid_ob);
|
||||
Py_DECREF(iid_ob);
|
||||
} // end temp scope
|
||||
// for backward compatibility:
|
||||
Py_nsIComponentManagerObsolete::InitType(dict);
|
||||
|
||||
// We have special support for proxies - may as well add their constants!
|
||||
REGISTER_INT(PROXY_SYNC);
|
||||
|
||||
@@ -57,7 +57,7 @@ tests = tests or test.regrtest.findtests(path, [])
|
||||
try:
|
||||
# unittest based tests first - hopefully soon this will be the default!
|
||||
if not sys.argv[1:]:
|
||||
for t in "test_misc".split():
|
||||
for t in "test_misc test_streams".split():
|
||||
m = __import__(t)
|
||||
try:
|
||||
unittest.main(m)
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
"""Test the xpcom.file module."""
|
||||
# Called "test_comfile" as Python has a standard test called test_file :-(
|
||||
import xpcom.file
|
||||
xpcom.file._TestAll()
|
||||
xpcom.file._TestAll()
|
||||
|
||||
@@ -105,15 +105,13 @@ class TestDumpInterfaces(unittest.TestCase):
|
||||
class TestEnumContractIDs(unittest.TestCase):
|
||||
def testContractIDs(self):
|
||||
"""Enumerate all the ContractIDs registered"""
|
||||
cm = xpcom._xpcom.NS_GetGlobalComponentManager()
|
||||
enum = cm.EnumerateContractIDs()
|
||||
rc = enum.First()
|
||||
enum = xpcom.components.registrar.enumerateContractIDs()
|
||||
n = 0
|
||||
while rc == 0:
|
||||
while enum.hasMoreElements():
|
||||
item = enum.getNext(xpcom.components.interfaces.nsISupportsCString)
|
||||
n = n + 1
|
||||
if verbose_level:
|
||||
print "ContractID:", enum.CurrentItem()
|
||||
rc = enum.Next()
|
||||
print "ContractID:", item.data
|
||||
if n < 200:
|
||||
print "Only found", n, "ContractIDs - this seems unusually low!"
|
||||
|
||||
@@ -191,7 +189,7 @@ class TestRepr(unittest.TestCase):
|
||||
ob = xpcom.components.classes[progid].createInstance()
|
||||
else:
|
||||
ob = progid
|
||||
self.failUnless(repr(ob).find(progid) >= 0, repr(ob))
|
||||
self.failUnless(repr(ob).find(str(progid)) >= 0, repr(ob))
|
||||
for interface_name in interfaces.split():
|
||||
self.failUnless(repr(ob).find(interface_name) >= 0, repr(ob))
|
||||
|
||||
|
||||
@@ -38,15 +38,17 @@
|
||||
import xpcom
|
||||
from xpcom import _xpcom, components, COMException, ServerException, nsError
|
||||
from StringIO import StringIO
|
||||
import unittest
|
||||
|
||||
test_data = "abcdefeghijklmnopqrstuvwxyz"
|
||||
|
||||
class koTestSimpleStreamBase:
|
||||
class koTestSimpleStream:
|
||||
_com_interfaces_ = [components.interfaces.nsIInputStream]
|
||||
# We avoid registering this object - see comments in get_test_inout_? below.
|
||||
|
||||
def __init__(self):
|
||||
self.data=StringIO(test_data)
|
||||
self._non_blocking = False
|
||||
|
||||
def close( self ):
|
||||
pass
|
||||
@@ -65,56 +67,29 @@ class koTestSimpleStreamBase:
|
||||
def set_observer( self, param0 ):
|
||||
raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
|
||||
|
||||
# This class has "nonBlocking" as an attribute.
|
||||
class koTestSimpleStream1(koTestSimpleStreamBase):
|
||||
nonBlocking=0
|
||||
def isNonBlocking(self):
|
||||
return self._non_blocking
|
||||
|
||||
# This class has "nonBlocking" as getter/setters.
|
||||
class koTestSimpleStream2(koTestSimpleStreamBase):
|
||||
def __init__(self):
|
||||
koTestSimpleStreamBase.__init__(self)
|
||||
self.isNonBlocking = 0
|
||||
def get_nonBlocking(self):
|
||||
return self.isNonBlocking
|
||||
|
||||
def get_test_input_1():
|
||||
def get_test_input():
|
||||
# We use a couple of internal hacks here that mean we can avoid having the object
|
||||
# registered. This code means that we are still working over the xpcom boundaries, tho
|
||||
# (and the point of this test is not the registration, etc).
|
||||
import xpcom.server, xpcom.client
|
||||
ob = xpcom.server.WrapObject( koTestSimpleStream1(), _xpcom.IID_nsISupports)
|
||||
ob = xpcom.client.Component(ob, components.interfaces.nsIInputStream)
|
||||
ob = xpcom.server.WrapObject( koTestSimpleStream(), _xpcom.IID_nsISupports)
|
||||
ob = xpcom.client.Component(ob._comobj_, components.interfaces.nsIInputStream)
|
||||
return ob
|
||||
|
||||
def get_test_input_2():
|
||||
# We use a couple of internal hacks here that mean we can avoid having the object
|
||||
# registered. This code means that we are still working over the xpcom boundaries, tho
|
||||
# (and the point of this test is not the registration, etc).
|
||||
import xpcom.server, xpcom.client
|
||||
ob = xpcom.server.WrapObject( koTestSimpleStream2(), _xpcom.IID_nsISupports)
|
||||
ob = xpcom.client.Component(ob, components.interfaces.nsIInputStream)
|
||||
return ob
|
||||
class StreamTests(unittest.TestCase):
|
||||
def testInput(self):
|
||||
self.do_test_input( get_test_input() )
|
||||
|
||||
def test_input(myStream):
|
||||
if myStream.read(5) != test_data[:5]:
|
||||
raise "Read the wrong data!"
|
||||
if myStream.read(0) != '':
|
||||
raise "Read the wrong emtpy data!"
|
||||
if myStream.read(5) != test_data[5:10]:
|
||||
raise "Read the wrong data after an empty read!"
|
||||
if myStream.read(-1) != test_data[10:]:
|
||||
raise "Couldnt read the rest of the data"
|
||||
if myStream.nonBlocking:
|
||||
raise "Expected default to be blocking"
|
||||
try:
|
||||
myStream.observer = None
|
||||
raise "Shouldnt get here!"
|
||||
except COMException, details:
|
||||
if details.errno != nsError.NS_ERROR_NOT_IMPLEMENTED:
|
||||
raise "Unexpected COM exception: %s (%r)" % (details, details)
|
||||
def do_test_input(self, myStream):
|
||||
self.failUnlessEqual(str(myStream.read(5)), test_data[:5])
|
||||
self.failUnlessEqual(str(myStream.read(0)), '')
|
||||
self.failUnlessEqual(str(myStream.read(5)), test_data[5:10])
|
||||
self.failUnlessEqual(str(myStream.read(-1)), test_data[10:])
|
||||
self.failIf(myStream.isNonBlocking(), "Expected default to be blocking")
|
||||
# stream observer mechanism has changed - we should test that.
|
||||
|
||||
if __name__=='__main__':
|
||||
test_input( get_test_input_1() )
|
||||
test_input( get_test_input_2() )
|
||||
print "The stream tests worked!"
|
||||
|
||||
unittest.main()
|
||||
|
||||
@@ -180,7 +180,7 @@ def test_base_interface(c):
|
||||
|
||||
test_attribute(c, "long_value", 5, 7)
|
||||
test_attribute(c, "long_value", 5, 0)
|
||||
test_attribute(c, "long_value", 5, 0xFFFFFFFF, -1) # 32 bit signed.
|
||||
test_attribute(c, "long_value", 5, -1, -1) # 32 bit signed.
|
||||
test_attribute(c, "long_value", 5, -1) # 32 bit signed.
|
||||
test_attribute(c, "long_value", 5, 0L)
|
||||
test_attribute(c, "long_value", 5, 1L)
|
||||
@@ -190,7 +190,7 @@ def test_base_interface(c):
|
||||
|
||||
test_attribute(c, "ulong_value", 6, 7)
|
||||
test_attribute(c, "ulong_value", 6, 0)
|
||||
test_attribute(c, "ulong_value", 6, 0xFFFFFFFF) # 32 bit signed.
|
||||
test_attribute(c, "ulong_value", 6, -1) # 32 bit signed.
|
||||
test_attribute_failure(c, "ulong_value", "boo", ValueError)
|
||||
|
||||
test_attribute(c, "long_long_value", 7, 8)
|
||||
@@ -305,15 +305,15 @@ def test_base_interface(c):
|
||||
test_constant(c, "Two", 2)
|
||||
test_constant(c, "MinusOne", -1)
|
||||
test_constant(c, "BigLong", 0x7FFFFFFF)
|
||||
test_constant(c, "BiggerLong", 0xFFFFFFFF)
|
||||
test_constant(c, "BigULong", 0xFFFFFFFF)
|
||||
test_constant(c, "BiggerLong", -1)
|
||||
test_constant(c, "BigULong", -1)
|
||||
# Test the components.Interfaces semantics
|
||||
i = xpcom.components.interfaces.nsIPythonTestInterface
|
||||
test_constant(i, "One", 1)
|
||||
test_constant(i, "Two", 2)
|
||||
test_constant(i, "MinusOne", -1)
|
||||
test_constant(i, "BigLong", 0x7FFFFFFF)
|
||||
test_constant(i, "BigULong", 0xFFFFFFFF)
|
||||
test_constant(i, "BigULong", -1)
|
||||
|
||||
def test_derived_interface(c, test_flat = 0):
|
||||
val = "Hello\0there"
|
||||
|
||||
Reference in New Issue
Block a user