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:
mhammond%skippinet.com.au
2005-08-25 21:52:19 +00:00
parent 96d6a8d0f7
commit 1cf8051395
21 changed files with 554 additions and 347 deletions

View File

@@ -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

View File

@@ -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!!!

View File

@@ -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)

View File

@@ -68,6 +68,7 @@ CPPSRCS= \
PyGWeakReference.cpp \
PyIClassInfo.cpp \
PyIComponentManager.cpp \
PyIComponentManagerObsolete.cpp \
PyIInputStream.cpp \
PyIEnumerator.cpp \
PyIID.cpp \

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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, &notyet, &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, &notyet, &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}
};

View File

@@ -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, &notyet, &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}
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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__

View File

@@ -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"

View File

@@ -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;

View File

@@ -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: {

View File

@@ -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.

View File

@@ -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);

View File

@@ -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)

View File

@@ -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()

View File

@@ -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))

View File

@@ -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()

View File

@@ -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"