From e80bdbafeba9af9b58aac81b999f4b299c9eecd6 Mon Sep 17 00:00:00 2001 From: Jörg Budischewski Date: Sun, 23 Mar 2003 11:12:59 +0000 Subject: initial checkin for the pyuno-0.9.2 release --- pyuno/source/loader/makefile.mk | 128 +++++ pyuno/source/loader/pythonloader.py | 129 +++++ pyuno/source/loader/pyuno_loader.cxx | 210 ++++++++ pyuno/source/module/makefile.mk | 143 ++++++ pyuno/source/module/pyuno | 4 + pyuno/source/module/pyuno.cxx | 681 +++++++++++++++++++++++++ pyuno/source/module/pyuno.flt | 10 + pyuno/source/module/pyuno_adapter.cxx | 406 +++++++++++++++ pyuno/source/module/pyuno_callable.cxx | 235 +++++++++ pyuno/source/module/pyuno_dlopenwrapper.c | 72 +++ pyuno/source/module/pyuno_except.cxx | 265 ++++++++++ pyuno/source/module/pyuno_gc.cxx | 118 +++++ pyuno/source/module/pyuno_impl.hxx | 294 +++++++++++ pyuno/source/module/pyuno_module.cxx | 631 +++++++++++++++++++++++ pyuno/source/module/pyuno_runtime.cxx | 819 ++++++++++++++++++++++++++++++ pyuno/source/module/pyuno_type.cxx | 460 +++++++++++++++++ pyuno/source/module/pyuno_util.cxx | 156 ++++++ pyuno/source/module/uno.py | 326 ++++++++++++ pyuno/source/module/unohelper.py | 214 ++++++++ 19 files changed, 5301 insertions(+) create mode 100644 pyuno/source/loader/makefile.mk create mode 100644 pyuno/source/loader/pythonloader.py create mode 100644 pyuno/source/loader/pyuno_loader.cxx create mode 100644 pyuno/source/module/makefile.mk create mode 100644 pyuno/source/module/pyuno create mode 100644 pyuno/source/module/pyuno.cxx create mode 100755 pyuno/source/module/pyuno.flt create mode 100644 pyuno/source/module/pyuno_adapter.cxx create mode 100644 pyuno/source/module/pyuno_callable.cxx create mode 100644 pyuno/source/module/pyuno_dlopenwrapper.c create mode 100644 pyuno/source/module/pyuno_except.cxx create mode 100644 pyuno/source/module/pyuno_gc.cxx create mode 100644 pyuno/source/module/pyuno_impl.hxx create mode 100644 pyuno/source/module/pyuno_module.cxx create mode 100644 pyuno/source/module/pyuno_runtime.cxx create mode 100644 pyuno/source/module/pyuno_type.cxx create mode 100644 pyuno/source/module/pyuno_util.cxx create mode 100644 pyuno/source/module/uno.py create mode 100644 pyuno/source/module/unohelper.py (limited to 'pyuno/source') diff --git a/pyuno/source/loader/makefile.mk b/pyuno/source/loader/makefile.mk new file mode 100644 index 000000000000..12ac257b68c6 --- /dev/null +++ b/pyuno/source/loader/makefile.mk @@ -0,0 +1,128 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2003-03-23 12:12:53 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source 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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Ralph Thomas +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Ralph Thomas, Joerg Budischewski +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=pyuno +TARGET=pycpld +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : pyversion.mk +#------------------------------------------------------------------- + +CFLAGS+=-I$(SOLARINCDIR)$/python + +.IF "$(GUI)" == "UNX" +PYUNOLIB=-lpyuno +PYTHONLIB=-lpython +.ELSE +PYUNOLIB=ipyuno.lib +PYTHONLIB=python$(PYMAJOR)$(PYMINOR).lib +.ENDIF + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(PYUNOLIB) \ + $(PYTHONLIB) + +SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +SLOFILES= $(SLO)$/pyuno_loader.obj + +COMPONENTS= \ + tcv \ + inv \ + corefl \ + insp \ + invadp \ + proxyfac \ + pycpld \ + +# --- Targets ------------------------------------------------------ + +ALL : ALLTAR \ + $(DLLDEST)$/pythonloader.py \ + $(DLLDEST)$/pyuno_services.rdb + +.INCLUDE : target.mk + +$(DLLDEST)$/%.py: %.py + +cp $? $@ + +$(DLLDEST)$/pyuno_services.rdb : makefile.mk + -rm -f $@ $(DLLDEST)$/pyuno_services.tmp $(DLLDEST)$/pyuno_services.rdb + +cd $(DLLDEST) && regcomp -register -r pyuno_services.tmp $(foreach,i,$(COMPONENTS) -c $(i)) +# just needed until OO644 +# regmerge $(MY_SHLOUT)$/pyuno_regcomp.rdb / $(MY_SHLOUT)$/pyuno_services.tmp $(SOLARBINDIR)$/udkapi.rdb +# +cd $(MY_SHLOUT) && \ +# regcomp -register -br pyuno_regcomp.rdb -r pyuno_services.tmp \ +# -l com.sun.star.loader.Python $(foreach,i,$(PYCOMPONENTS) -c $(i)) + +cd $(DLLDEST) && mv pyuno_services.tmp pyuno_services.rdb diff --git a/pyuno/source/loader/pythonloader.py b/pyuno/source/loader/pythonloader.py new file mode 100644 index 000000000000..e2c526284fed --- /dev/null +++ b/pyuno/source/loader/pythonloader.py @@ -0,0 +1,129 @@ +#************************************************************************* +# +# $RCSfile: pythonloader.py,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2003-03-23 12:12:53 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source 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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Ralph Thomas +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Ralph Thomas, Joerg Budischewski +# +#************************************************************************* +import uno +import unohelper +from com.sun.star.uno import Exception,RuntimeException +from com.sun.star.loader import XImplementationLoader +from com.sun.star.lang import XServiceInfo + +MODULE_PROTOCOL = "vnd.openoffice.pymodule:" +DEBUG = 0 + +g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! +g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! + +class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): + def __init__(self, ctx ): + if DEBUG: + print "pythonloader.Loader ctor" + self.ctx = ctx + + def extractModuleFromUrl( self, url ): + if url.startswith( MODULE_PROTOCOL ): + return url[len(MODULE_PROTOCOL):len(url)] + else: + nColon = url.find( ":" ) + if -1 == nColon: + raise RuntimeException( "PythonLoader: No protocol in url " + url ) + else: + raise RuntimeException( "PythonLoader: Unknown protocol "+url[0:nColon] + + " in " + url ) + + def activate( self, implementationName, dummy, locationUrl, regKey ): + if DEBUG: + print "pythonloader.Loader.activate" + moduleName = self.extractModuleFromUrl( locationUrl ) + if DEBUG: + print "extracting modulname " + moduleName + " from url " + locationUrl + + try: + mod = __import__( moduleName ) + implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + if implHelper == None: + return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) + else: + return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) + except ImportError,e: + raise RuntimeException( "Couldn't import module " + moduleName + " for reason ("+str(e)+")", None) + + def writeRegistryInfo( self, regKey, dummy, locationUrl ): + if DEBUG: + print "pythonloader.Loader.writeRegistryInfo" + moduleName = self.extractModuleFromUrl( locationUrl ) + try: + mod = __import__( moduleName ) + implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + if implHelper == None: + return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) + else: + return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) + except ImportError,e: + raise RuntimeException( "Couldn't import module " + moduleName + " for reason ("+str(e)+")", None) + + def getImplementationName( self ): + return g_implementationName + + def supportsService( self, ServiceName ): + return ServiceName in self.serviceNames + + def getSupportedServiceNames( self ): + return g_supportedServices + + diff --git a/pyuno/source/loader/pyuno_loader.cxx b/pyuno/source/loader/pyuno_loader.cxx new file mode 100644 index 000000000000..91f6d7dfedb9 --- /dev/null +++ b/pyuno/source/loader/pyuno_loader.cxx @@ -0,0 +1,210 @@ +/************************************************************************* + * + * $RCSfile: pyuno_loader.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:54 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include + +#include +#include + +#include + +using rtl::OUString; +using rtl::OUStringBuffer; + +using pyuno::PyRef; +using pyuno::Runtime; +using pyuno::PyThreadAttach; + +using com::sun::star::registry::XRegistryKey; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::XComponentContext; +using com::sun::star::uno::RuntimeException; + +namespace pyuno_loader +{ + +static void raiseRuntimeExceptionWhenNeeded() throw ( RuntimeException ) +{ + if( PyErr_Occurred() ) + { + PyRef excType, excValue, excTraceback; + PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback); + if( excType.is() ) + { + PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE ); + OUStringBuffer buf; + buf.appendAscii( "python-loader:" ); + PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE ); + buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" ); + buf.appendAscii( PyString_AsString( str.get() ) ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () ); + } + } +} + +static PyRef getLoaderModule() throw( RuntimeException ) +{ + PyRef module( PyImport_ImportModule( "pythonloader" ), SAL_NO_ACQUIRE ); + raiseRuntimeExceptionWhenNeeded(); + if( !module.is() ) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pythonloader: Couldn't load pythonloader module" ) ), + Reference< XInterface > () ); + } + return PyRef( PyModule_GetDict( module.get() )); +} + +static PyRef getObjectFromLoaderModule( const char * func ) + throw ( RuntimeException ) +{ + PyRef object( PyDict_GetItemString(getLoaderModule().get(), (char*)func ) ); + if( !object.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "pythonloader: couldn't find core element pythonloader." ); + buf.appendAscii( func ); + throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >()); + } + return object; +} + +OUString getImplementationName() +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.pyuno.Loader" ) ); +} + +Sequence< OUString > getSupportedServiceNames() +{ + OUString serviceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Python" ) ); + return Sequence< OUString > ( &serviceName, 1 ); +} + +Reference< XInterface > CreateInstance( const Reference< XComponentContext > & ctx ) +{ + Reference< XInterface > ret; + + if( ! Py_IsInitialized() ) + { + Py_Initialize(); + PyEval_InitThreads(); + PyThreadState *tstate = PyThreadState_Get(); + PyEval_ReleaseThread( tstate ); + } + + PyThreadAttach attach( PyInterpreterState_Head() ); + { + if( ! Runtime::isInitialized() ) + { + Runtime::initialize( ctx ); + } + Runtime runtime; + + PyRef pyCtx = runtime.any2PyObject( + com::sun::star::uno::makeAny( ctx ) ); + + PyRef clazz = getObjectFromLoaderModule( "Loader" ); + PyRef args ( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); + PyTuple_SetItem( args.get(), 0 , pyCtx.getAcquired() ); + PyRef pyInstance( PyObject_CallObject( clazz.get() , args.get() ), SAL_NO_ACQUIRE ); + runtime.pyObject2Any( pyInstance ) >>= ret; + } + return ret; +} + +} + + +static struct cppu::ImplementationEntry g_entries[] = +{ + { + pyuno_loader::CreateInstance, pyuno_loader::getImplementationName, + pyuno_loader::getSupportedServiceNames, cppu::createSingleComponentFactory, + 0 , 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + +extern "C" +{ + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries ); +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + return cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries ); +} + +} + diff --git a/pyuno/source/module/makefile.mk b/pyuno/source/module/makefile.mk new file mode 100644 index 000000000000..36371412b441 --- /dev/null +++ b/pyuno/source/module/makefile.mk @@ -0,0 +1,143 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2003-03-23 12:12:54 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source 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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Ralph Thomas, Joerg Budischewski +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=pyuno +TARGET=pyuno +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : pyversion.mk +#------------------------------------------------------------------- + +CFLAGS+=-I$(SOLARINCDIR)$/python + +.IF "$(GUI)" == "UNX" +# python expects modules without the lib prefix +PYUNO_MODULE=$(DLLDEST)$/pyuno$(DLLPOST) +# python executable brings in the needed python core symbols, +# so this library cannot be checked +SHL1NOCHECK=yes +PYUNORC=pyunorc +.ELSE +# on windows, the python executable also uses the shared library, +# so we link pyuno directly to it +PYTHONLIB=python$(PYMAJOR)$(PYMINOR).lib +PYUNORC=pyuno.ini +.ENDIF + + +SHL1TARGET=$(TARGET) +SLOFILES= \ + $(SLO)$/pyuno_runtime.obj \ + $(SLO)$/pyuno.obj \ + $(SLO)$/pyuno_callable.obj \ + $(SLO)$/pyuno_module.obj \ + $(SLO)$/pyuno_type.obj \ + $(SLO)$/pyuno_util.obj \ + $(SLO)$/pyuno_except.obj \ + $(SLO)$/pyuno_adapter.obj \ + $(SLO)$/pyuno_gc.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(PYTHONLIB) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib +SHL1IMPLIB=i$(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1DEPN= $(MISC)$/pyuno.flt + +DEFLIB1NAME=$(TARGET) + +# --- Targets ------------------------------------------------------ + +ALL : ALLTAR \ + $(DLLDEST)$/uno.py \ + $(DLLDEST)$/unohelper.py \ + $(PYUNO_MODULE) \ + $(MISC)$/$(PYUNORC) + +.INCLUDE : target.mk + +$(DLLDEST)$/%.py: %.py + +cp $? $@ + + +.IF "$(GUI)" == "UNX" +$(PYUNO_MODULE) : $(SLO)$/pyuno_dlopenwrapper.obj + ld -shared -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o +.ENDIF + +$(MISC)$/$(PYUNORC) : pyuno + -rm -f $@ + cat pyuno > $@ + +$(MISC)$/pyuno.flt : pyuno.flt + -rm -f $@ + cat $? > $@ diff --git a/pyuno/source/module/pyuno b/pyuno/source/module/pyuno new file mode 100644 index 000000000000..1cd17390d57b --- /dev/null +++ b/pyuno/source/module/pyuno @@ -0,0 +1,4 @@ +# The bootstrap variable PYUNOLIBDIR will be set by the pyuno runtime library +PYUNO_BINPATH=$PYUNOLIBDIR/../bin$UPDMINOREXT +UNO_TYPES=$PYUNO_BINPATH/applicat.rdb +UNO_SERVICES=$PYUNO_BINPATH/pyuno_services.rdb diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx new file mode 100644 index 000000000000..df19b8e36f71 --- /dev/null +++ b/pyuno/source/module/pyuno.cxx @@ -0,0 +1,681 @@ +/************************************************************************* + * + * $RCSfile: pyuno.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ + +#include "pyuno_impl.hxx" + +#include +#include + +#include + +#include +#include +#include +#include + +#define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr() + +using rtl::OStringBuffer; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; +using rtl::OUString; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Type; +using com::sun::star::uno::TypeClass; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Exception; +using com::sun::star::uno::XComponentContext; +using com::sun::star::lang::XSingleServiceFactory; +using com::sun::star::lang::XServiceInfo; +using com::sun::star::lang::XTypeProvider; +using com::sun::star::script::XTypeConverter; +using com::sun::star::script::XInvocation2; +using com::sun::star::beans::XMaterialHolder; + +namespace pyuno +{ + +PyObject *PyUNO_str( PyObject * self ); + +void PyUNO_del (PyObject* self) +{ + PyUNO* me = reinterpret_cast< PyUNO* > (self); + delete me->members; + PyMem_DEL (self); +} + + + +static OUString val2str( void * pVal, typelib_TypeDescriptionReference * pTypeRef ) SAL_THROW( () ) +{ + OSL_ASSERT( pVal ); + if (pTypeRef->eTypeClass == typelib_TypeClass_VOID) + return OUString( RTL_CONSTASCII_USTRINGPARAM("void") ); + + OUStringBuffer buf( 64 ); + buf.append( (sal_Unicode)'(' ); + buf.append( pTypeRef->pTypeName ); + buf.append( (sal_Unicode)')' ); + + switch (pTypeRef->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( (sal_Int64)*(void **)pVal, 16 ); + buf.appendAscii( "{" ); Reference< XInterface > r = *( Reference< XInterface > * ) pVal; + Reference< XServiceInfo > serviceInfo( r, UNO_QUERY); + Reference< XTypeProvider > typeProvider(r,UNO_QUERY); + if( serviceInfo.is() ) + { + buf.appendAscii("implementationName=" ); + buf.append(serviceInfo->getImplementationName() ); + buf.appendAscii(", supportedServices={" ); + Sequence< OUString > seq = serviceInfo->getSupportedServiceNames(); + for( int i = 0 ; i < seq.getLength() ; i ++ ) + { + buf.append( seq[i] ); + if( i +1 != seq.getLength() ) + buf.appendAscii( "," ); + } + buf.appendAscii("}"); + } + + if( typeProvider.is() ) + { + buf.appendAscii(", supportedInterfaces={" ); + Sequence< Type > seq (typeProvider->getTypes()); + for( int i = 0 ; i < seq.getLength() ; i ++ ) + { + buf.append(seq[i].getTypeName()); + if( i +1 != seq.getLength() ) + buf.appendAscii( "," ); + } + buf.appendAscii("}"); + } + buf.appendAscii( "}" ); + + break; + } + case typelib_TypeClass_UNION: + { +// typelib_TypeDescription * pTypeDescr = 0; +// TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); +// buf.append( val2str( (char *)pVal + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, +// union_getSetType( pVal, pTypeDescr ) ) ); +// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); +// TYPELIB_DANGER_RELEASE( pTypeDescr ); + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); + OSL_ASSERT( pTypeDescr ); + + typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr; + sal_Int32 nDescr = pCompType->nMembers; + + if (pCompType->pBaseTypeDescription) + { + buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef ) ); + if (nDescr) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + + typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs; + sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets; + rtl_uString ** ppMemberNames = pCompType->ppMemberNames; + + for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) + { + buf.append( ppMemberNames[nPos] ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") ); + typelib_TypeDescription * pMemberType = 0; + TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] ); + buf.append( val2str( (char *)pVal + pMemberOffsets[nPos], pMemberType->pWeakRef ) ); + TYPELIB_DANGER_RELEASE( pMemberType ); + if (nPos < (nDescr -1)) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + break; + } + case typelib_TypeClass_SEQUENCE: + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); + + uno_Sequence * pSequence = *(uno_Sequence **)pVal; + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + + sal_Int32 nElementSize = pElementTypeDescr->nSize; + sal_Int32 nElements = pSequence->nElements; + + if (nElements) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + char * pElements = pSequence->elements; + for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) + { + buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef ) ); + if (nPos < (nElements -1)) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") ); + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + break; + } + case typelib_TypeClass_ANY: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + buf.append( val2str( ((uno_Any *)pVal)->pData, + ((uno_Any *)pVal)->pType ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + break; + case typelib_TypeClass_TYPE: + buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName ); + break; + case typelib_TypeClass_STRING: + buf.append( (sal_Unicode)'\"' ); + buf.append( *(rtl_uString **)pVal ); + buf.append( (sal_Unicode)'\"' ); + break; + case typelib_TypeClass_ENUM: + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); + + sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues; + sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues; + while (nPos--) + { + if (pValues[nPos] == *(int *)pVal) + break; + } + if (nPos >= 0) + buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[nPos] ); + else + buf.append( (sal_Unicode)'?' ); + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + break; + } + case typelib_TypeClass_BOOLEAN: + if (*(sal_Bool *)pVal) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") ); + else + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") ); + break; + case typelib_TypeClass_CHAR: + buf.append( (sal_Unicode)'\'' ); + buf.append( *(sal_Unicode *)pVal ); + buf.append( (sal_Unicode)'\'' ); + break; + case typelib_TypeClass_FLOAT: + buf.append( *(float *)pVal ); + break; + case typelib_TypeClass_DOUBLE: + buf.append( *(double *)pVal ); + break; + case typelib_TypeClass_BYTE: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 ); + break; + case typelib_TypeClass_SHORT: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 ); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 ); + break; + case typelib_TypeClass_LONG: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( *(sal_Int32 *)pVal, 16 ); + break; + case typelib_TypeClass_UNSIGNED_LONG: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); + buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 ); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") ); +#if defined(GCC) && defined(SPARC) + { + sal_Int64 aVal; + *(sal_Int32 *)&aVal = *(sal_Int32 *)pVal; + *((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1); + buf.append( aVal, 16 ); + } +#else + buf.append( *(sal_Int64 *)pVal, 16 ); +#endif + break; + + case typelib_TypeClass_VOID: + case typelib_TypeClass_ARRAY: + case typelib_TypeClass_UNKNOWN: + case typelib_TypeClass_SERVICE: + case typelib_TypeClass_MODULE: + default: + buf.append( (sal_Unicode)'?' ); + } + + return buf.makeStringAndClear(); +} + + +PyObject *PyUNO_repr( PyObject * self ) +{ + PyUNO *me = (PyUNO * ) self; + PyObject * ret = 0; + + if( me->members->wrappedObject.getValueType().getTypeClass() == typelib_TypeClass_EXCEPTION ) + { + Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY); + if( rHolder.is() ) + { + Any a = rHolder->getMaterial(); + Exception e; + a >>= e; + ret = ustring2PyUnicode(e.Message ).getAcquired(); + } + } + else + { + ret = PyUNO_str( self ); + } + return ret; +} + +PyObject *PyUNO_str( PyObject * self ) +{ + PyUNO *me = ( PyUNO * ) self; + + OStringBuffer buf; + + + if( me->members->wrappedObject.getValueType().getTypeClass() == typelib_TypeClass_STRUCT || + me->members->wrappedObject.getValueType().getTypeClass() == typelib_TypeClass_EXCEPTION) + { + Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY); + if( rHolder.is() ) + { + Any a = rHolder->getMaterial(); + OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() ); + buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) ); + } + } + else + { + // a common UNO object + + buf.append( "pyuno object " ); + + OUString s = val2str( (void*)me->members->wrappedObject.getValue(), + me->members->wrappedObject.getValueType().getTypeLibType() ); + buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) ); + } + + return PyString_FromString( buf.getStr()); +} + +static OUString constPrint( RTL_CONSTASCII_USTRINGPARAM( "print" ) ); +PyObject* PyUNO_getattr (PyObject* self, char* name) +{ + PyUNO* me; + + try + { + + Runtime runtime; + + me = (PyUNO*) self; + //Handle Python dir () stuff first... + if (strcmp (name, "__members__") == 0) + { + PyObject* member_list; + Sequence oo_member_list; + + oo_member_list = me->members->xInvocation->getMemberNames (); + member_list = PyList_New (oo_member_list.getLength ()); + for (int i = 0; i < oo_member_list.getLength (); i++) + { + Any a; + //Nobody has a bad thing to say about python, eh? + //This hack makes anything called "print" become "_print" + //because python won't let you get any attribute called "print". + + if (oo_member_list [i] == constPrint) + { + a <<= OUString::createFromAscii ("_print"); + } + else + { + a <<= oo_member_list [i]; + } + + PyList_SetItem (member_list, i, runtime.any2PyObject (a).get()); + } + return member_list; + } + + if (strcmp (name, "__dict__") == 0) + { + Py_INCREF (Py_None); + return Py_None; + } + if (strcmp (name, "__methods__") == 0) + { + Py_INCREF (Py_None); + return Py_None; + } + if (strcmp (name, "__class__") == 0) + { + if( me->members->wrappedObject.getValueTypeClass() == + com::sun::star::uno::TypeClass_STRUCT || + me->members->wrappedObject.getValueTypeClass() == + com::sun::star::uno::TypeClass_EXCEPTION ) + { + return getClass( + me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired(); + } + Py_INCREF (Py_None); + return Py_None; + } + + OUString attrName( OUString::createFromAscii( name ) ); + //We need to find out if it's a method... + if (me->members->xInvocation->hasMethod (attrName)) + { + //Create a callable object to invoke this... + PyRef ret = PyUNO_callable_new ( + me->members->xInvocation, + attrName, + runtime.getImpl()->cargo->xInvocation, + runtime.getImpl()->cargo->xTypeConverter); + Py_XINCREF( ret.get() ); + return ret.get(); + + } + //Hack to fix python's "print" member handling...! + if (strcmp (name, "_print") == 0 && me->members->xInvocation->hasMethod (constPrint)) + { + PyRef ret = PyUNO_callable_new ( + me->members->xInvocation, + constPrint, + runtime.getImpl()->cargo->xInvocation, + runtime.getImpl()->cargo->xTypeConverter); + Py_XDECREF( ret.get() ); + return ret.get(); + } + //or a property + if (me->members->xInvocation->hasProperty ( attrName)) + { + //Return the value of the property + PyRef ret = runtime.any2PyObject ( me->members->xInvocation->getValue (attrName) ); + Py_XINCREF( ret.get() ); + return ret.get(); + } + if (strcmp (name, "_print") == 0 && me->members->xInvocation->hasProperty (constPrint)) + { + PyRef ret = runtime.any2PyObject ( me->members->xInvocation->getValue(constPrint)); + Py_XINCREF( ret.get() ); + return ret.get(); + } + //or else... + PyErr_SetString (PyExc_AttributeError, name); + } + catch( com::sun::star::reflection::InvocationTargetException & e ) + { + raisePyExceptionWithAny( makeAny(e.TargetException) ); + } + catch( com::sun::star::beans::UnknownPropertyException & e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + catch( com::sun::star::lang::IllegalArgumentException &e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + catch( com::sun::star::script::CannotConvertException &e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + catch( RuntimeException &e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + + return NULL; +} + +int PyUNO_setattr (PyObject* self, char* name, PyObject* value) +{ + PyUNO* me; + + me = (PyUNO*) self; + try + { + Runtime runtime; + Any val= runtime.pyObject2Any(value); + + OUString attrName( OUString::createFromAscii( name ) ); + { + PyThreadDetach antiguard; + if (me->members->xInvocation->hasProperty (attrName)) + { + me->members->xInvocation->setValue (attrName, val); + return 0; //Keep with Python's boolean system + } + } + } + catch( com::sun::star::reflection::InvocationTargetException & e ) + { + raisePyExceptionWithAny( makeAny(e.TargetException) ); + return 1; + } + catch( com::sun::star::beans::UnknownPropertyException & e ) + { + raisePyExceptionWithAny( makeAny(e) ); + return 1; + } + catch( com::sun::star::script::CannotConvertException &e ) + { + raisePyExceptionWithAny( makeAny(e) ); + return 1; + } + catch( RuntimeException & e ) + { + raisePyExceptionWithAny( makeAny( e ) ); + return 1; + } + PyErr_SetString (PyExc_AttributeError, name); + return 1; //as above. +} + +// ensure object identity and struct equality +static int PyUNO_cmp( PyObject *self, PyObject *that ) +{ + if( self == that ) + return 0; + int retDefault = self > that ? 1 : -1; + try + { + Runtime runtime; + if( PyObject_IsInstance( that, getPyUnoClass( runtime ).get() ) ) + { + + PyUNO *me = reinterpret_cast< PyUNO*> ( self ); + PyUNO *other = reinterpret_cast< PyUNO *> (that ); + com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass(); + com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass(); + + if( tcMe == tcOther ) + { + if( tcMe == com::sun::star::uno::TypeClass_STRUCT || + tcMe == com::sun::star::uno::TypeClass_EXCEPTION ) + { + Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY); + Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY ); + if( xMe->getMaterial() == xOther->getMaterial() ) + return 0; + } + else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE ) + { + if( me->members->xInvocation == other->members->xInvocation ) + return 0; + } + } + } + } + catch( com::sun::star::uno::RuntimeException & e) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + return retDefault; +} + +static PyTypeObject PyUNOType = +{ + PyObject_HEAD_INIT (&PyType_Type) + 0, + "pyuno", + sizeof (PyUNO), + 0, + (destructor) PyUNO_del, + (printfunc) 0, + (getattrfunc) PyUNO_getattr, + (setattrfunc) PyUNO_setattr, + (cmpfunc) PyUNO_cmp, + (reprfunc) PyUNO_repr, + 0, + 0, + 0, + (hashfunc) 0, + (ternaryfunc) 0, + (reprfunc) PyUNO_str, +}; + +PyRef getPyUnoClass( const Runtime &) +{ + return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) ); +} + +PyObject* PyUNO_new ( + const Any & targetInterface, const Reference &ssf) +{ + Reference tmp_interface; + + targetInterface >>= tmp_interface; + if (!tmp_interface.is ()) + { + // empty reference ! + return Py_None; + } + + return PyUNO_new_UNCHECKED (targetInterface, ssf); +} + + +PyObject* PyUNO_new_UNCHECKED ( + const Any &targetInterface, + const Reference &ssf ) +{ + PyUNO* self; + Sequence arguments (1); + Reference tmp_interface; + + self = PyObject_NEW (PyUNO, &PyUNOType); + if (self == NULL) + return NULL; //NULL == error + self->members = new PyUNOInternals (); + + arguments[0] <<= targetInterface; + { + PyThreadDetach antiguard; + tmp_interface = ssf->createInstanceWithArguments (arguments); + Reference tmp_invocation (tmp_interface, UNO_QUERY); + self->members->xInvocation = tmp_invocation; + self->members->wrappedObject = targetInterface; + } + return (PyObject*) self; +} + +} diff --git a/pyuno/source/module/pyuno.flt b/pyuno/source/module/pyuno.flt new file mode 100755 index 000000000000..921433f66ca0 --- /dev/null +++ b/pyuno/source/module/pyuno.flt @@ -0,0 +1,10 @@ +??_R0?AVException@uno@star@sun@com@@@8??0Exception@uno@star@sun@com@@QAE@ABV01234@@Z8 +??_R0?AVIllegalArgumentException@lang@star@sun@com@@@8??0IllegalArgumentException@lang@star@sun@com@@QAE@ABV01234@@Z12 +??_R0?AVInvocationTargetException@reflection@star@sun@com@@@8??0InvocationTargetException@reflection@star@sun@com@@QAE@ABV01234@@Z20 +??_R0?AVRuntimeException@uno@star@sun@com@@@8??0RuntimeException@uno@star@sun@com@@QAE@ABV01234@@Z8 +??_R0?AVUnknownPropertyException@beans@star@sun@com@@@8??0UnknownPropertyException@beans@star@sun@com@@QAE@ABV01234@@Z8 +??_R0?AVWrappedTargetException@lang@star@sun@com@@@8??0WrappedTargetException@lang@star@sun@com@@QAE@ABV01234@@Z20 +?AVIllegalArgumentException@lang@star@sun@com@@ +?AVRuntimeException@uno@star@sun@com@@ +?AVUnknownPropertyException@beans@star@sun@com@@ +?AVInvocationTargetException@reflection@star@sun@com@@ diff --git a/pyuno/source/module/pyuno_adapter.cxx b/pyuno/source/module/pyuno_adapter.cxx new file mode 100644 index 000000000000..3176b3caa60b --- /dev/null +++ b/pyuno/source/module/pyuno_adapter.cxx @@ -0,0 +1,406 @@ +/************************************************************************* + * + * $RCSfile: pyuno_adapter.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:56 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include "pyuno_impl.hxx" + +#include +#include + +#include + +#include + +using rtl::OUStringToOString; +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OString; +using rtl::OStringBuffer; + +using com::sun::star::beans::XIntrospectionAccess; +using com::sun::star::beans::XIntrospection; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::XInterface; +using com::sun::star::lang::XUnoTunnel; +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::beans::UnknownPropertyException; +using com::sun::star::script::CannotConvertException; +using com::sun::star::reflection::InvocationTargetException; +using com::sun::star::reflection::XIdlMethod; +using com::sun::star::reflection::ParamInfo; +using com::sun::star::reflection::XIdlClass; + +#define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr() + +namespace pyuno +{ + +Adapter::Adapter( const PyRef & ref, const Runtime & runtime): + mWrappedObject( ref ), mInterpreter( (PyThreadState_Get()->interp) ) +{} + +Adapter::~Adapter() +{ + // Problem: We don't know, if we have the python interpreter lock + // There is no runtime function to get to know this. + decreaseRefCount( mInterpreter, mWrappedObject.get() ); + mWrappedObject.scratch(); +} + +static cppu::OImplementationId g_id( sal_False ); + +Sequence Adapter::getUnoTunnelImplementationId() +{ + return g_id.getImplementationId(); +} + +sal_Int64 Adapter::getSomething( const Sequence< sal_Int8 > &id) throw (RuntimeException) +{ + if( id == g_id.getImplementationId() ) + return (sal_Int64)this; + return 0; +} + +void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime ) + throw ( InvocationTargetException ) +{ + if( PyErr_Occurred() ) + { + PyRef excType, excValue, excTraceback; + PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback); + Any unoExc = runtime.pyObject2Any( excValue ); + PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE ); + if( unoExc.getValueTypeClass() != com::sun::star::uno::TypeClass_EXCEPTION ) + { + OUStringBuffer buf; + buf.appendAscii( "python object raised an unknown exception (" ); + PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE ); + buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" ); + buf.appendAscii( PyString_AsString( str.get() ) ); + RuntimeException e; + e.Message = buf.makeStringAndClear(); + unoExc = makeAny( e ); + } + com::sun::star::uno::Exception e; + unoExc >>= e; + + OUStringBuffer buf; + buf.append( ((com::sun::star::uno::Exception*)unoExc.getValue())->Message ); + buf.appendAscii( "pyuno-bridge:" ); + buf.append( e.Message ); + buf.appendAscii( "," ); + buf.appendAscii( PyString_AsString( str.get() ) ); + + OUString msg = buf.makeStringAndClear(); + ((com::sun::star::uno::Exception*)unoExc.getValue())->Message = msg; + throw InvocationTargetException(msg, Reference(), unoExc ); + } +} + +Reference< XIntrospectionAccess > Adapter::getIntrospection() + throw ( RuntimeException ) +{ + // not supported + return Reference< XIntrospectionAccess > (); +} + +Any Adapter::invoke( const OUString &aFunctionName, + const Sequence< Any >& aParams, + Sequence< sal_Int16 > &aOutParamIndex, + Sequence< Any > &aOutParam) + throw (IllegalArgumentException,CannotConvertException,InvocationTargetException,RuntimeException) +{ + Any ret; + PyThreadAttach guard( mInterpreter ); + { + // convert parameters to python args + // TODO: Out parameter + Runtime runtime; + + sal_Int32 size = aParams.getLength(); + PyRef argsTuple(PyTuple_New( size ), SAL_NO_ACQUIRE ); + int i; + // fill tuple with default values in case of exceptions + for( i = 0 ;i < size ; i ++ ) + { + Py_INCREF( Py_None ); + PyTuple_SetItem( argsTuple.get(), i, Py_None ); + } + + // convert args to python + for( i = 0; i < size ; i ++ ) + { + PyRef val = runtime.any2PyObject( aParams[i] ); + PyTuple_SetItem( argsTuple.get(), i, val.getAcquired() ); + } + + // get callable + PyRef method(PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aFunctionName)), + SAL_NO_ACQUIRE); + raiseInvocationTargetExceptionWhenNeeded( runtime); + if( !method.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno::Adapater: Method " ).append( aFunctionName ); + buf.appendAscii( " is not implemented at object " ); + PyRef str( PyObject_Repr( mWrappedObject.get() ), SAL_NO_ACQUIRE ); + buf.appendAscii( PyString_AsString( str.get() )); + throw IllegalArgumentException( buf.makeStringAndClear(), Reference< XInterface > (),0 ); + } + + PYUNO_DEBUG_2( "entering python method %s\n" , (char*)TO_ASCII(aFunctionName) ); + PyRef pyRet( PyObject_CallObject( method.get(), argsTuple.get() ), SAL_NO_ACQUIRE ); + PYUNO_DEBUG_3( "leaving python method %s %d\n" , (char*)TO_ASCII(aFunctionName) , pyRet.is() ); + raiseInvocationTargetExceptionWhenNeeded( runtime); + if( pyRet.is() ) + { + ret = runtime.pyObject2Any( pyRet ); + + if( ret.hasValue() && + ret.getValueTypeClass() == com::sun::star::uno::TypeClass_SEQUENCE && + 0 != aFunctionName.compareToAscii( "getTypes" ) && // needed by introspection itself ! + 0 != aFunctionName.compareToAscii( "getImplementationId" ) ) // needed by introspection itself ! + { + // the sequence can either be + // 1) a simple sequence return value + // 2) a sequence, where the first element is the return value + // and the following elements are interpreted as the outparameter + // I can only decide for one solution by checking the method signature, + // so I need the reflection of the adapter ! +// if( ! mReflection.is() ) +// { +// Reference< XInterface > unoAdapter = mWeakUnoAdapter; +// if( ! unoAdapter.is() ) +// throw RuntimeException( +// OUString(RTL_CONSTASCII_USTRINGPARAM( +// "pyuno bridge: Couldn't retrieve uno adapter reference")),*this); +// mReflection = runtime.getImpl()->cargo->xCoreReflection->getType( +// makeAny( unoAdapter )); +// mWeakUnoAdapter = com::sun::star::uno::WeakReference< XInterface > (); +// } + if( ! mIntrospectionAccess.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno bridge: Couldn't inspect uno adapter ( the python class must implement com.sun.star.lang.XTypeProvider !)" ) ), + Reference< XInterface > () ); + + { + PyThreadDetach antiguard; + Reference< XIdlMethod > method = mIntrospectionAccess->getMethod( + aFunctionName, com::sun::star::beans::MethodConcept::ALL ); + if( ! method.is( ) ) + { + throw RuntimeException( + OUStringBuffer().appendAscii("pyuno bridge: Couldn't get reflection for method " + ).append( aFunctionName ).makeStringAndClear(), + Reference< XInterface > () ); + } + + Sequence< ParamInfo > seqInfo = method->getParameterInfos(); + int i; + int nOuts = 0; + for( i = 0 ; i < seqInfo.getLength() ; i ++ ) + { + if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT || + seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT ) + { + // sequence must be interpreted as return value/outparameter tuple ! + nOuts ++; + break; + } + } + + if( nOuts ) + { + Sequence< Any > seq; + if( ! ( ret >>= seq ) ) + { + throw RuntimeException( + OUStringBuffer().appendAscii( + "pyuno bridge: Couldn't extract out parameters for method " + ).append( aFunctionName ).makeStringAndClear(), + Reference< XInterface > () ); + } + if( nOuts +1 != seq.getLength() ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno bridge: expected for method " ); + buf.append( aFunctionName ); + buf.appendAscii( " one return value and " ); + buf.append( (sal_Int32) nOuts ); + buf.appendAscii( " out parameters, got a sequence of " ); + buf.append( seq.getLength() ); + buf.appendAscii( " elements as return value." ); + throw RuntimeException(buf.makeStringAndClear(), *this ); + } + aOutParamIndex.realloc( nOuts ); + aOutParam.realloc( nOuts ); + ret = seq[0]; + sal_Int32 nOutsAssigned = 0; + for( i = 0 ; i < seqInfo.getLength() ; i ++ ) + { + if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT || + seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT ) + { + aOutParamIndex[nOutsAssigned] = (sal_Int16) i; + aOutParam[nOutsAssigned] = seq[1+nOutsAssigned]; + nOutsAssigned ++; + } + } + } + } + // else { sequence is a return value !} + } + } + + } + PYUNO_DEBUG_1( "leaving Adapter::invoke normally\n" ); + return ret; +} + +void Adapter::setUnoAdapter( const Reference< XInterface > & unoAdapter ) +{ + // A performance nightmare. Every UNO object implemented in python needs to be introspected + // to get the knowledge about parameters. Must be solved differently + + // Even worse, the adapters do not support XWeak ! +// mWeakUnoAdapter = unoAdapter; + + Runtime runtime; + Reference< XIntrospection > xIntrospection =runtime.getImpl()->cargo->xIntrospection; + { + PyThreadDetach antiguard; + mIntrospectionAccess = xIntrospection->inspect(makeAny( unoAdapter )); + } +} + +void Adapter::setValue( const OUString & aPropertyName, const Any & value ) + throw( UnknownPropertyException, CannotConvertException, InvocationTargetException,RuntimeException) +{ + PyThreadAttach guard( mInterpreter ); + try + { + Runtime runtime; + PyRef obj = runtime.any2PyObject( value ); + + if( !hasProperty( aPropertyName ) ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName ); + buf.appendAscii( " is unknown." ); + throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + + PyObject_SetAttrString( + mWrappedObject.get(), (char*)TO_ASCII(aPropertyName), obj.get() ); + raiseInvocationTargetExceptionWhenNeeded( runtime); + + } + catch( IllegalArgumentException & exc ) + { + throw InvocationTargetException( exc.Message, *this, com::sun::star::uno::makeAny( exc ) ); + } +} + +Any Adapter::getValue( const OUString & aPropertyName ) + throw ( UnknownPropertyException, RuntimeException ) +{ + Any ret; + PyThreadAttach guard( mInterpreter ); + { + Runtime runtime; + PyRef pyRef( + PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aPropertyName) ), + SAL_NO_ACQUIRE ); + + raiseInvocationTargetExceptionWhenNeeded( runtime); + if( !pyRef.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName ); + buf.appendAscii( " is unknown." ); + throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + ret = runtime.pyObject2Any( pyRef ); + } + return ret; +} + +sal_Bool Adapter::hasMethod( const OUString & aMethodName ) + throw ( RuntimeException ) +{ + return hasProperty( aMethodName ); +} + +sal_Bool Adapter::hasProperty( const OUString & aPropertyName ) + throw ( RuntimeException ) +{ + sal_Bool bRet = sal_False; + PyThreadAttach guard( mInterpreter ); + { + bRet = PyObject_HasAttrString( + mWrappedObject.get() , (char*) TO_ASCII( aPropertyName )); + } + return bRet; +} + +} diff --git a/pyuno/source/module/pyuno_callable.cxx b/pyuno/source/module/pyuno_callable.cxx new file mode 100644 index 000000000000..fbe1f3690d86 --- /dev/null +++ b/pyuno/source/module/pyuno_callable.cxx @@ -0,0 +1,235 @@ +/************************************************************************* + * + * $RCSfile: pyuno_callable.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:56 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include "pyuno_impl.hxx" + +#include +#include + +using rtl::OUStringToOString; +using rtl::OUString; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::Type; +using com::sun::star::uno::TypeClass; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::XComponentContext; +using com::sun::star::lang::XSingleServiceFactory; +using com::sun::star::script::XTypeConverter; +using com::sun::star::script::XInvocation2; + +namespace pyuno +{ +typedef struct +{ + Reference xInvocation; + Reference xInvocationFactory; + Reference xTypeConverter; + OUString methodName; +} PyUNO_callable_Internals; + +typedef struct +{ + PyObject_HEAD + PyUNO_callable_Internals* members; +} PyUNO_callable; + +void PyUNO_callable_del (PyObject* self) +{ + PyUNO_callable* me; + + me = (PyUNO_callable*) self; + delete me->members; + PyMem_DEL (self); + + return; +} + +PyObject* PyUNO_callable_call (PyObject* self, PyObject* args, PyObject* kwords) +{ + PyUNO_callable* me; + + Sequence aOutParamIndex; + Sequence aOutParam; + Sequence aParams; + Sequence aParamTypes; + Any any_params; + Any out_params; + PyObject* python_params; + Any ret_value; + int num_params_in; + + me = (PyUNO_callable*) self; + + PyRef ret; + try + { + Runtime runtime; + any_params = runtime.pyObject2Any (args); + + if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE) + { + any_params >>= aParams; + } + else + { + aParams.realloc (1); + aParams [0] <<= any_params; + } + + { + PyThreadDetach antiguard; + PYUNO_DEBUG_2( "entering invoke %s\n", + OUStringToOString( me->members->methodName,RTL_TEXTENCODING_ASCII_US).getStr() ); + ret_value = me->members->xInvocation->invoke ( + me->members->methodName, aParams, aOutParamIndex, aOutParam); + PYUNO_DEBUG_2( "leaving invoke %s\n", + OUStringToOString( me->members->methodName,RTL_TEXTENCODING_ASCII_US).getStr() ); + } + + PyRef temp = runtime.any2PyObject (ret_value); + if( aOutParam.getLength() ) + { + PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE ); + PyTuple_SetItem (return_list.get(), 0, temp.getAcquired()); + + // initialize with defaults in case of exceptions + int i; + for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ ) + PyTuple_SetItem( return_list.get() , i , Py_None ); + + for( i = 0 ; i < aOutParam.getLength() ; i ++ ) + { + PyRef ref = runtime.any2PyObject( aOutParam[i] ); + PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired()); + } + ret = return_list; + } + else + { + ret = temp; + } + } + catch( com::sun::star::reflection::InvocationTargetException & e ) + { + raisePyExceptionWithAny( e.TargetException ); + } + catch( com::sun::star::script::CannotConvertException &e ) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); + } + catch( com::sun::star::lang::IllegalArgumentException &e ) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); + } + catch (::com::sun::star::uno::RuntimeException &e) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); + } + + return ret.getAcquired(); +} + + +static PyTypeObject PyUNO_callable_Type = +{ + PyObject_HEAD_INIT (&PyType_Type) + 0, + "PyUNO_callable", + sizeof (PyUNO_callable), + 0, + (destructor) ::pyuno::PyUNO_callable_del, + (printfunc) 0, + (getattrfunc) 0, + (setattrfunc) 0, + (cmpfunc) 0, + (reprfunc) 0, + 0, + 0, + 0, + (hashfunc) 0, + (ternaryfunc) ::pyuno::PyUNO_callable_call, + (reprfunc) 0, +}; + +PyRef PyUNO_callable_new ( + const Reference &my_inv, + const OUString & methodName, + const Reference &xInvocationFactory, + const Reference &tc) +{ + PyUNO_callable* self; + + self = PyObject_NEW (PyUNO_callable, &PyUNO_callable_Type); + if (self == NULL) + return NULL; //NULL == Error! + + self->members = new PyUNO_callable_Internals; + self->members->xInvocation = my_inv; + self->members->methodName = methodName; + self->members->xInvocationFactory = xInvocationFactory; + self->members->xTypeConverter = tc; + + return PyRef( (PyObject*)self, SAL_NO_ACQUIRE ); +} + +} diff --git a/pyuno/source/module/pyuno_dlopenwrapper.c b/pyuno/source/module/pyuno_dlopenwrapper.c new file mode 100644 index 000000000000..fbf0b101520d --- /dev/null +++ b/pyuno/source/module/pyuno_dlopenwrapper.c @@ -0,0 +1,72 @@ +/************************************************************************* + * + * $RCSfile: pyuno_dlopenwrapper.c,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:56 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include + +void initpyuno () +{ + void (*func)(void); + void* h = dlopen ("libpyuno.so", RTLD_NOW | RTLD_GLOBAL); + if( h ) + { + func = (void (*)())dlsym (h, "initpyuno"); + (func) (); + } +} diff --git a/pyuno/source/module/pyuno_except.cxx b/pyuno/source/module/pyuno_except.cxx new file mode 100644 index 000000000000..17bec3a53a8b --- /dev/null +++ b/pyuno/source/module/pyuno_except.cxx @@ -0,0 +1,265 @@ +/************************************************************************* + * + * $RCSfile: pyuno_except.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:57 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include "pyuno_impl.hxx" + +#include + +#include + +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Type; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::TypeDescription; + +namespace pyuno +{ + +void raisePyExceptionWithAny( const com::sun::star::uno::Any &anyExc ) +{ + try + { + Runtime runtime; + PyRef exc = runtime.any2PyObject( anyExc ); + if( exc.is() ) + { + PyRef type( getClass( anyExc.getValueType().getTypeName(),runtime ) ); + PyErr_SetObject( type.get(), exc.get()); + } + else + { + com::sun::star::uno::Exception e; + anyExc >>= e; + + OUStringBuffer buf; + buf.appendAscii( "Couldn't convert uno exception to a python exception (" ); + buf.append(anyExc.getValueType().getTypeName()); + buf.appendAscii( ": " ); + buf.append(e.Message ); + buf.appendAscii( ")" ); + PyErr_SetString( + PyExc_SystemError, + OUStringToOString(buf.makeStringAndClear(),RTL_TEXTENCODING_ASCII_US) ); + } + } + catch( com::sun::star::lang::IllegalArgumentException & e) + { + PyErr_SetString( PyExc_SystemError, + OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); + } + catch( com::sun::star::script::CannotConvertException & e) + { + PyErr_SetString( PyExc_SystemError, + OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); + } + catch( RuntimeException & e) + { + PyErr_SetString( PyExc_SystemError, + OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); + } +} + + +static PyRef createClass( const OUString & name, const Runtime &runtime ) + throw ( RuntimeException ) +{ + // assuming that this is never deleted ! + // note I don't have the knowledge how to initialize these type objects correctly ! + TypeDescription desc( name ); + if( ! desc.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.getClass: uno exception " ); + buf.append(name).appendAscii( " is unknown" ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + + sal_Bool isStruct = desc.get()->eTypeClass == typelib_TypeClass_STRUCT; + sal_Bool isExc = desc.get()->eTypeClass == typelib_TypeClass_EXCEPTION; + sal_Bool isInterface = desc.get()->eTypeClass == typelib_TypeClass_INTERFACE; + if( !isStruct && !isExc && ! isInterface ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.getClass: " ).append(name).appendAscii( "is a " ); + buf.appendAscii( + typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass)); + buf.appendAscii( ", expected EXCEPTION, STRUCT or INTERFACE" ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface>() ); + } + + // retrieve base class + PyRef base; + if( isInterface ) + { + typelib_InterfaceTypeDescription *pDesc = (typelib_InterfaceTypeDescription * )desc.get(); + if( pDesc->pBaseTypeDescription ) + { + base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime ); + } + else + { + // must be XInterface ! + } + } + else + { + typelib_CompoundTypeDescription *pDesc = (typelib_CompoundTypeDescription*)desc.get(); + if( pDesc->pBaseTypeDescription ) + { + base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime ); + } + else + { + if( isExc ) + // we are currently creating the root UNO exception + base = PyRef(PyExc_Exception); + } + } + PyRef args( PyTuple_New( 3 ), SAL_NO_ACQUIRE ); + + PyRef pyTypeName = ustring2PyString( name /*.replace( '.', '_' )*/ ); + + PyRef bases; + if( base.is() ) + { + bases = PyRef( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); + PyTuple_SetItem( bases.get(), 0 , base.getAcquired() ); + } + else + { + bases = PyRef( PyTuple_New( 0 ), SAL_NO_ACQUIRE ); + } + + PyTuple_SetItem( args.get(), 0, pyTypeName.getAcquired()); + PyTuple_SetItem( args.get(), 1, bases.getAcquired() ); + PyTuple_SetItem( args.get(), 2, PyDict_New() ); + + PyRef ret( + PyObject_CallObject(reinterpret_cast(&PyClass_Type) , args.get()), + SAL_NO_ACQUIRE ); + + // now overwrite ctor and attrib functions + if( isInterface ) + { + PyObject_SetAttrString( ret.get(), "__pyunointerface__" , ustring2PyString(name).get() ); + } + else + { + PyRef ctor = getObjectFromUnoModule( runtime,"_uno_struct__init__" ); + PyRef setter = getObjectFromUnoModule( runtime,"_uno_struct__setattr__" ); + PyRef getter = getObjectFromUnoModule( runtime,"_uno_struct__getattr__" ); + PyRef repr = getObjectFromUnoModule( runtime,"_uno_struct__repr__" ); + PyRef eq = getObjectFromUnoModule( runtime,"_uno_struct__eq__" ); + + PyObject_SetAttrString( ret.get(), "__pyunostruct__" , ustring2PyString(name).get() ); + PyObject_SetAttrString( ret.get(), "typeName", ustring2PyString(name).get() ); + PyObject_SetAttrString( ret.get(), "__init__" , ctor.get() ); + PyObject_SetAttrString( ret.get(), "__getattr__", getter.get() ); + PyObject_SetAttrString( ret.get(), "__setattr__", setter.get() ); + PyObject_SetAttrString( ret.get(), "__repr__", repr.get() ); + PyObject_SetAttrString( ret.get(), "__str__", repr.get() ); + PyObject_SetAttrString( ret.get(), "__eq__", eq.get() ); + } + return ret; +} + +sal_Bool isInstanceOfStructOrException( const Runtime & runtime, PyObject *obj) +{ + PyRef attr(PyObject_GetAttrString(obj,"__class__"), SAL_NO_ACQUIRE ); + return PyObject_HasAttrString(attr.get(),"__pyunostruct__"); +} + +sal_Bool isInterfaceClass( const Runtime &runtime, PyObject * obj ) +{ + const ClassSet & set = runtime.getImpl()->cargo->interfaceSet; + return set.find( obj ) != set.end(); +} + +PyRef getClass( const OUString & name , const Runtime &runtime) +{ + PyRef ret; + + RuntimeCargo *cargo =runtime.getImpl()->cargo; + ExceptionClassMap::iterator ii = cargo->exceptionMap.find( name ); + if( ii == cargo->exceptionMap.end() ) + { + ret = createClass( name, runtime ); + cargo->exceptionMap[name] = ret; + if( PyObject_HasAttrString( ret.get() , "__pyunointerface__" ) ) + cargo->interfaceSet.insert( ret ); + + PyObject_SetAttrString( ret.get(), "__pyunointerface__" , ustring2PyString(name).get() ); + } + else + { + ret = ii->second; + } + + return ret; +} + + +} diff --git a/pyuno/source/module/pyuno_gc.cxx b/pyuno/source/module/pyuno_gc.cxx new file mode 100644 index 000000000000..3a9da266544d --- /dev/null +++ b/pyuno/source/module/pyuno_gc.cxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: pyuno_gc.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:57 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include +#include +namespace pyuno +{ + + +class GCThread : public ::osl::Thread +{ + PyObject *mPyObject; + PyInterpreterState *mPyInterpreter; + GCThread( const GCThread & ); // not implemented + GCThread &operator =( const GCThread & ); // not implemented + +public: + GCThread( PyInterpreterState *interpreter, PyObject * object ); + virtual void SAL_CALL run(); + virtual void SAL_CALL onTerminated(); +}; + + +GCThread::GCThread( PyInterpreterState *interpreter, PyObject * object ) : + mPyInterpreter( interpreter ), mPyObject( object ) +{} + +void GCThread::run() +{ + try + { + PyThreadAttach guard( (PyInterpreterState*)mPyInterpreter ); + { + Py_XDECREF( mPyObject ); + } + } + catch( com::sun::star::uno::RuntimeException & e ) + { + rtl::OString msg; + msg = rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + fprintf( stderr, "Leaking python objects bridged to UNO for reason %s\n",msg.getStr()); + } +} + + +void GCThread::onTerminated() +{ + delete this; +} + +void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object ) +{ + // delegate to a new thread, because there does not seem + // to be a method, which tells, whether the global + // interpreter lock is held or not + // TODO: Look for a more efficient solution + osl::Thread *t = new GCThread( interpreter, object ); + t->create(); +} + +} diff --git a/pyuno/source/module/pyuno_impl.hxx b/pyuno/source/module/pyuno_impl.hxx new file mode 100644 index 000000000000..f40559a15a96 --- /dev/null +++ b/pyuno/source/module/pyuno_impl.hxx @@ -0,0 +1,294 @@ +/************************************************************************* + * + * $RCSfile: pyuno_impl.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:57 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#ifndef _PYUNO_IMPL_ +#define _PYUNO_IMPL_ + +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include + +namespace pyuno +{ + +typedef ::std::hash_map +< + PyRef, + com::sun::star::uno::WeakReference< com::sun::star::uno::XInterface >, + PyRef::Hash, + std::equal_to< PyRef > +> PyRef2Adapter; + + +typedef ::std::hash_map +< +rtl::OUString, +PyRef, +rtl::OUStringHash, +std::equal_to +> ExceptionClassMap; + + +typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to > ClassSet; + +PyObject* PyUNO_new( + const com::sun::star::uno::Any & targetInterface, + const com::sun::star::uno::Reference & ssf); + +PyObject* PyUNO_new_UNCHECKED ( + const com::sun::star::uno::Any & targetInterface, + const com::sun::star::uno::Reference & ssf); + +typedef struct +{ + com::sun::star::uno::Reference xInvocation; + com::sun::star::uno::Any wrappedObject; +} PyUNOInternals; + +typedef struct +{ + PyObject_HEAD + PyUNOInternals* members; +} PyUNO; + +PyRef ustring2PyUnicode( const rtl::OUString &source ); +PyRef ustring2PyString( const ::rtl::OUString & source ); +rtl::OUString pyString2ustring( PyObject *str ); + + +PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Any PyObjectToAny (PyObject* o) + throw ( com::sun::star::uno::RuntimeException ); + +void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime ) + throw ( com::sun::star::reflection::InvocationTargetException ); + +// bool CheckPyObjectTypes (PyObject* o, Sequence types); +// bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object. + +com::sun::star::uno::TypeClass StringToTypeClass (char* string); + +PyRef PyUNO_callable_new ( + const com::sun::star::uno::Reference &xInv, + const rtl::OUString &methodName, + const com::sun::star::uno::Reference &ssf, + const com::sun::star::uno::Reference &tc ); + +PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r ); +PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r ); +PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r); +PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r ); + +PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName ); + +PyRef getTypeClass( const Runtime &); +PyRef getEnumClass( const Runtime &); +PyRef getBoolClass( const Runtime &); +PyRef getCharClass( const Runtime &); +PyRef getByteSequenceClass( const Runtime & ); +PyRef getPyUnoClass( const Runtime &); +PyRef getClass( const rtl::OUString & name , const Runtime & runtime ); + +com::sun::star::uno::Any PyEnum2Enum( PyObject *obj, const Runtime & r ) + throw ( com::sun::star::uno::RuntimeException ); +sal_Bool PyBool2Bool( PyObject *o, const Runtime & r ) + throw ( com::sun::star::uno::RuntimeException ); +sal_Unicode PyChar2Unicode( PyObject *o, const Runtime & r ) + throw ( com::sun::star::uno::RuntimeException ); +com::sun::star::uno::Type PyType2Type( PyObject * o, const Runtime & r ) + throw( com::sun::star::uno::RuntimeException ); + +void raisePyExceptionWithAny( const com::sun::star::uno::Any &a ); +const char *typeClassToString( com::sun::star::uno::TypeClass t ); + +PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object ) + throw ( com::sun::star::uno::RuntimeException ); + +sal_Bool isInterfaceClass( const Runtime &, PyObject *obj ); +sal_Bool isInstanceOfStructOrException( const Runtime & runtime, PyObject *obj); +com::sun::star::uno::Sequence implementsInterfaces( + const Runtime & runtime, PyObject *obj ); + +struct RuntimeCargo +{ + com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation; + com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter; + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext; + com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection; + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr; + com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory; + com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection; + PyRef dictUnoModule; + bool valid; + ExceptionClassMap exceptionMap; + ClassSet interfaceSet; + PyRef2Adapter mappedObjects; + + PyRef getUnoModule(); +}; + +struct stRuntimeImpl +{ + PyObject_HEAD + struct RuntimeCargo *cargo; +public: + static void del( PyObject *self ); + + static PyRef create( + const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext ) + throw ( com::sun::star::uno::RuntimeException ); +}; + + +class Adapter : public cppu::WeakImplHelper2< + com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel > +{ + PyRef mWrappedObject; + PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted ! + com::sun::star::uno::WeakReference< com::sun::star::uno::XInterface > mWeakUnoAdapter; + com::sun::star::uno::Reference< com::sun::star::beans::XIntrospectionAccess > mIntrospectionAccess; +public: + Adapter( const PyRef &obj, const Runtime & ); + + // should be called directly after construction of the adapter + // implementation stores a weak reference to it until it has + // created a reflection. (Ensure, that there is already a refcount + // on the Adapter object !) + void setUnoAdapter( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &itr); + + static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId(); + PyRef getWrappedObject() { return mWrappedObject; } + virtual ~Adapter(); + + // XInvocation + virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > + SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL invoke( + const ::rtl::OUString& aFunctionName, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, + ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex, + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::script::CannotConvertException, + ::com::sun::star::reflection::InvocationTargetException, + ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setValue( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::script::CannotConvertException, + ::com::sun::star::reflection::InvocationTargetException, + ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( + const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (::com::sun::star::uno::RuntimeException); +}; + + +/** releases a refcount on the interpreter object and on another given python object. + + The function can be called from any thread regardless of whether the global + interpreter lock is held. + + */ +void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object ); + +#ifdef PYUNO_DEBUG +#define PYUNO_DEBUG_1( msg ) fprintf( stdout, msg ) +#define PYUNO_DEBUG_2( msg, arg1 ) fprintf( stdout, msg , arg1 ) +#define PYUNO_DEBUG_3( msg, arg1 , arg2 ) fprintf( stdout, msg, arg1, arg2 ) +#else +#define PYUNO_DEBUG_1(msg) ((void)0) +#define PYUNO_DEBUG_2(msg,arg1) ((void)0) +#define PYUNO_DEBUG_3(msg,arg2,arg3) ((void)0) +#endif + +} + +#endif diff --git a/pyuno/source/module/pyuno_module.cxx b/pyuno/source/module/pyuno_module.cxx new file mode 100644 index 000000000000..07ca43086d2f --- /dev/null +++ b/pyuno/source/module/pyuno_module.cxx @@ -0,0 +1,631 @@ +/************************************************************************* + * + * $RCSfile: pyuno_module.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:58 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "pyuno_impl.hxx" + +#include +#include + +using osl::Module; + +using rtl::OString; +using rtl::OUString; +using rtl::OUStringToOString; +using rtl::OUStringBuffer; +using rtl::OStringBuffer; + +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::TypeDescription; +using com::sun::star::uno::XComponentContext; +using com::sun::star::container::NoSuchElementException; +using com::sun::star::reflection::XIdlReflection; +using com::sun::star::reflection::XIdlClass; +using com::sun::star::script::XInvocation2; + +namespace pyuno +{ + +/** + @ index of the next to be used member in the initializer list ! + */ +static sal_Int32 fillStructWithInitializer( + const Reference< XInvocation2 > &inv, + typelib_CompoundTypeDescription *pCompType, + PyObject *initializer, + const Runtime &runtime) throw ( RuntimeException ) +{ + sal_Int32 nIndex = 0; + if( pCompType->pBaseTypeDescription ) + nIndex = fillStructWithInitializer( + inv, pCompType->pBaseTypeDescription, initializer, runtime ); + + sal_Int32 nTupleSize = PyTuple_Size(initializer); + int i; + for( i = 0 ; i < pCompType->nMembers ; i ++ ) + { + if( i + nIndex >= nTupleSize ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno._createUnoStructHelper: too few elements in the initializer tuple,"); + buf.appendAscii( "expected at least " ).append( nIndex + pCompType->nMembers ); + buf.appendAscii( ", got " ).append( nTupleSize ); + throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ()); + } + PyObject *element = PyTuple_GetItem( initializer, i + nIndex ); + Any a = runtime.pyObject2Any( element ); + inv->setValue( pCompType->ppMemberNames[i], a ); + } + return i+nIndex; +} + +static PyObject *createUnoStructHelper(PyObject *self, PyObject* args ) +{ + Any IdlStruct; + PyRef ret; + + try + { + Runtime runtime; + if( PyTuple_Size( args ) == 2 ) + { + PyObject *structName = PyTuple_GetItem( args,0 ); + PyObject *initializer = PyTuple_GetItem( args ,1 ); + + if( PyString_Check( structName ) ) + { + if( PyTuple_Check( initializer ) ) + { + OUString typeName( OUString::createFromAscii(PyString_AsString(structName))); + RuntimeCargo *c = runtime.getImpl()->cargo; + Reference idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY); + if (idl_class.is ()) + { + idl_class->createObject (IdlStruct); + PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation ); + ret = PyRef( (PyObject *) me , SAL_NO_ACQUIRE); + if( PyTuple_Size( initializer ) > 0 ) + { + TypeDescription desc( typeName ); + OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 ! + + typelib_CompoundTypeDescription *pCompType = + ( typelib_CompoundTypeDescription * ) desc.get(); + sal_Int32 n = fillStructWithInitializer( + me->members->xInvocation, pCompType, initializer, runtime ); + if( n != PyTuple_Size(initializer) ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno._createUnoStructHelper: wrong number of "); + buf.appendAscii( "elements in the initializer list, expected " ); + buf.append( n ); + buf.appendAscii( ", got " ); + buf.append( (sal_Int32) PyTuple_Size(initializer) ); + throw RuntimeException( + buf.makeStringAndClear(), Reference< XInterface > ()); + } + } + } + else + { + OStringBuffer buf; + buf.append( "UNO struct " ); + buf.append( PyString_AsString(structName) ); + buf.append( " is unkown" ); + PyErr_SetString (PyExc_RuntimeError, buf.getStr()); + } + } + else + { + PyErr_SetString( + PyExc_RuntimeError, + "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" ); + } + } + else + { + PyErr_SetString (PyExc_AttributeError, "createUnoStruct: first argument wasn't a string"); + } + } + else + { + PyErr_SetString (PyExc_AttributeError, "1 Arguments: Structure Name"); + } + } + catch( com::sun::star::uno::RuntimeException & e ) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + catch( com::sun::star::script::CannotConvertException & e ) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + catch( com::sun::star::uno::Exception & e ) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + return ret.getAcquired(); +} +static OUString getLibDir() +{ + static OUString *pLibDir; + if( !pLibDir ) + { + osl::MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! pLibDir ) + { + static OUString libDir; + + OUString path; + if( Module::getUrlFromAddress( reinterpret_cast(getLibDir) , path ) ) + { + libDir = path.copy( 0, path.lastIndexOf( '/' ) ); + OStringBuffer buf(path.getLength()+20); + buf.append( "PYUNOLIBDIR=" ); + buf.append( OUStringToOString( libDir, osl_getThreadTextEncoding() ) ); + OString o = buf.makeStringAndClear(); + + // leak the string, because on some platforms, putenv takes over ownership of the string + rtl_string_acquire( o.pData ); + + // needs to be replaced by rtl_setBootstrapVariable once it is available + putenv( (char*) o.getStr() ); + } + pLibDir = &libDir; + } + } + return *pLibDir; +} + +static PyObject* getComponentContext (PyObject* self, PyObject* args) +{ + PyRef ret; + try + { + Reference ctx; + + // getLibDir() must be called in order to set bootstrap variables correctly ! + OUString path( getLibDir()); + + if( Runtime::isInitialized() ) + { + Runtime runtime; + ctx = runtime.getImpl()->cargo->xContext; + } + else + { + OUString iniFile; + if( !path.getLength() ) + { + PyErr_SetString( + PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini " + "file for bootstrapping python uno bridge\n" ); + return NULL; + } + + OUStringBuffer iniFileName; + iniFileName.append( path ); + iniFileName.appendAscii( "/" ); + iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) ); + iniFile = iniFileName.makeStringAndClear(); + + PyThreadDetach antiguard; + ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile); + } + + if( ! Runtime::isInitialized() ) + { + Runtime::initialize( ctx ); + } + Runtime runtime; + ret = runtime.any2PyObject( makeAny( ctx ) ); + } + catch (com::sun::star::registry::InvalidRegistryException &e) + { + raisePyExceptionWithAny( makeAny(e) ); + } + catch( com::sun::star::lang::IllegalArgumentException & e) + { + raisePyExceptionWithAny( makeAny(e)); + } + catch( com::sun::star::script::CannotConvertException & e) + { + raisePyExceptionWithAny( makeAny(e)); + } + catch (com::sun::star::uno::RuntimeException & e) + { + raisePyExceptionWithAny( makeAny(e) ); + } + catch (com::sun::star::uno::Exception & e) + { + raisePyExceptionWithAny( makeAny(e) ); + } + return ret.getAcquired(); +} + +static PyObject *getTypeByName( PyObject *self, PyObject *args ) +{ + PyObject * ret = NULL; + + try + { + char *name; + + if (PyArg_ParseTuple (args, "s", &name)) + { + OUString typeName ( OUString::createFromAscii( name ) ); + TypeDescription typeDesc( typeName ); + if( typeDesc.is() ) + { + Runtime runtime; + ret = PyUNO_Type_new( + name, (com::sun::star::uno::TypeClass)typeDesc.get()->eTypeClass, runtime ); + } + else + { + OStringBuffer buf; + buf.append( "Type " ).append(name).append( " is unknown" ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + } + } + } + catch ( RuntimeException & e ) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + return ret; +} + +static PyObject * extractOneStringArg( PyObject *args, char *funcName ) +{ + if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 ) + { + OStringBuffer buf; + buf.append( funcName ).append( ": expecting one string argument" ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + return NULL; + } + PyObject *obj = PyTuple_GetItem( args, 0 ); + if( !PyString_Check( obj ) ) + { + OStringBuffer buf; + buf.append( funcName ).append( ": expecting one string argument" ); + PyErr_SetString( PyExc_TypeError, buf.getStr()); + return NULL; + } + return obj; +} + + +static PyObject *getConstantByName( PyObject *self, PyObject *args ) +{ + PyObject *ret = 0; + try + { + char *name; + + if (PyArg_ParseTuple (args, "s", &name)) + { + OUString typeName ( OUString::createFromAscii( name ) ); + Runtime runtime; + Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName); + if( a.getValueType().getTypeClass() == + com::sun::star::uno::TypeClass_INTERFACE ) + { + // a ídl constant cannot be an instance of an uno-object, thus + // this cannot be a constant + OUStringBuffer buf; + buf.appendAscii( "pyuno.getConstantByName: " ).append( typeName ); + buf.appendAscii( "is not a constant" ); + throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > () ); + } + PyRef constant = runtime.any2PyObject( a ); + ret = constant.getAcquired(); + } + } + catch( NoSuchElementException & e ) + { + // to the python programmer, this is a runtime exception, + // do not support tweakings with the type system + RuntimeException runExc( e.Message, Reference< XInterface > () ); + raisePyExceptionWithAny( makeAny( runExc ) ); + } + catch( com::sun::star::script::CannotConvertException & e) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + catch( com::sun::star::lang::IllegalArgumentException & e) + { + raisePyExceptionWithAny( makeAny( e ) ); + } + catch( RuntimeException & e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + return ret; +} + +static PyObject *checkType( PyObject *self, PyObject *args ) +{ + if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 ) + { + OStringBuffer buf; + buf.append( "pyuno.checkType : expecting one uno.Type argument" ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + return NULL; + } + PyObject *obj = PyTuple_GetItem( args, 0 ); + + try + { + Runtime runtime; + PyType2Type( obj , runtime ); + } + catch( RuntimeException & e) + { + raisePyExceptionWithAny( makeAny( e ) ); + return NULL; + } + return Py_None; +} + +static PyObject *checkEnum( PyObject *self, PyObject *args ) +{ + if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 ) + { + OStringBuffer buf; + buf.append( "pyuno.checkType : expecting one uno.Type argument" ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + return NULL; + } + PyObject *obj = PyTuple_GetItem( args, 0 ); + + try + { + Runtime runtime; + PyEnum2Enum( obj , runtime ); + } + catch( RuntimeException & e) + { + raisePyExceptionWithAny( makeAny( e) ); + return NULL; + } + return Py_None; +} + +static PyObject *getClass( PyObject *self, PyObject *args ) +{ + PyObject *obj = extractOneStringArg( args, "pyuno.getClass"); + if( ! obj ) + return NULL; + + try + { + Runtime runtime; + PyRef ret = getClass( + OUString( PyString_AsString( obj), strlen(PyString_AsString(obj)),RTL_TEXTENCODING_ASCII_US), + runtime ); + Py_XINCREF( ret.get() ); + return ret.get(); + } + catch( RuntimeException & e) + { + raisePyExceptionWithAny( makeAny(e) ); + } + return NULL; +} + +static PyObject *isInterface( PyObject *self, PyObject *args ) +{ + + if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 ) + { + PyObject *obj = PyTuple_GetItem( args, 0 ); + Runtime r; + return PyInt_FromLong( isInterfaceClass( r, obj ) ); + } + return PyInt_FromLong( 0 ); +} + +static PyObject * generateUuid( PyObject *self, PyObject *args ) +{ + Sequence< sal_Int8 > seq( 16 ); + rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False ); + PyRef ret; + try + { + Runtime runtime; + ret = runtime.any2PyObject( makeAny( seq ) ); + } + catch( RuntimeException & e ) + { + raisePyExceptionWithAny( makeAny(e) ); + } + return ret.getAcquired(); +} + +static PyObject *systemPathToFileUrl( PyObject * self, PyObject * args ) +{ + PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" ); + if( ! obj ) + return NULL; + + OUString sysPath = pyString2ustring( obj ); + OUString url; + osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url ); + + if( e != osl::FileBase::E_None ) + { + OUStringBuffer buf; + buf.appendAscii( "Couldn't convert " ); + buf.append( sysPath ); + buf.appendAscii( " to a file url for reason (" ); + buf.append( (sal_Int32) e ); + buf.appendAscii( ")" ); + raisePyExceptionWithAny( + makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ))); + return NULL; + } + return ustring2PyUnicode( url ).getAcquired(); +} + + +static PyObject * fileUrlToSystemPath( PyObject *self, PyObject * args ) +{ + PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" ); + if( ! obj ) + return NULL; + + OUString url = pyString2ustring( obj ); + OUString sysPath; + osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath ); + + if( e != osl::FileBase::E_None ) + { + OUStringBuffer buf; + buf.appendAscii( "Couldn't convert file url " ); + buf.append( sysPath ); + buf.appendAscii( " to a system path for reason (" ); + buf.append( (sal_Int32) e ); + buf.appendAscii( ")" ); + raisePyExceptionWithAny( + makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ))); + return NULL; + } + return ustring2PyUnicode( sysPath ).getAcquired(); +} + + +static PyObject * absolutize( PyObject *self, PyObject * args ) +{ + Py_UNICODE * path = 0; + Py_UNICODE * rel = 0; + if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 ) + { + OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) ); + OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) ); + OUString ret; + oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) ); + if( e != osl_File_E_None ) + { + OUStringBuffer buf; + buf.appendAscii( "Couldn't absolutize " ); + buf.append( ouRel ); + buf.appendAscii( " using root " ); + buf.append( ouPath ); + buf.appendAscii( " for reason (" ); + buf.append( (sal_Int32) e ); + buf.appendAscii( ")" ); + + PyErr_SetString( + PyExc_OSError, + OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding())); + return 0; + } + return PyUnicode_FromUnicode( (const Py_UNICODE * ) ret.pData->buffer, ret.pData->length ); + } + return 0; +} + +} + +using namespace pyuno; + +static struct PyMethodDef PyUNOModule_methods [] = +{ + {"getComponentContext", getComponentContext, 1}, + {"_createUnoStructHelper", createUnoStructHelper, 2}, + {"getTypeByName", getTypeByName, 1}, + {"getConstantByName", getConstantByName,1}, + {"getClass", getClass,1}, + {"checkEnum", checkEnum, 1}, + {"checkType", checkType, 1}, + {"generateUuid", generateUuid,0}, + {"systemPathToFileUrl",systemPathToFileUrl,1}, + {"fileUrlToSystemPath",fileUrlToSystemPath,1}, + {"absolutize",absolutize,2}, + {"isInterface",isInterface,1}, + {NULL, NULL} +}; + + +extern "C" PY_DLLEXPORT void initpyuno() +{ + // noop when called already, otherwise needed to allow multiple threads + PyEval_InitThreads(); + Py_InitModule ("pyuno", PyUNOModule_methods); +} diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx new file mode 100644 index 000000000000..48994e56eef7 --- /dev/null +++ b/pyuno/source/module/pyuno_runtime.cxx @@ -0,0 +1,819 @@ +/************************************************************************* + * + * $RCSfile: pyuno_runtime.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:58 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include +#include +#include + +#include + +#include + +#include "pyuno_impl.hxx" + +using rtl::OUString; +using rtl::OUStringToOString; +using rtl::OUStringBuffer; +using rtl::OStringBuffer; +using rtl::OString; + +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::TypeDescription; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Type; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::XComponentContext; +using com::sun::star::lang::XSingleServiceFactory; +using com::sun::star::lang::XUnoTunnel; +using com::sun::star::reflection::XIdlReflection; +using com::sun::star::script::XTypeConverter; +using com::sun::star::script::XInvocationAdapterFactory2; +using com::sun::star::beans::XMaterialHolder; +using com::sun::star::beans::XIntrospection; + +namespace pyuno +{ +#define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +static PyTypeObject RuntimeImpl_Type = +{ + PyObject_HEAD_INIT (&PyType_Type) + 0, + "pyuno_runtime", + sizeof (RuntimeImpl), + 0, + (destructor) RuntimeImpl::del, + (printfunc) 0, + (getattrfunc) 0, + (setattrfunc) 0, + (cmpfunc) 0, + (reprfunc) 0, + 0, + 0, + 0, + (hashfunc) 0, + (ternaryfunc) 0, + (reprfunc) 0, +}; + +/*---------------------------------------------------------------------- + Runtime implementation + -----------------------------------------------------------------------*/ +static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl ) + throw ( com::sun::star::uno::RuntimeException ) +{ + PyThreadState * state = PyThreadState_Get(); + if( ! state ) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "python global interpreter must be held (thread must be attached)" )), + Reference< XInterface > () ); + } + + globalDict = PyRef( PyModule_GetDict(PyImport_AddModule("__main__"))); + + if( ! globalDict.is() ) // FATAL ! + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "can't find __main__ module" )), Reference< XInterface > ()); + } + runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" ); +} + +static PyRef importUnoModule( ) throw ( RuntimeException ) +{ + PyRef globalDict = PyRef( PyModule_GetDict(PyImport_AddModule("__main__"))); + // import the uno module + PyRef module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE ); + if( PyErr_Occurred() ) + { + PyRef excType, excValue, excTraceback; + PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback); + PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE ); + + OUStringBuffer buf; + buf.appendAscii( "python object raised an unknown exception (" ); + PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE ); + buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" ); + buf.appendAscii( PyString_AsString( str.get() ) ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + PyRef dict( PyModule_GetDict( module.get() ) ); + return dict; +} + +/*------------------------------------------------------------------- + RuntimeImpl implementations + *-------------------------------------------------------------------*/ +PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx ) + throw( com::sun::star::uno::RuntimeException ) +{ + RuntimeImpl *me = PyObject_NEW (RuntimeImpl, &RuntimeImpl_Type); + if( ! me ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ), + Reference< XInterface > () ); + me->cargo = 0; + + // must use a different struct here, as the PyObject_NEW macro + // makes C++ unusable + RuntimeCargo *c = new RuntimeCargo(); + c->valid = 1; + c->xContext = ctx; + c->xInvocation = Reference< XSingleServiceFactory > ( + ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ), + ctx ), + UNO_QUERY ); + if( ! c->xInvocation.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ), + Reference< XInterface > () ); + + c->xTypeConverter = Reference< XTypeConverter > ( + ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ), + ctx ), + UNO_QUERY ); + if( ! c->xTypeConverter.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )), + Reference< XInterface > () ); + + c->xCoreReflection = Reference< XIdlReflection > ( + ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ), + ctx ), + UNO_QUERY ); + if( ! c->xCoreReflection.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )), + Reference< XInterface > () ); + + c->xAdapterFactory = Reference< XInvocationAdapterFactory2 > ( + ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ), + ctx ), + UNO_QUERY ); + if( ! c->xAdapterFactory.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )), + Reference< XInterface > () ); + + c->xIntrospection = Reference< XIntrospection > ( + ctx->getServiceManager()->createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ), + ctx ), + UNO_QUERY ); + if( ! c->xIntrospection.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )), + Reference< XInterface > () ); + + Any a = ctx->getValueByName(OUString( + RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) ); + a >>= c->xTdMgr; + if( ! c->xTdMgr.is() ) + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )), + Reference< XInterface > () ); + + me->cargo =c; + return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE ); +} + +void stRuntimeImpl::del(PyObject* self) +{ + RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self ); + delete me->cargo; + PyMem_DEL (self); +} + + +void Runtime::initialize( const Reference< XComponentContext > & ctx ) + throw ( RuntimeException ) +{ + PyRef globalDict, runtime; + getRuntimeImpl( globalDict , runtime ); + RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); + + if( runtime.is() && impl->cargo->valid ) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "pyuno runtime has already been initialized before" ) ), + Reference< XInterface > () ); + } + PyRef keep( RuntimeImpl::create( ctx ) ); + PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() ); + Py_XINCREF( keep.get() ); +} + + +bool Runtime::isInitialized() throw ( RuntimeException ) +{ + PyRef globalDict, runtime; + getRuntimeImpl( globalDict , runtime ); + RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); + return runtime.is() && impl->cargo->valid; +} + +void Runtime::finalize() throw (RuntimeException) +{ + PyRef globalDict, runtime; + getRuntimeImpl( globalDict , runtime ); + RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); + if( !runtime.is() || ! impl->cargo->valid ) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "pyuno bridge must have been initialized before finalizing" )), + Reference< XInterface > () ); + } + impl->cargo->valid = false; + impl->cargo->xInvocation.clear(); + impl->cargo->xContext.clear(); + impl->cargo->xTypeConverter.clear(); +} + +Runtime::Runtime() throw( RuntimeException ) + : impl( 0 ) +{ + PyRef globalDict, runtime; + getRuntimeImpl( globalDict , runtime ); + if( ! runtime.is() ) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, " + "(the pyuno.bootstrap needs to be called before using any uno classes)")), + Reference< XInterface > () ); + } + impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); + Py_XINCREF( runtime.get() ); +} + +Runtime::Runtime( const Runtime & r ) +{ + impl = r.impl; + Py_XINCREF( reinterpret_cast< PyObject * >(impl) ); +} + +Runtime::~Runtime() +{ + Py_XDECREF( reinterpret_cast< PyObject * >(impl) ); +} + +Runtime & Runtime::operator = ( const Runtime & r ) +{ + PyRef temp( reinterpret_cast< PyObject * >(r.impl) ); + Py_XINCREF( temp.get() ); + Py_XDECREF( reinterpret_cast< PyObject * >(impl) ); + impl = r.impl; + return *this; +} + +PyRef Runtime::any2PyObject (const Any &a ) const + throw ( com::sun::star::script::CannotConvertException, + com::sun::star::lang::IllegalArgumentException, + RuntimeException) +{ + if( ! impl->cargo->valid ) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "pyuno runtime must be initialized before calling any2PyObject" )), + Reference< XInterface > () ); + } + + switch (a.getValueTypeClass ()) + { + case typelib_TypeClass_VOID: + { + Py_INCREF (Py_None); + return PyRef(Py_None); + } + case typelib_TypeClass_CHAR: + { + sal_Unicode c = *(sal_Unicode*)a.getValue(); + return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE ); + } + case typelib_TypeClass_BOOLEAN: + { + sal_Bool b; + a >>= b; + if (b) + return Py_True; + else + return Py_False; + } + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + { + long l; + a >>= l; + return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE ); + } + case typelib_TypeClass_UNSIGNED_LONG: + { + unsigned long l; + a >>= l; + return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE ); + } + case typelib_TypeClass_HYPER: + { + sal_Int64 l; + a >>= l; + return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE); + } + case typelib_TypeClass_UNSIGNED_HYPER: + { + sal_uInt64 l; + a >>= l; + return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE); + } + case typelib_TypeClass_FLOAT: + { + float f; + a >>= f; + return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE); + } + case typelib_TypeClass_DOUBLE: + { + double d; + a >>= d; + return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE); + } + case typelib_TypeClass_STRING: + { + OUString tmp_ostr; + a >>= tmp_ostr; + return ustring2PyUnicode( tmp_ostr ); + } + case typelib_TypeClass_TYPE: + { + Type t; + a >>= t; + OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US ); + return PyRef( + PyUNO_Type_new ( + o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this), + SAL_NO_ACQUIRE); + } + case typelib_TypeClass_ANY: + { + //I don't think this can happen. + Py_INCREF (Py_None); + return Py_None; + } + case typelib_TypeClass_ENUM: + { + long l = *(long *) a.getValue(); + TypeDescription desc( a.getValueType() ); + if( desc.is() ) + { + desc.makeComplete(); + typelib_EnumTypeDescription *pEnumDesc = + (typelib_EnumTypeDescription *) desc.get(); + for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ ) + { + if( pEnumDesc->pEnumValues[i] == l ) + { + OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US); + OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US); + return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE ); + } + } + } + OUStringBuffer buf; + buf.appendAscii( "Any carries enum " ); + buf.append( a.getValueType().getTypeName()); + buf.appendAscii( " with invalid value " ).append( l ); + throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > () ); + } + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_STRUCT: + { + PyRef excClass = getClass( a.getValueType().getTypeName(), *this ); + PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE); + PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE ); + PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() ); + PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.getAcquired() ), SAL_NO_ACQUIRE ); + if( ! ret.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " ); + buf.append( a.getValueType().getTypeName() ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + + if( typelib_TypeClass_EXCEPTION == a.getValueTypeClass() ) + { + // add the message in a standard python way ! + PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); + + // assuming that the Message is always the first member, wuuuu + void *pData = (void*)a.getValue(); + OUString message = *(OUString * )pData; + PyRef pymsg = ustring2PyString( message ); + PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() ); + // the exception base functions want to have an "args" tuple, + // which contains the message + PyObject_SetAttrString( ret.get(), "args", args.get() ); + } + return ret; + } + case typelib_TypeClass_SEQUENCE: + { + Sequence s; + + Sequence< sal_Int8 > byteSequence; + if( a >>= byteSequence ) + { + // byte sequence is treated in a special way because of peformance reasons + // @since 0.9.2 + return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE ); + } + else + { + Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter; + Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation; + tc->convertTo (a, ::getCppuType (&s)) >>= s; + PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE); + int i; + bool cont = true; + OUString errMsg; + try + { + for ( i = 0; i < s.getLength (); i++) + { + PyRef element; + element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() )); + OSL_ASSERT( element.is() ); + PyTuple_SetItem( tuple.get(), i, element.getAcquired() ); + } + } + catch( com::sun::star::uno::Exception & ) + { + for( ; i < s.getLength() ; i ++ ) + { + Py_INCREF( Py_None ); + PyTuple_SetItem( tuple.get(), i, Py_None ); + } + throw; + } + return tuple; + } + } + case typelib_TypeClass_INTERFACE: + { + Reference< XUnoTunnel > tunnel; + a >>= tunnel; + if( tunnel.is() ) + { + sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() ); + if( that ) + return ((Adapter*)that)->getWrappedObject(); + } + //This is just like the struct case: + return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE ); + } + default: + { + OUStringBuffer buf; + buf.appendAscii( "Unknonwn UNO type class " ); + buf.append( (sal_Int32 ) a.getValueTypeClass() ); + throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () ); + } + } + //We shouldn't be here... + return Py_None; +} + +static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o ) +{ + Sequence< Type > ret; + + PyRef method( PyObject_GetAttrString( o , "getTypes" ), SAL_NO_ACQUIRE ); + raiseInvocationTargetExceptionWhenNeeded( r ); + if( method.is() && PyCallable_Check( method.get() ) ) + { + PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE ); + raiseInvocationTargetExceptionWhenNeeded( r ); + if( types.is() && PyTuple_Check( types.get() ) ) + { + int size = PyTuple_Size( types.get() ); + ret.realloc( size ); + for( int i = 0 ; i < size ; i ++ ) + { + Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i)); + a >>= ret[i]; + } + } + } + return ret; +} + +Any Runtime::pyObject2Any ( const PyRef & source ) const + throw ( com::sun::star::uno::RuntimeException ) +{ + if( ! impl->cargo->valid ) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "pyuno runtime must be initialized before calling any2PyObject" )), + Reference< XInterface > () ); + } + + Any a; + PyObject *o = source.get(); + if( Py_None == o ) + { + + } + else if (PyInt_Check (o)) + { + if( o == Py_True ) + { + sal_Bool b = sal_True; + a = Any( &b, getBooleanCppuType() ); + } + else if ( o == Py_False ) + { + sal_Bool b = sal_False; + a = Any( &b, getBooleanCppuType() ); + } + else + { + sal_Int32 l = (sal_Int32) PyInt_AsLong( o ); + if( l < 128 && l >= -128 ) + { + sal_Int8 b = (sal_Int8 ) l; + a <<= b; + } + else if( l <= 0x7fff && l >= -0x8000 ) + { + sal_Int16 s = (sal_Int16) l; + a <<= s; + } + else + { + a <<= l; + } + } + } + else if (PyLong_Check (o)) + { + sal_Int64 l = (sal_Int64)PyLong_AsLong (o); + a <<= l; + } + else if (PyFloat_Check (o)) + { + double d = PyFloat_AsDouble (o); + a <<= d; + } + else if (PyString_Check (o)) + { + a <<= OUString(PyString_AsString (o), strlen( PyString_AsString(o)), + osl_getThreadTextEncoding()); + } + else if( PyUnicode_Check( o ) ) + { + OUString s; + if( sizeof( Py_UNICODE ) == 2 ) + { + s = OUString( (sal_Unicode *) PyUnicode_AsUnicode( o ), PyUnicode_GetSize( o ) ); + } + else if( sizeof( Py_UNICODE ) == 4 ) + { + // fixed for 0.9.2: OUString ctor expects the length of the byte array ! + s = OUString( (sal_Char * ) PyUnicode_AsUnicode( o ), + PyUnicode_GetSize( o ) * sizeof(Py_UNICODE), RTL_TEXTENCODING_UCS4 ); + } + else + { + OUStringBuffer buf; + buf.appendAscii( "pyuno string conversion routines can't deal with sizeof(Py_UNICODE) ==" ); + buf.append( (sal_Int32) sizeof( Py_UNICODE ) ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > ( ) ); + } + a <<= s; + } + else if (PyTuple_Check (o)) + { + Sequence s (PyTuple_Size (o)); + for (int i = 0; i < PyTuple_Size (o); i++) + { + s[i] = pyObject2Any (PyTuple_GetItem (o, i)); + } + a <<= s; + } + else + { + Runtime runtime; + if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) ) + { + PyRef str(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE); + Sequence< sal_Int8 > seq; + if( PyString_Check( str.get() ) ) + { + seq = Sequence ( + (sal_Int8*) PyString_AsString(str.get()), PyString_Size(str.get())); + } + a <<= seq; + } + else if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) ) + { + Type t = PyType2Type( o , runtime ); + a <<= t; + } + else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) ) + { + a = PyEnum2Enum( o, runtime ); + } + else if( isInstanceOfStructOrException( runtime, o ) ) + { + PyRef struc(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE); + PyUNO * obj = (PyUNO*)struc.get(); + Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY ); + if( holder.is( ) ) + a = holder->getMaterial(); + else + { + throw RuntimeException( + USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ), + Reference< XInterface > () ); + } + } + else if( PyObject_IsInstance( o, getPyUnoClass( runtime ).get() ) ) + { + PyUNO* o_pi; + o_pi = (PyUNO*) o; + if (o_pi->members->wrappedObject.getValueTypeClass () == + com::sun::star::uno::TypeClass_STRUCT || + o_pi->members->wrappedObject.getValueTypeClass () == + com::sun::star::uno::TypeClass_EXCEPTION) + { + Reference my_mh (o_pi->members->xInvocation, UNO_QUERY); + + if (!my_mh.is ()) + { + throw RuntimeException( + USTR_ASCII( "struct wrapper does not support XMaterialHolder" ), + Reference< XInterface > () ); + } + else + a = my_mh->getMaterial (); + } + else + { + a = o_pi->members->wrappedObject; + } + } + else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) ) + { + sal_Unicode c = PyChar2Unicode( o,runtime ); + a.setValue( &c, getCharCppuType( )); + } + else + { + Reference< XInterface > mappedObject; + + // can be improved in the 643 source tree with an improved + // invocation adapter factory + if( ! mappedObject.is() ) + { + Sequence< Type > interfaces = invokeGetTypes( *this, o ); + //implementsInterfaces( *this, o ); + if( interfaces.getLength() ) + { + Adapter *pAdapter = new Adapter( o , *this); + mappedObject = + getImpl()->cargo->xAdapterFactory->createAdapter( + pAdapter, interfaces ); + pAdapter->setUnoAdapter( mappedObject ); + } + } + + if( mappedObject.is() ) + { + a = com::sun::star::uno::makeAny( mappedObject ); + } + else + { + OUStringBuffer buf; + buf.appendAscii( "Couldn't convert " ); + PyRef reprString( PyObject_Str( o ) , SAL_NO_ACQUIRE ); + buf.appendAscii( PyString_AsString( reprString.get() ) ); + buf.appendAscii( " to a UNO type" ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); + } + } + } + return a; +} + + +PyThreadAttach::PyThreadAttach( PyInterpreterState *interp) + throw ( com::sun::star::uno::RuntimeException ) +{ + PYUNO_DEBUG_1( "PyThreadAttach ctor\n" ); + tstate = PyThreadState_New( interp ); + if( !tstate ) + throw RuntimeException( + OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ), + Reference< XInterface > () ); + PyEval_AcquireThread( tstate); +} + +PyThreadAttach::~PyThreadAttach() +{ + PYUNO_DEBUG_1( "PyThreadAttach dtor\n" ); + PyThreadState_Clear( tstate ); + PyEval_ReleaseThread( tstate ); + PyThreadState_Delete( tstate ); +} + +PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException ) +{ + PYUNO_DEBUG_1( "PyThreadDeattach ctor\n" ); + tstate = PyThreadState_Get(); + PyEval_ReleaseThread( tstate ); +} + + /** Acquires the global interpreter lock again + + */ +PyThreadDetach::~PyThreadDetach() +{ + PYUNO_DEBUG_1( "PyThreadDeattach dtor\n" ); + PyEval_AcquireThread( tstate ); +} + + +PyRef RuntimeCargo::getUnoModule() +{ + if( ! dictUnoModule.is() ) + { + dictUnoModule = importUnoModule(); + } + return dictUnoModule; +} +} diff --git a/pyuno/source/module/pyuno_type.cxx b/pyuno/source/module/pyuno_type.cxx new file mode 100644 index 000000000000..70dead2701cc --- /dev/null +++ b/pyuno/source/module/pyuno_type.cxx @@ -0,0 +1,460 @@ +/************************************************************************* + * + * $RCSfile: pyuno_type.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:58 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include "pyuno_impl.hxx" + +#include +#include + +#include + +using rtl::OString; +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; +using rtl::OStringBuffer; + +using com::sun::star::uno::TypeClass; +using com::sun::star::uno::Type; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Any; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Reference; +using com::sun::star::uno::TypeDescription; + +#define USTR_ASCII(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +namespace pyuno +{ +const char *typeClassToString( TypeClass t ) +{ + const char * ret = 0; + switch (t) + { + case com::sun::star::uno::TypeClass_VOID: + ret = "VOID"; break; + case com::sun::star::uno::TypeClass_CHAR: + ret = "CHAR"; break; + case com::sun::star::uno::TypeClass_BOOLEAN: + ret = "BOOLEAN"; break; + case com::sun::star::uno::TypeClass_BYTE: + ret = "BYTE"; break; + case com::sun::star::uno::TypeClass_SHORT: + ret = "SHORT"; break; + case com::sun::star::uno::TypeClass_UNSIGNED_SHORT: + ret = "UNSIGNED_SHORT"; break; + case com::sun::star::uno::TypeClass_LONG: + ret = "LONG"; break; + case com::sun::star::uno::TypeClass_UNSIGNED_LONG: + ret = "UNSIGNED_LONG"; + case com::sun::star::uno::TypeClass_HYPER: + ret = "HYPER"; break; + case com::sun::star::uno::TypeClass_UNSIGNED_HYPER: + ret = "UNSIGNED_HYPER"; break; + case com::sun::star::uno::TypeClass_FLOAT: + ret = "FLOAT"; break; + case com::sun::star::uno::TypeClass_DOUBLE: + ret = "DOUBLE"; break; + case com::sun::star::uno::TypeClass_STRING: + ret = "STRING"; break; + case com::sun::star::uno::TypeClass_TYPE: + ret = "TYPE"; break; + case com::sun::star::uno::TypeClass_ANY: + ret = "ANY";break; + case com::sun::star::uno::TypeClass_ENUM: + ret = "ENUM";break; + case com::sun::star::uno::TypeClass_STRUCT: + ret = "STRUCT"; break; + case com::sun::star::uno::TypeClass_EXCEPTION: + ret = "EXCEPTION"; break; + case com::sun::star::uno::TypeClass_SEQUENCE: + ret = "SEQUENCE"; + case com::sun::star::uno::TypeClass_INTERFACE: + ret = "INTERFACE"; break; + case com::sun::star::uno::TypeClass_TYPEDEF: + ret = "TYPEDEF"; break; + case com::sun::star::uno::TypeClass_UNION: + ret = "UNION"; break; + case com::sun::star::uno::TypeClass_ARRAY: + ret = "ARRAY"; break; + case com::sun::star::uno::TypeClass_SERVICE: + ret = "SERVICE"; break; + case com::sun::star::uno::TypeClass_MODULE: + ret = "MODULE"; break; + case com::sun::star::uno::TypeClass_INTERFACE_METHOD: + ret = "INTERFACE_METHOD"; break; + case com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE: + ret = "INTERFACE_ATTRIBUTE"; break; + default: + ret = "UNKNOWN"; break; + } + return ret; +} + +static PyRef getClass( const Runtime & r , const char * name) +{ + return PyRef( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*) name ) ); +} + +PyRef getTypeClass( const Runtime & r ) +{ + return getClass( r , "Type" ); +} + +PyRef getEnumClass( const Runtime & r ) +{ + return getClass( r , "Enum" ); +} + +PyRef getCharClass( const Runtime & r ) +{ + return getClass( r , "Char" ); +} + +PyRef getByteSequenceClass( const Runtime & r ) +{ + return getClass( r , "ByteSequence" ); +} + + +sal_Unicode PyChar2Unicode( PyObject *obj, const Runtime & r ) throw ( RuntimeException ) +{ + PyRef value( PyObject_GetAttrString( obj, "value" ), SAL_NO_ACQUIRE ); + if( ! PyUnicode_Check( value.get() ) ) + { + throw RuntimeException( + USTR_ASCII( "attribute value of uno.Char is not a unicode string" ), + Reference< XInterface > () ); + } + + if( PyUnicode_GetSize( value.get() ) < 1 ) + { + throw RuntimeException( + USTR_ASCII( "uno.Char contains an empty unicode string" ), + Reference< XInterface > () ); + } + + sal_Unicode c = (sal_Unicode)PyUnicode_AsUnicode( value.get() )[0]; + return c; +} + +Any PyEnum2Enum( PyObject *obj, const Runtime & r ) throw ( RuntimeException ) +{ + Any ret; + PyRef typeName( PyObject_GetAttrString( obj,"typeName" ), SAL_NO_ACQUIRE); + PyRef value( PyObject_GetAttrString( obj, "value" ), SAL_NO_ACQUIRE); + if( !PyString_Check( typeName.get() ) || ! PyString_Check( value.get() ) ) + { + throw RuntimeException( + USTR_ASCII( "attributes typeName and/or value of uno.Enum are not strings" ), + Reference< XInterface > () ); + } + + OUString strTypeName( OUString::createFromAscii( PyString_AsString( typeName.get() ) ) ); + char *stringValue = PyString_AsString( value.get() ); + + TypeDescription desc( strTypeName ); + if( desc.is() ) + { + if(desc.get()->eTypeClass != typelib_TypeClass_ENUM ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.checkEnum: " ).append(strTypeName).appendAscii( "is a " ); + buf.appendAscii( + typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass)); + buf.appendAscii( ", expected ENUM" ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () ); + } + + desc.makeComplete(); + + typelib_EnumTypeDescription *pEnumDesc = (typelib_EnumTypeDescription*) desc.get(); + int i = 0; + for( i = 0; i < pEnumDesc->nEnumValues ; i ++ ) + { + if( (*((OUString *)&pEnumDesc->ppEnumNames[i])).compareToAscii( stringValue ) == 0 ) + { + break; + } + } + if( i == pEnumDesc->nEnumValues ) + { + OUStringBuffer buf; + buf.appendAscii( "value " ).appendAscii( stringValue ).appendAscii( "is unknown in enum " ); + buf.appendAscii( PyString_AsString( typeName.get() ) ); + throw RuntimeException( buf.makeStringAndClear(), Reference () ); + } + ret = Any( &pEnumDesc->pEnumValues[i], desc.get()->pWeakRef ); + } + else + { + OUStringBuffer buf; + buf.appendAscii( "enum " ).appendAscii( PyString_AsString(typeName.get()) ).appendAscii( " is unknown" ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () ); + } + return ret; +} + + +Type PyType2Type( PyObject * o, const Runtime & r ) throw(RuntimeException ) +{ + PyRef pyName( PyObject_GetAttrString( o, "typeName" ), SAL_NO_ACQUIRE); + if( !PyString_Check( pyName.get() ) ) + { + throw RuntimeException( + USTR_ASCII( "type object does not have typeName property" ), + Reference< XInterface > () ); + } + + PyRef pyTC( PyObject_GetAttrString( o, "typeClass" ), SAL_NO_ACQUIRE ); + Any enumValue = PyEnum2Enum( pyTC.get(), r ); + + OUString name( OUString::createFromAscii( PyString_AsString( pyName.get() ) ) ); + TypeDescription desc( name ); + if( ! desc.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "type " ).append(name).appendAscii( " is unknown" ); + throw RuntimeException( + buf.makeStringAndClear(), Reference< XInterface > () ); + } + if( desc.get()->eTypeClass != (typelib_TypeClass) *(sal_Int32*)enumValue.getValue() ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.checkType: " ).append(name).appendAscii( " is a " ); + buf.appendAscii( typeClassToString( (TypeClass) desc.get()->eTypeClass) ); + buf.appendAscii( ", but type got construct with typeclass " ); + buf.appendAscii( typeClassToString( (TypeClass) *(sal_Int32*)enumValue.getValue() ) ); + throw RuntimeException( + buf.makeStringAndClear(), Reference< XInterface > () ); + } + return desc.get()->pWeakRef; +} + +PyObject *importToGlobal(PyObject *str, PyObject *dict, PyObject *target) +{ + // maybe a constant ? + PyObject *ret = 0; + OUString name = pyString2ustring(str); + try + { + Runtime runtime; + TypeDescription desc(name ); + desc.makeComplete(); + if( desc.is() ) + { + com::sun::star::uno::TypeClass tc = + (com::sun::star::uno::TypeClass)desc.get()->eTypeClass; + + PyRef typesModule( PyDict_GetItemString( dict, "unotypes" ) ); + if( ! typesModule.is() || ! PyModule_Check( typesModule.get() )) + { + typesModule = PyRef( PyModule_New( "unotypes" ), SAL_NO_ACQUIRE ); + Py_INCREF( typesModule.get() ); + PyDict_SetItemString( dict, "unotypes" , typesModule.get() ); + } + PyModule_AddObject( + typesModule.get(), + PyString_AsString( target ), + PyUNO_Type_new( PyString_AsString(str),tc,runtime ) ); + + if( com::sun::star::uno::TypeClass_EXCEPTION == tc || + com::sun::star::uno::TypeClass_STRUCT == tc ) + { + PyRef exc = getClass( name, runtime ); + PyDict_SetItem( dict, target, exc.getAcquired() ); + } + else if( com::sun::star::uno::TypeClass_ENUM == tc ) + { + // introduce all enums into the dictionary ! + typelib_EnumTypeDescription *pDesc = + (typelib_EnumTypeDescription *) desc.get(); + for( int i = 0 ; i < pDesc->nEnumValues; i ++ ) + { + OString enumElementName( + OUStringToOString( pDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US) ); + PyDict_SetItemString( + dict, (char*)enumElementName.getStr(), + PyUNO_Enum_new(PyString_AsString(str) , enumElementName.getStr(), runtime ) ); + } + } + Py_INCREF( Py_None ); + ret = Py_None; + } + else + { + Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(name); + if(a.hasValue()) + { + PyRef constant = runtime.any2PyObject( a ); + if( constant.is() ) + { + Py_INCREF( constant.get() ); + PyDict_SetItem( dict, target , constant.get()); + ret = constant.get(); + } + else + { + OStringBuffer buf; + buf.append( "constant " ).append(PyString_AsString(str)).append( " unknown" ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + } + } + else + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.imp unknown type " ); + buf.append( name ); + PyErr_SetString( + PyExc_RuntimeError, + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() ); + } + } + } + catch( com::sun::star::container::NoSuchElementException &e ) + { + OUStringBuffer buf; + buf.appendAscii( "pyuno.imp unknown type " ); + buf.append( name ); + PyErr_SetString( + PyExc_RuntimeError, + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() ); + } + catch( com::sun::star::script::CannotConvertException & e ) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); + } + catch( com::sun::star::lang::IllegalArgumentException & e ) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); + } + catch( RuntimeException &e ) + { + raisePyExceptionWithAny( com::sun::star::uno::makeAny( e )); + } + return ret; +} + +static PyObject* callCtor( const Runtime &r , const char * clazz, const PyRef & args ) +{ + PyRef code( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*)clazz ) ); + if( ! code.is() ) + { + OStringBuffer buf; + buf.append( "couldn't access uno." ); + buf.append( clazz ); + PyErr_SetString( PyExc_RuntimeError, buf.getStr() ); + return NULL; + } + PyRef instance( PyObject_CallObject( code.get(), args.get() ), SAL_NO_ACQUIRE); + Py_XINCREF( instance.get() ); + return instance.get(); + +} + + +PyObject *PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r ) +{ + PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE ); + PyTuple_SetItem( args.get() , 0 , PyString_FromString( enumBase ) ); + PyTuple_SetItem( args.get() , 1 , PyString_FromString( enumValue ) ); + + return callCtor( r, "Enum" , args ); +} + + +PyObject* PyUNO_Type_new (const char *typeName , TypeClass t , const Runtime &r ) +{ + // retrieve type object + PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE ); + + PyTuple_SetItem( args.get() , 0 , PyString_FromString( typeName ) ); + PyObject *typeClass = PyUNO_Enum_new( "com.sun.star.uno.TypeClass" , typeClassToString(t), r ); + if( ! typeClass ) + return NULL; + PyTuple_SetItem( args.get() , 1 , typeClass); + + return callCtor( r, "Type" , args ); +} + +PyObject* PyUNO_char_new ( sal_Unicode val , const Runtime &r ) +{ + // retrieve type object + PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); + + Py_UNICODE u[2]; + u[0] = val; + u[1] = 0; + PyTuple_SetItem( args.get() , 0 , PyUnicode_FromUnicode( u ,1) ); + + return callCtor( r, "Char" , args ); +} + +PyObject *PyUNO_ByteSequence_new( + const com::sun::star::uno::Sequence< sal_Int8 > &byteSequence, const Runtime &r ) +{ + PyRef str( + PyString_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()), + SAL_NO_ACQUIRE ); + PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); + PyTuple_SetItem( args.get() , 0 , str.getAcquired() ); + return callCtor( r, "ByteSequence" , args ); + +} +} diff --git a/pyuno/source/module/pyuno_util.cxx b/pyuno/source/module/pyuno_util.cxx new file mode 100644 index 000000000000..163a97caabe9 --- /dev/null +++ b/pyuno/source/module/pyuno_util.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * $RCSfile: pyuno_util.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jbu $ $Date: 2003-03-23 12:12:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source 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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Ralph Thomas + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Ralph Thomas, Joerg Budischewski + * + * + ************************************************************************/ +#include + +#include + +#include +#include + +#include + +#include "pyuno_impl.hxx" + + +using rtl::OUStringToOString; +using rtl::OUString; +using rtl::OString; +using rtl::OStringBuffer; +using rtl::OUStringBuffer; + + +using com::sun::star::uno::TypeDescription; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::Any; +using com::sun::star::uno::Type; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::TypeClass; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::XComponentContext; +using com::sun::star::lang::XSingleServiceFactory; +using com::sun::star::script::XTypeConverter; +using com::sun::star::beans::XMaterialHolder; + +#define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) +namespace pyuno +{ +PyRef ustring2PyUnicode( const OUString & str ) +{ + PyRef ret; + if( sizeof( Py_UNICODE ) == 2 ) + { + ret = PyRef( PyUnicode_FromUnicode( str.getStr(), str.getLength() ), SAL_NO_ACQUIRE ); + } + else if( sizeof( Py_UNICODE ) == 4 ) + { + // MUST BE TESTED !!! + printf( "not tested string conversion underway\n" ); + OString o = OUStringToOString( str, RTL_TEXTENCODING_UCS4 ); + ret = PyRef( PyUnicode_FromUnicode( (Py_UNICODE*)o.getStr(), o.getLength() ), SAL_NO_ACQUIRE ); + } + else + { + OUStringBuffer buf; + buf.appendAscii( "pyuno string conversion routines can't deal with sizeof(Py_UNICODE) ==" ); + buf.append( (sal_Int32) sizeof( Py_UNICODE ) ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > ( ) ); + } + return ret; +} + +PyRef ustring2PyString( const OUString &str ) +{ + OString o = OUStringToOString( str, osl_getThreadTextEncoding() ); + return PyRef( PyString_FromString( o.getStr() ), SAL_NO_ACQUIRE ); +} + +OUString pyString2ustring( PyObject *pystr ) +{ + OUString ret; + if( PyUnicode_Check( pystr ) ) + { + ret = OUString( (sal_Unicode * ) PyUnicode_AS_UNICODE( pystr ) ); + } + else + { + char *name = PyString_AsString(pystr ); + ret = OUString( name, strlen(name), osl_getThreadTextEncoding() ); + } + return ret; +} + +PyRef getObjectFromUnoModule( const Runtime &runtime, const char * func ) + throw ( RuntimeException ) +{ + PyRef object(PyDict_GetItemString( runtime.getImpl()->cargo->getUnoModule().get(), (char*)func ) ); + if( !object.is() ) + { + OUStringBuffer buf; + buf.appendAscii( "couldn't find core function " ); + buf.appendAscii( func ); + throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >()); + } + return object; +} + +} diff --git a/pyuno/source/module/uno.py b/pyuno/source/module/uno.py new file mode 100644 index 000000000000..592f04395f86 --- /dev/null +++ b/pyuno/source/module/uno.py @@ -0,0 +1,326 @@ +#************************************************************************* +# +# $RCSfile: uno.py,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2003-03-23 12:12:59 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source 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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Ralph Thomas +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Ralph Thomas, Joerg Budischewski +# +#************************************************************************* +import sys +from types import UnicodeType, StringTypes + +import pyuno +import __builtin__ + +# all functions and variables starting with a underscore (_) must be considered private +# and can be changed at any time. Don't use them +_g_ctx = pyuno.getComponentContext( ) +_g_delegatee = __builtin__.__dict__["__import__"] + +def getComponentContext(): + """ returns the UNO component context, that was used to initialize the python runtime. + """ + return _g_ctx + +def getConstantByName( constant ): + "Looks up the value of a idl constant by giving its explicit name" + return pyuno.getConstantByName( constant ) + +def getTypeByName( typeName): + """ returns a uno.Type instance of the type given by typeName. In case the + type does not exist, a com.sun.star.uno.RuntimeException is raised. + """ + return pyuno.getTypeByName( typeName ) + +def createUnoStruct( typeName, *args ): + """creates a uno struct or exception given by typeName. The parameter args may + 1) be empty. In this case, you get a default constructed uno structure. + ( e.g. createUnoStruct( "com.sun.star.uno.Exception" ) ) + 2) be a sequence with exactly one element, that contains an instance of typeName. + In this case, a copy constructed instance of typeName is returned + ( e.g. createUnoStruct( "com.sun.star.uno.Exception" , e ) ) + 3) be a sequence, where the length of the sequence must match the number of + elements within typeName (e.g. + createUnoStruct( "com.sun.star.uno.Exception", "foo error" , self) ). The + elements with in the sequence must match the type of each struct element, + otherwise an exception is thrown. + """ + return getClass(typeName)( *args ) + +def getClass( typeName ): + """returns the class of a concrete uno exception, struct or interface + """ + return pyuno.getClass(typeName) + +def isInterface( obj ): + """returns true, when obj is a class of a uno interface""" + return pyuno.isInterface( obj ) + +def generateUuid(): + "returns a 16 byte sequence containing a newly generated uuid or guid, see rtl/uuid.h " + return pyuno.generateUuid() + +def systemPathToFileUrl( systemPath ): + "returns a file-url for the given system path" + return pyuno.systemPathToFileUrl( systemPath ) + +def fileUrlToSystemPath( url ): + "returns a system path (determined by the system, the python interpreter is running on)" + return pyuno.fileUrlToSystemPath( url ) + +def absolutize( path, relativeUrl ): + "returns an absolute file url from the given urls" + return pyuno.absolutize( path, relativeUrl ) + +class Enum: + "Represents a UNO idl enum, use an instance of this class to explicitly pass a boolean to UNO" + #typeName the name of the enum as a string + #value the actual value of this enum as a string + def __init__(self,typeName, value): + self.typeName = typeName + self.value = value + pyuno.checkEnum( self ) + + def __repr__(self): + return "" % (self.typeName, self.value) + + def __eq__(self, that): + if not isinstance(that, Enum): + return 0 + return (self.typeName == that.typeName ) and ( self.value == that.value) + +class Type: + "Represents a UNO type, use an instance of this class to explicitly pass a boolean to UNO" +# typeName # Name of the UNO type +# typeClass # python Enum of TypeClass, see com/sun/star/uno/TypeClass.idl + def __init__(self, typeName, typeClass): + self.typeName = typeName + self.typeClass = typeClass + pyuno.checkType(self) + def __repr__(self): + return "" % (self.typeName, self.typeClass) + + def __eq__(self, that): + if not isinstance(that, Type): + return 0 + return self.typeClass == that.typeClass and self.typeName == that.typeName + + def __hash__(self): + return self.typeName.__hash__() + +class Bool(object): + """Represents a UNO boolean, use an instance of this class to explicitly + pass a boolean to UNO. + Note: This class is deprecated. Use python's True and False directly instead + """ + def __new__(cls, value): + if isinstance( value, type("") ) and value == "true": + return True + elif isinstance( value, type("") ) and value == "false": + return False + else: + if value: + return True + else: + return False + +class Char: + "Represents a UNO char, use an instance of this class to explicitly pass a char to UNO" + # @param value pass a Unicode string with length 1 + def __init__(self,value): + assert isinstance(value, UnicodeType) + assert len(value) == 1 + self.value=value + + def __repr__(self): + return "" & (self.value) + + def __eq__(self, that): + if isinstance(that, StringTypes): + if len(that) > 1: + return 0 + return self.value == that[0] + elif isinstance(that, Char): + return self.value == that.value + return 0 + +class ByteSequence: + def __init__(self,value): + if isinstance( value, StringTypes ): + self.value = value + elif isinstance( value, ByteSequence ): + self.value = value.value + else: + raise TypeError( "expected string or bytesequence" ) + + def __repr__( self): + return "" % (self.value ) + + def __eq__( self,that): + if isinstance( that, ByteSequence): + return self.value == that.value + elif isinstance( that, StringTypes ): + return self.value == that + raise TypeError( "expected string or bytesequence for comparison" ) + + def __len__( self ): + return len( self.value ) + + def __getitem__( self, index ): + return self.value[index] + + def __iter__( self ): + return self.value.__iter__() + + def __add__( self , b ): + if isinstance( b, StringTypes ): + return ByteSequence( self.value + b ) + elif isinstance( b, ByteSequence ): + return ByteSequence( self.value + b.value ) + raise TypeError( "expected string or ByteSequence as operand" ) + + def __hash__( self ): + return self.value.hash() + +#--------------------------------------------------------------------------------------- +# don't use any functions beyond this point, private section, likely to change +#--------------------------------------------------------------------------------------- +def _uno_import( name, *optargs ): + try: +# print "optargs = " + repr(optargs) + if len(optargs) == 0: + return _g_delegatee( name ) + #print _g_delegatee + return _g_delegatee( name, *optargs ) + except ImportError: + if len(optargs) != 3 or not optargs[2]: + raise + globals = optargs[0] + locals = optargs[1] + fromlist = optargs[2] + modnames = name.split( "." ) + mod = None + d = sys.modules + for x in modnames: + if d.has_key(x): + mod = d[x] + else: + mod = pyuno.__class__(x) # How to create a module ?? + d = mod.__dict__ + + RuntimeException = pyuno.getClass( "com.sun.star.uno.RuntimeException" ) + for x in fromlist: + if not d.has_key(x): + if x.startswith( "typeOf" ): + try: + d[x] = pyuno.getTypeByName( name + "." + x[6:len(x)] ) + except RuntimeException,e: + raise ImportError( "type " + name + "." + x[6:len(x)] +" is unknown" ) + else: + try: + # check for structs, exceptions or interfaces + d[x] = pyuno.getClass( name + "." + x ) + except RuntimeException,e: + # check for enums + try: + d[x] = Enum( name , x ) + except RuntimeException,e2: + # check for constants + try: + d[x] = getConstantByName( name + "." + x ) + except RuntimeException,e3: + # no known uno type ! + raise ImportError( "type "+ name + "." +x + " is unknown" ) + return mod + +# hook into the __import__ chain +__builtin__.__dict__["__import__"] = _uno_import + +# private function, don't use +def _impl_extractName(name): + r = range (len(name)-1,0,-1) + for i in r: + if name[i] == ".": + name = name[i+1:len(name)] + break + return name + +# private, referenced from the pyuno shared library +def _uno_struct__init__(self,*args): + if len(args) == 1 and hasattr(args[0], "__class__") and args[0].__class__ == self.__class__ : + self.__dict__["value"] = args[0] + else: + self.__dict__["value"] = pyuno._createUnoStructHelper(self.__class__.__pyunostruct__,args) + +# private, referenced from the pyuno shared library +def _uno_struct__getattr__(self,name): + return __builtin__.getattr(self.__dict__["value"],name) + +# private, referenced from the pyuno shared library +def _uno_struct__setattr__(self,name,value): + return __builtin__.setattr(self.__dict__["value"],name,value) + +# private, referenced from the pyuno shared library +def _uno_struct__repr__(self): + return repr(self.__dict__["value"]) + +def _uno_struct__str__(self): + return str(self.__dict__["value"]) + +# private, referenced from the pyuno shared library +def _uno_struct__eq__(self,cmp): + if hasattr(cmp,"value"): + return self.__dict__["value"] == cmp.__dict__["value"] + return 0 + diff --git a/pyuno/source/module/unohelper.py b/pyuno/source/module/unohelper.py new file mode 100644 index 000000000000..fb792df239e6 --- /dev/null +++ b/pyuno/source/module/unohelper.py @@ -0,0 +1,214 @@ +#************************************************************************* +# +# $RCSfile: unohelper.py,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2003-03-23 12:12:59 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source 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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Ralph Thomas +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Ralph Thomas, Joerg Budischewski +# +#************************************************************************* +import uno +import pyuno + +from com.sun.star.lang import XTypeProvider, XSingleComponentFactory, XServiceInfo +from com.sun.star.uno import RuntimeException + +def createSingleServiceFactory( clazz, implementationName, serviceNames ): + return _FactoryHelper_( clazz, implementationName, serviceNames ) + +class _ImplementationHelperEntry: + def __init__(self, ctor,serviceNames): + self.ctor = ctor + self.serviceNames = serviceNames + +class ImplementationHelper: + def __init__(self): + self.impls = {} + + def addImplementation( self, ctor, implementationName, serviceNames ): + self.impls[implementationName] = _ImplementationHelperEntry(ctor,serviceNames) + + def writeRegistryInfo( self, regKey, smgr ): + for i in self.impls.items(): + keyName = "/"+ i[0] + "/UNO/SERVICES" + key = regKey.createKey( keyName ) + for serviceName in i[1].serviceNames: + key.createKey( serviceName ) + return 1 + + def getComponentFactory( self, implementationName , regKey, smgr ): + entry = self.impls.get( implementationName, None ) + if entry == None: + raise RuntimeException( implementationName + " is unknown" , None ) + return createSingleServiceFactory( entry.ctor, implementationName, entry.serviceNames ) + + def getSupportedServiceNames( self, implementationName ): + entry = self.impls.get( implementationName, None ) + if entry == None: + raise RuntimeException( implementationName + " is unknown" , None ) + return entry.serviceNames + + def supportsService( self, implementationName, serviceName ): + entry = self.impls.get( implementationName,None ) + if entry == None: + raise RuntimeException( implementationName + " is unknown", None ) + return serviceName in entry.serviceNames + + +class ImplementationEntry: + def __init__(self, implName, supportedServices, clazz ): + self.implName = implName + self.supportedServices = supportedServices + self.clazz = clazz + +def writeRegistryInfoHelper( smgr, regKey, seqEntries ): + for entry in seqEntries: + keyName = "/"+ entry.implName + "/UNO/SERVICES" + key = regKey.createKey( keyName ) + for serviceName in entry.supportedServices: + key.createKey( serviceName ) + +def systemPathToFileUrl( systemPath ): + "returns a file-url for the given system path" + return pyuno.systemPathToFileUrl( systemPath ) + +def fileUrlToSystemPath( url ): + "returns a system path (determined by the system, the python interpreter is running on)" + return pyuno.fileUrlToSystemPath( url ) + +def absolutize( path, relativeUrl ): + "returns an absolute file url from the given urls" + return pyuno.absolutize( path, relativeUrl ) + +def getComponentFactoryHelper( implementationName, smgr, regKey, seqEntries ): + for x in seqEntries: + if x.implName == implementationName: + return createSingleServiceFactory( x.clazz, implementationName, x.supportedServices ) + +def addComponentsToContext( toBeExtendedContext, contextRuntime, componentUrls, loaderName ): + smgr = contextRuntime.ServiceManager + loader = smgr.createInstanceWithContext( loaderName, contextRuntime ) + implReg = smgr.createInstanceWithContext( "com.sun.star.registry.ImplementationRegistration",contextRuntime) + + # create a temporary registry + for componentUrl in componentUrls: + reg = smgr.createInstanceWithContext( "com.sun.star.registry.SimpleRegistry", contextRuntime ) + reg.open( "", 0, 1 ) + implReg.registerImplementation( loaderName,componentUrl, reg ) + rootKey = reg.getRootKey() + implementationKey = rootKey.openKey( "IMPLEMENTATIONS" ) + implNames = implementationKey.getKeyNames() + extSMGR = toBeExtendedContext.ServiceManager + for x in implNames: + fac = loader.activate( max(x.split("/")),"",componentUrl,rootKey) + extSMGR.insert( fac ) + reg.close() + +# never shrinks ! +_g_typeTable = {} +def _unohelper_getHandle( self): + ret = None + if _g_typeTable.has_key( self.__class__ ): + ret = _g_typeTable[self.__class__] + else: + names = {} + traverse = list(self.__class__.__bases__) + while len( traverse ) > 0: + item = traverse.pop() + bases = item.__bases__ + if uno.isInterface( item ): + names[item.__pyunointerface__] = None + elif len(bases) > 0: + # the "else if", because we only need the most derived interface + traverse = traverse + list(bases)# + + lst = names.keys() + types = [] + for x in lst: + t = uno.getTypeByName( x ) + types.append( t ) + + ret = tuple(types) , uno.generateUuid() + _g_typeTable[self.__class__] = ret + return ret + +class Base(XTypeProvider): + def getTypes( self ): + return _unohelper_getHandle( self )[0] + def getImplementationId(self): + return _unohelper_getHandle( self )[1] + +# ------------------------------------------------- +# implementation details +# ------------------------------------------------- +class _FactoryHelper_( XSingleComponentFactory, XServiceInfo, Base ): + def __init__( self, clazz, implementationName, serviceNames ): + self.clazz = clazz + self.implementationName = implementationName + self.serviceNames = serviceNames + + def getImplementationName( self ): + return self.implementationName + + def supportsService( self, ServiceName ): + return ServiceName in serviceNames + + def getSupportedServiceNames( self ): + return self.serviceNames + + def createInstanceWithContext( self, context ): + return self.clazz( context ) + + def createInstanceWithArgumentsAndContext( self, args, context ): + return self.clazz( context, *args ) + -- cgit v1.2.3