1*67c7d1c1SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*67c7d1c1SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*67c7d1c1SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*67c7d1c1SAndrew Rist * distributed with this work for additional information 6*67c7d1c1SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*67c7d1c1SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*67c7d1c1SAndrew Rist * "License"); you may not use this file except in compliance 9*67c7d1c1SAndrew Rist * with the License. You may obtain a copy of the License at 10*67c7d1c1SAndrew Rist * 11*67c7d1c1SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*67c7d1c1SAndrew Rist * 13*67c7d1c1SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*67c7d1c1SAndrew Rist * software distributed under the License is distributed on an 15*67c7d1c1SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*67c7d1c1SAndrew Rist * KIND, either express or implied. See the License for the 17*67c7d1c1SAndrew Rist * specific language governing permissions and limitations 18*67c7d1c1SAndrew Rist * under the License. 19*67c7d1c1SAndrew Rist * 20*67c7d1c1SAndrew Rist *************************************************************/ 21*67c7d1c1SAndrew Rist 22*67c7d1c1SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "pyuno_impl.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <osl/thread.h> 27cdf0e10cSrcweir #include <osl/module.h> 28cdf0e10cSrcweir #include <osl/process.h> 29cdf0e10cSrcweir #include <rtl/strbuf.hxx> 30cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 31cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 32cdf0e10cSrcweir #include <locale.h> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <typelib/typedescription.hxx> 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include <com/sun/star/beans/XMaterialHolder.hpp> 37cdf0e10cSrcweir 38cdf0e10cSrcweir using rtl::OUString; 39cdf0e10cSrcweir using rtl::OUStringToOString; 40cdf0e10cSrcweir using rtl::OUStringBuffer; 41cdf0e10cSrcweir using rtl::OStringBuffer; 42cdf0e10cSrcweir using rtl::OString; 43cdf0e10cSrcweir 44cdf0e10cSrcweir using com::sun::star::uno::Reference; 45cdf0e10cSrcweir using com::sun::star::uno::XInterface; 46cdf0e10cSrcweir using com::sun::star::uno::Any; 47cdf0e10cSrcweir using com::sun::star::uno::TypeDescription; 48cdf0e10cSrcweir using com::sun::star::uno::Sequence; 49cdf0e10cSrcweir using com::sun::star::uno::Type; 50cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY; 51cdf0e10cSrcweir using com::sun::star::uno::RuntimeException; 52cdf0e10cSrcweir using com::sun::star::uno::XComponentContext; 53cdf0e10cSrcweir using com::sun::star::lang::XSingleServiceFactory; 54cdf0e10cSrcweir using com::sun::star::lang::XUnoTunnel; 55cdf0e10cSrcweir using com::sun::star::reflection::XIdlReflection; 56cdf0e10cSrcweir using com::sun::star::script::XTypeConverter; 57cdf0e10cSrcweir using com::sun::star::script::XInvocationAdapterFactory2; 58cdf0e10cSrcweir using com::sun::star::script::XInvocation; 59cdf0e10cSrcweir using com::sun::star::beans::XMaterialHolder; 60cdf0e10cSrcweir using com::sun::star::beans::XIntrospection; 61cdf0e10cSrcweir 62cdf0e10cSrcweir namespace pyuno 63cdf0e10cSrcweir { 64cdf0e10cSrcweir #define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) 65cdf0e10cSrcweir 66cdf0e10cSrcweir static PyTypeObject RuntimeImpl_Type = 67cdf0e10cSrcweir { 68cdf0e10cSrcweir PyObject_HEAD_INIT (&PyType_Type) 69cdf0e10cSrcweir 0, 70cdf0e10cSrcweir const_cast< char * >("pyuno_runtime"), 71cdf0e10cSrcweir sizeof (RuntimeImpl), 72cdf0e10cSrcweir 0, 73cdf0e10cSrcweir (destructor) RuntimeImpl::del, 74cdf0e10cSrcweir (printfunc) 0, 75cdf0e10cSrcweir (getattrfunc) 0, 76cdf0e10cSrcweir (setattrfunc) 0, 77cdf0e10cSrcweir (cmpfunc) 0, 78cdf0e10cSrcweir (reprfunc) 0, 79cdf0e10cSrcweir 0, 80cdf0e10cSrcweir 0, 81cdf0e10cSrcweir 0, 82cdf0e10cSrcweir (hashfunc) 0, 83cdf0e10cSrcweir (ternaryfunc) 0, 84cdf0e10cSrcweir (reprfunc) 0, 85cdf0e10cSrcweir (getattrofunc)0, 86cdf0e10cSrcweir (setattrofunc)0, 87cdf0e10cSrcweir NULL, 88cdf0e10cSrcweir 0, 89cdf0e10cSrcweir NULL, 90cdf0e10cSrcweir (traverseproc)0, 91cdf0e10cSrcweir (inquiry)0, 92cdf0e10cSrcweir (richcmpfunc)0, 93cdf0e10cSrcweir 0, 94cdf0e10cSrcweir (getiterfunc)0, 95cdf0e10cSrcweir (iternextfunc)0, 96cdf0e10cSrcweir NULL, 97cdf0e10cSrcweir NULL, 98cdf0e10cSrcweir NULL, 99cdf0e10cSrcweir NULL, 100cdf0e10cSrcweir NULL, 101cdf0e10cSrcweir (descrgetfunc)0, 102cdf0e10cSrcweir (descrsetfunc)0, 103cdf0e10cSrcweir 0, 104cdf0e10cSrcweir (initproc)0, 105cdf0e10cSrcweir (allocfunc)0, 106cdf0e10cSrcweir (newfunc)0, 107cdf0e10cSrcweir (freefunc)0, 108cdf0e10cSrcweir (inquiry)0, 109cdf0e10cSrcweir NULL, 110cdf0e10cSrcweir NULL, 111cdf0e10cSrcweir NULL, 112cdf0e10cSrcweir NULL, 113cdf0e10cSrcweir NULL, 114cdf0e10cSrcweir (destructor)0 115cdf0e10cSrcweir #if PY_VERSION_HEX >= 0x02060000 116cdf0e10cSrcweir , 0 117cdf0e10cSrcweir #endif 118cdf0e10cSrcweir }; 119cdf0e10cSrcweir 120cdf0e10cSrcweir /*---------------------------------------------------------------------- 121cdf0e10cSrcweir Runtime implementation 122cdf0e10cSrcweir -----------------------------------------------------------------------*/ 123cdf0e10cSrcweir static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl ) 124cdf0e10cSrcweir throw ( com::sun::star::uno::RuntimeException ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir PyThreadState * state = PyThreadState_Get(); 127cdf0e10cSrcweir if( ! state ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 130cdf0e10cSrcweir "python global interpreter must be held (thread must be attached)" )), 131cdf0e10cSrcweir Reference< XInterface > () ); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__")))); 135cdf0e10cSrcweir 136cdf0e10cSrcweir if( ! globalDict.is() ) // FATAL ! 137cdf0e10cSrcweir { 138cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 139cdf0e10cSrcweir "can't find __main__ module" )), Reference< XInterface > ()); 140cdf0e10cSrcweir } 141cdf0e10cSrcweir runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" ); 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir static PyRef importUnoModule( ) throw ( RuntimeException ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir PyRef globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__")))); 147cdf0e10cSrcweir // import the uno module 148cdf0e10cSrcweir PyRef module( PyImport_ImportModule( const_cast< char * >("uno") ), SAL_NO_ACQUIRE ); 149cdf0e10cSrcweir if( PyErr_Occurred() ) 150cdf0e10cSrcweir { 151cdf0e10cSrcweir PyRef excType, excValue, excTraceback; 152cdf0e10cSrcweir PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback); 153cdf0e10cSrcweir PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE ); 154cdf0e10cSrcweir 155cdf0e10cSrcweir OUStringBuffer buf; 156cdf0e10cSrcweir buf.appendAscii( "python object raised an unknown exception (" ); 157cdf0e10cSrcweir PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE ); 158cdf0e10cSrcweir buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" ); 159cdf0e10cSrcweir buf.appendAscii( PyString_AsString( str.get() ) ); 160cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); 161cdf0e10cSrcweir } 162cdf0e10cSrcweir PyRef dict( PyModule_GetDict( module.get() ) ); 163cdf0e10cSrcweir return dict; 164cdf0e10cSrcweir } 165cdf0e10cSrcweir 166cdf0e10cSrcweir static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile ) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir *pLevel = LogLevel::NONE; 169cdf0e10cSrcweir *ppFile = 0; 170cdf0e10cSrcweir OUString fileName; 171cdf0e10cSrcweir osl_getModuleURLFromFunctionAddress( 172cdf0e10cSrcweir reinterpret_cast< oslGenericFunction >(readLoggingConfig), 173cdf0e10cSrcweir (rtl_uString **) &fileName ); 174cdf0e10cSrcweir fileName = OUString( fileName.getStr(), fileName.lastIndexOf( '/' )+1 ); 175cdf0e10cSrcweir fileName += OUString::createFromAscii( SAL_CONFIGFILE("pyuno") ); 176cdf0e10cSrcweir rtl::Bootstrap bootstrapHandle( fileName ); 177cdf0e10cSrcweir 178cdf0e10cSrcweir OUString str; 179cdf0e10cSrcweir if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGLEVEL" ), str ) ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir if( str.equalsAscii( "NONE" ) ) 182cdf0e10cSrcweir *pLevel = LogLevel::NONE; 183cdf0e10cSrcweir else if( str.equalsAscii( "CALL" ) ) 184cdf0e10cSrcweir *pLevel = LogLevel::CALL; 185cdf0e10cSrcweir else if( str.equalsAscii( "ARGS" ) ) 186cdf0e10cSrcweir *pLevel = LogLevel::ARGS; 187cdf0e10cSrcweir else 188cdf0e10cSrcweir { 189cdf0e10cSrcweir fprintf( stderr, "unknown loglevel %s\n", 190cdf0e10cSrcweir OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() ); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir } 193cdf0e10cSrcweir if( *pLevel > LogLevel::NONE ) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir *ppFile = stdout; 196cdf0e10cSrcweir if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str ) ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir if( str.equalsAscii( "stdout" ) ) 199cdf0e10cSrcweir *ppFile = stdout; 200cdf0e10cSrcweir else if( str.equalsAscii( "stderr" ) ) 201cdf0e10cSrcweir *ppFile = stderr; 202cdf0e10cSrcweir else 203cdf0e10cSrcweir { 204cdf0e10cSrcweir oslProcessInfo data; 205cdf0e10cSrcweir data.Size = sizeof( data ); 206cdf0e10cSrcweir osl_getProcessInfo( 207cdf0e10cSrcweir 0 , osl_Process_IDENTIFIER , &data ); 208cdf0e10cSrcweir osl_getSystemPathFromFileURL( str.pData, &str.pData); 209cdf0e10cSrcweir OString o = OUStringToOString( str, osl_getThreadTextEncoding() ); 210cdf0e10cSrcweir o += "."; 211cdf0e10cSrcweir o += OString::valueOf( (sal_Int32)data.Ident ); 212cdf0e10cSrcweir 213cdf0e10cSrcweir *ppFile = fopen( o.getStr() , "w" ); 214cdf0e10cSrcweir if ( *ppFile ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir // do not buffer (useful if e.g. analyzing a crash) 217cdf0e10cSrcweir setvbuf( *ppFile, 0, _IONBF, 0 ); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir else 220cdf0e10cSrcweir { 221cdf0e10cSrcweir fprintf( stderr, "couldn't create file %s\n", 222cdf0e10cSrcweir OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() ); 223cdf0e10cSrcweir 224cdf0e10cSrcweir } 225cdf0e10cSrcweir } 226cdf0e10cSrcweir } 227cdf0e10cSrcweir } 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir /*------------------------------------------------------------------- 231cdf0e10cSrcweir RuntimeImpl implementations 232cdf0e10cSrcweir *-------------------------------------------------------------------*/ 233cdf0e10cSrcweir PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx ) 234cdf0e10cSrcweir throw( com::sun::star::uno::RuntimeException ) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type); 237cdf0e10cSrcweir if( ! me ) 238cdf0e10cSrcweir throw RuntimeException( 239cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ), 240cdf0e10cSrcweir Reference< XInterface > () ); 241cdf0e10cSrcweir me->cargo = 0; 242cdf0e10cSrcweir // must use a different struct here, as the PyObject_New 243cdf0e10cSrcweir // makes C++ unusable 244cdf0e10cSrcweir RuntimeCargo *c = new RuntimeCargo(); 245cdf0e10cSrcweir readLoggingConfig( &(c->logLevel) , &(c->logFile) ); 246cdf0e10cSrcweir log( c, LogLevel::CALL, "Instantiating pyuno bridge" ); 247cdf0e10cSrcweir 248cdf0e10cSrcweir c->valid = 1; 249cdf0e10cSrcweir c->xContext = ctx; 250cdf0e10cSrcweir c->xInvocation = Reference< XSingleServiceFactory > ( 251cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 252cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ), 253cdf0e10cSrcweir ctx ), 254cdf0e10cSrcweir UNO_QUERY ); 255cdf0e10cSrcweir if( ! c->xInvocation.is() ) 256cdf0e10cSrcweir throw RuntimeException( 257cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ), 258cdf0e10cSrcweir Reference< XInterface > () ); 259cdf0e10cSrcweir 260cdf0e10cSrcweir c->xTypeConverter = Reference< XTypeConverter > ( 261cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 262cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ), 263cdf0e10cSrcweir ctx ), 264cdf0e10cSrcweir UNO_QUERY ); 265cdf0e10cSrcweir if( ! c->xTypeConverter.is() ) 266cdf0e10cSrcweir throw RuntimeException( 267cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )), 268cdf0e10cSrcweir Reference< XInterface > () ); 269cdf0e10cSrcweir 270cdf0e10cSrcweir c->xCoreReflection = Reference< XIdlReflection > ( 271cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 272cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ), 273cdf0e10cSrcweir ctx ), 274cdf0e10cSrcweir UNO_QUERY ); 275cdf0e10cSrcweir if( ! c->xCoreReflection.is() ) 276cdf0e10cSrcweir throw RuntimeException( 277cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )), 278cdf0e10cSrcweir Reference< XInterface > () ); 279cdf0e10cSrcweir 280cdf0e10cSrcweir c->xAdapterFactory = Reference< XInvocationAdapterFactory2 > ( 281cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 282cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ), 283cdf0e10cSrcweir ctx ), 284cdf0e10cSrcweir UNO_QUERY ); 285cdf0e10cSrcweir if( ! c->xAdapterFactory.is() ) 286cdf0e10cSrcweir throw RuntimeException( 287cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )), 288cdf0e10cSrcweir Reference< XInterface > () ); 289cdf0e10cSrcweir 290cdf0e10cSrcweir c->xIntrospection = Reference< XIntrospection > ( 291cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 292cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ), 293cdf0e10cSrcweir ctx ), 294cdf0e10cSrcweir UNO_QUERY ); 295cdf0e10cSrcweir if( ! c->xIntrospection.is() ) 296cdf0e10cSrcweir throw RuntimeException( 297cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )), 298cdf0e10cSrcweir Reference< XInterface > () ); 299cdf0e10cSrcweir 300cdf0e10cSrcweir Any a = ctx->getValueByName(OUString( 301cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) ); 302cdf0e10cSrcweir a >>= c->xTdMgr; 303cdf0e10cSrcweir if( ! c->xTdMgr.is() ) 304cdf0e10cSrcweir throw RuntimeException( 305cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )), 306cdf0e10cSrcweir Reference< XInterface > () ); 307cdf0e10cSrcweir 308cdf0e10cSrcweir me->cargo =c; 309cdf0e10cSrcweir return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE ); 310cdf0e10cSrcweir } 311cdf0e10cSrcweir 312cdf0e10cSrcweir void stRuntimeImpl::del(PyObject* self) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self ); 315cdf0e10cSrcweir if( me->cargo->logFile ) 316cdf0e10cSrcweir fclose( me->cargo->logFile ); 317cdf0e10cSrcweir delete me->cargo; 318cdf0e10cSrcweir PyObject_Del (self); 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir 322cdf0e10cSrcweir void Runtime::initialize( const Reference< XComponentContext > & ctx ) 323cdf0e10cSrcweir throw ( RuntimeException ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir PyRef globalDict, runtime; 326cdf0e10cSrcweir getRuntimeImpl( globalDict , runtime ); 327cdf0e10cSrcweir RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); 328cdf0e10cSrcweir 329cdf0e10cSrcweir if( runtime.is() && impl->cargo->valid ) 330cdf0e10cSrcweir { 331cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 332cdf0e10cSrcweir "pyuno runtime has already been initialized before" ) ), 333cdf0e10cSrcweir Reference< XInterface > () ); 334cdf0e10cSrcweir } 335cdf0e10cSrcweir PyRef keep( RuntimeImpl::create( ctx ) ); 336cdf0e10cSrcweir PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() ); 337cdf0e10cSrcweir Py_XINCREF( keep.get() ); 338cdf0e10cSrcweir } 339cdf0e10cSrcweir 340cdf0e10cSrcweir 341cdf0e10cSrcweir bool Runtime::isInitialized() throw ( RuntimeException ) 342cdf0e10cSrcweir { 343cdf0e10cSrcweir PyRef globalDict, runtime; 344cdf0e10cSrcweir getRuntimeImpl( globalDict , runtime ); 345cdf0e10cSrcweir RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); 346cdf0e10cSrcweir return runtime.is() && impl->cargo->valid; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir 349cdf0e10cSrcweir void Runtime::finalize() throw (RuntimeException) 350cdf0e10cSrcweir { 351cdf0e10cSrcweir PyRef globalDict, runtime; 352cdf0e10cSrcweir getRuntimeImpl( globalDict , runtime ); 353cdf0e10cSrcweir RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); 354cdf0e10cSrcweir if( !runtime.is() || ! impl->cargo->valid ) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 357cdf0e10cSrcweir "pyuno bridge must have been initialized before finalizing" )), 358cdf0e10cSrcweir Reference< XInterface > () ); 359cdf0e10cSrcweir } 360cdf0e10cSrcweir impl->cargo->valid = false; 361cdf0e10cSrcweir impl->cargo->xInvocation.clear(); 362cdf0e10cSrcweir impl->cargo->xContext.clear(); 363cdf0e10cSrcweir impl->cargo->xTypeConverter.clear(); 364cdf0e10cSrcweir } 365cdf0e10cSrcweir 366cdf0e10cSrcweir Runtime::Runtime() throw( RuntimeException ) 367cdf0e10cSrcweir : impl( 0 ) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir PyRef globalDict, runtime; 370cdf0e10cSrcweir getRuntimeImpl( globalDict , runtime ); 371cdf0e10cSrcweir if( ! runtime.is() ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir throw RuntimeException( 374cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, " 375cdf0e10cSrcweir "(the pyuno.bootstrap needs to be called before using any uno classes)")), 376cdf0e10cSrcweir Reference< XInterface > () ); 377cdf0e10cSrcweir } 378cdf0e10cSrcweir impl = reinterpret_cast< RuntimeImpl * > (runtime.get()); 379cdf0e10cSrcweir Py_XINCREF( runtime.get() ); 380cdf0e10cSrcweir } 381cdf0e10cSrcweir 382cdf0e10cSrcweir Runtime::Runtime( const Runtime & r ) 383cdf0e10cSrcweir { 384cdf0e10cSrcweir impl = r.impl; 385cdf0e10cSrcweir Py_XINCREF( reinterpret_cast< PyObject * >(impl) ); 386cdf0e10cSrcweir } 387cdf0e10cSrcweir 388cdf0e10cSrcweir Runtime::~Runtime() 389cdf0e10cSrcweir { 390cdf0e10cSrcweir Py_XDECREF( reinterpret_cast< PyObject * >(impl) ); 391cdf0e10cSrcweir } 392cdf0e10cSrcweir 393cdf0e10cSrcweir Runtime & Runtime::operator = ( const Runtime & r ) 394cdf0e10cSrcweir { 395cdf0e10cSrcweir PyRef temp( reinterpret_cast< PyObject * >(r.impl) ); 396cdf0e10cSrcweir Py_XINCREF( temp.get() ); 397cdf0e10cSrcweir Py_XDECREF( reinterpret_cast< PyObject * >(impl) ); 398cdf0e10cSrcweir impl = r.impl; 399cdf0e10cSrcweir return *this; 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir PyRef Runtime::any2PyObject (const Any &a ) const 403cdf0e10cSrcweir throw ( com::sun::star::script::CannotConvertException, 404cdf0e10cSrcweir com::sun::star::lang::IllegalArgumentException, 405cdf0e10cSrcweir RuntimeException) 406cdf0e10cSrcweir { 407cdf0e10cSrcweir if( ! impl->cargo->valid ) 408cdf0e10cSrcweir { 409cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 410cdf0e10cSrcweir "pyuno runtime must be initialized before calling any2PyObject" )), 411cdf0e10cSrcweir Reference< XInterface > () ); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414cdf0e10cSrcweir switch (a.getValueTypeClass ()) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir case typelib_TypeClass_VOID: 417cdf0e10cSrcweir { 418cdf0e10cSrcweir Py_INCREF (Py_None); 419cdf0e10cSrcweir return PyRef(Py_None); 420cdf0e10cSrcweir } 421cdf0e10cSrcweir case typelib_TypeClass_CHAR: 422cdf0e10cSrcweir { 423cdf0e10cSrcweir sal_Unicode c = *(sal_Unicode*)a.getValue(); 424cdf0e10cSrcweir return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE ); 425cdf0e10cSrcweir } 426cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 427cdf0e10cSrcweir { 428cdf0e10cSrcweir sal_Bool b = sal_Bool(); 429cdf0e10cSrcweir if ((a >>= b) && b) 430cdf0e10cSrcweir return Py_True; 431cdf0e10cSrcweir else 432cdf0e10cSrcweir return Py_False; 433cdf0e10cSrcweir } 434cdf0e10cSrcweir case typelib_TypeClass_BYTE: 435cdf0e10cSrcweir case typelib_TypeClass_SHORT: 436cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 437cdf0e10cSrcweir case typelib_TypeClass_LONG: 438cdf0e10cSrcweir { 439cdf0e10cSrcweir sal_Int32 l = 0; 440cdf0e10cSrcweir a >>= l; 441cdf0e10cSrcweir return PyRef( PyInt_FromLong (l), SAL_NO_ACQUIRE ); 442cdf0e10cSrcweir } 443cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 444cdf0e10cSrcweir { 445cdf0e10cSrcweir sal_uInt32 l = 0; 446cdf0e10cSrcweir a >>= l; 447cdf0e10cSrcweir return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE ); 448cdf0e10cSrcweir } 449cdf0e10cSrcweir case typelib_TypeClass_HYPER: 450cdf0e10cSrcweir { 451cdf0e10cSrcweir sal_Int64 l = 0; 452cdf0e10cSrcweir a >>= l; 453cdf0e10cSrcweir return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE); 454cdf0e10cSrcweir } 455cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 456cdf0e10cSrcweir { 457cdf0e10cSrcweir sal_uInt64 l = 0; 458cdf0e10cSrcweir a >>= l; 459cdf0e10cSrcweir return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE); 460cdf0e10cSrcweir } 461cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 462cdf0e10cSrcweir { 463cdf0e10cSrcweir float f = 0.0; 464cdf0e10cSrcweir a >>= f; 465cdf0e10cSrcweir return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE); 466cdf0e10cSrcweir } 467cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 468cdf0e10cSrcweir { 469cdf0e10cSrcweir double d = 0.0; 470cdf0e10cSrcweir a >>= d; 471cdf0e10cSrcweir return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE); 472cdf0e10cSrcweir } 473cdf0e10cSrcweir case typelib_TypeClass_STRING: 474cdf0e10cSrcweir { 475cdf0e10cSrcweir OUString tmp_ostr; 476cdf0e10cSrcweir a >>= tmp_ostr; 477cdf0e10cSrcweir return ustring2PyUnicode( tmp_ostr ); 478cdf0e10cSrcweir } 479cdf0e10cSrcweir case typelib_TypeClass_TYPE: 480cdf0e10cSrcweir { 481cdf0e10cSrcweir Type t; 482cdf0e10cSrcweir a >>= t; 483cdf0e10cSrcweir OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US ); 484cdf0e10cSrcweir return PyRef( 485cdf0e10cSrcweir PyUNO_Type_new ( 486cdf0e10cSrcweir o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this), 487cdf0e10cSrcweir SAL_NO_ACQUIRE); 488cdf0e10cSrcweir } 489cdf0e10cSrcweir case typelib_TypeClass_ANY: 490cdf0e10cSrcweir { 491cdf0e10cSrcweir //I don't think this can happen. 492cdf0e10cSrcweir Py_INCREF (Py_None); 493cdf0e10cSrcweir return Py_None; 494cdf0e10cSrcweir } 495cdf0e10cSrcweir case typelib_TypeClass_ENUM: 496cdf0e10cSrcweir { 497cdf0e10cSrcweir sal_Int32 l = *(sal_Int32 *) a.getValue(); 498cdf0e10cSrcweir TypeDescription desc( a.getValueType() ); 499cdf0e10cSrcweir if( desc.is() ) 500cdf0e10cSrcweir { 501cdf0e10cSrcweir desc.makeComplete(); 502cdf0e10cSrcweir typelib_EnumTypeDescription *pEnumDesc = 503cdf0e10cSrcweir (typelib_EnumTypeDescription *) desc.get(); 504cdf0e10cSrcweir for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ ) 505cdf0e10cSrcweir { 506cdf0e10cSrcweir if( pEnumDesc->pEnumValues[i] == l ) 507cdf0e10cSrcweir { 508cdf0e10cSrcweir OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US); 509cdf0e10cSrcweir OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US); 510cdf0e10cSrcweir return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE ); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir } 513cdf0e10cSrcweir } 514cdf0e10cSrcweir OUStringBuffer buf; 515cdf0e10cSrcweir buf.appendAscii( "Any carries enum " ); 516cdf0e10cSrcweir buf.append( a.getValueType().getTypeName()); 517cdf0e10cSrcweir buf.appendAscii( " with invalid value " ).append( l ); 518cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > () ); 519cdf0e10cSrcweir } 520cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 521cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 522cdf0e10cSrcweir { 523cdf0e10cSrcweir PyRef excClass = getClass( a.getValueType().getTypeName(), *this ); 524cdf0e10cSrcweir PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE); 525cdf0e10cSrcweir PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE ); 526cdf0e10cSrcweir PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() ); 527cdf0e10cSrcweir PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE ); 528cdf0e10cSrcweir if( ! ret.is() ) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir OUStringBuffer buf; 531cdf0e10cSrcweir buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " ); 532cdf0e10cSrcweir buf.append( a.getValueType().getTypeName() ); 533cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); 534cdf0e10cSrcweir } 535cdf0e10cSrcweir 536cdf0e10cSrcweir if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() ) 537cdf0e10cSrcweir { 538cdf0e10cSrcweir // add the message in a standard python way ! 539cdf0e10cSrcweir PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); 540cdf0e10cSrcweir 541cdf0e10cSrcweir // assuming that the Message is always the first member, wuuuu 542cdf0e10cSrcweir void *pData = (void*)a.getValue(); 543cdf0e10cSrcweir OUString message = *(OUString * )pData; 544cdf0e10cSrcweir PyRef pymsg = ustring2PyString( message ); 545cdf0e10cSrcweir PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() ); 546cdf0e10cSrcweir // the exception base functions want to have an "args" tuple, 547cdf0e10cSrcweir // which contains the message 548cdf0e10cSrcweir PyObject_SetAttrString( ret.get(), const_cast< char * >("args"), args.get() ); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir return ret; 551cdf0e10cSrcweir } 552cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: 553cdf0e10cSrcweir { 554cdf0e10cSrcweir Sequence<Any> s; 555cdf0e10cSrcweir 556cdf0e10cSrcweir Sequence< sal_Int8 > byteSequence; 557cdf0e10cSrcweir if( a >>= byteSequence ) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir // byte sequence is treated in a special way because of peformance reasons 560cdf0e10cSrcweir // @since 0.9.2 561cdf0e10cSrcweir return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE ); 562cdf0e10cSrcweir } 563cdf0e10cSrcweir else 564cdf0e10cSrcweir { 565cdf0e10cSrcweir Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter; 566cdf0e10cSrcweir Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation; 567cdf0e10cSrcweir tc->convertTo (a, ::getCppuType (&s)) >>= s; 568cdf0e10cSrcweir PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE); 569cdf0e10cSrcweir int i=0; 570cdf0e10cSrcweir OUString errMsg; 571cdf0e10cSrcweir try 572cdf0e10cSrcweir { 573cdf0e10cSrcweir for ( i = 0; i < s.getLength (); i++) 574cdf0e10cSrcweir { 575cdf0e10cSrcweir PyRef element; 576cdf0e10cSrcweir element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() )); 577cdf0e10cSrcweir OSL_ASSERT( element.is() ); 578cdf0e10cSrcweir PyTuple_SetItem( tuple.get(), i, element.getAcquired() ); 579cdf0e10cSrcweir } 580cdf0e10cSrcweir } 581cdf0e10cSrcweir catch( com::sun::star::uno::Exception & ) 582cdf0e10cSrcweir { 583cdf0e10cSrcweir for( ; i < s.getLength() ; i ++ ) 584cdf0e10cSrcweir { 585cdf0e10cSrcweir Py_INCREF( Py_None ); 586cdf0e10cSrcweir PyTuple_SetItem( tuple.get(), i, Py_None ); 587cdf0e10cSrcweir } 588cdf0e10cSrcweir throw; 589cdf0e10cSrcweir } 590cdf0e10cSrcweir return tuple; 591cdf0e10cSrcweir } 592cdf0e10cSrcweir } 593cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 594cdf0e10cSrcweir { 595cdf0e10cSrcweir Reference< XUnoTunnel > tunnel; 596cdf0e10cSrcweir a >>= tunnel; 597cdf0e10cSrcweir if( tunnel.is() ) 598cdf0e10cSrcweir { 599cdf0e10cSrcweir sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() ); 600cdf0e10cSrcweir if( that ) 601cdf0e10cSrcweir return ((Adapter*)sal::static_int_cast< sal_IntPtr >(that))->getWrappedObject(); 602cdf0e10cSrcweir } 603cdf0e10cSrcweir //This is just like the struct case: 604cdf0e10cSrcweir return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE ); 605cdf0e10cSrcweir } 606cdf0e10cSrcweir default: 607cdf0e10cSrcweir { 608cdf0e10cSrcweir OUStringBuffer buf; 609cdf0e10cSrcweir buf.appendAscii( "Unknonwn UNO type class " ); 610cdf0e10cSrcweir buf.append( (sal_Int32 ) a.getValueTypeClass() ); 611cdf0e10cSrcweir throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () ); 612cdf0e10cSrcweir } 613cdf0e10cSrcweir } 614cdf0e10cSrcweir //We shouldn't be here... 615cdf0e10cSrcweir Py_INCREF( Py_None ); 616cdf0e10cSrcweir return Py_None; 617cdf0e10cSrcweir } 618cdf0e10cSrcweir 619cdf0e10cSrcweir static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o ) 620cdf0e10cSrcweir { 621cdf0e10cSrcweir Sequence< Type > ret; 622cdf0e10cSrcweir 623cdf0e10cSrcweir PyRef method( PyObject_GetAttrString( o , const_cast< char * >("getTypes") ), SAL_NO_ACQUIRE ); 624cdf0e10cSrcweir raiseInvocationTargetExceptionWhenNeeded( r ); 625cdf0e10cSrcweir if( method.is() && PyCallable_Check( method.get() ) ) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE ); 628cdf0e10cSrcweir raiseInvocationTargetExceptionWhenNeeded( r ); 629cdf0e10cSrcweir if( types.is() && PyTuple_Check( types.get() ) ) 630cdf0e10cSrcweir { 631cdf0e10cSrcweir int size = PyTuple_Size( types.get() ); 632cdf0e10cSrcweir 633cdf0e10cSrcweir // add the XUnoTunnel interface for uno object identity concept (hack) 634cdf0e10cSrcweir ret.realloc( size + 1 ); 635cdf0e10cSrcweir for( int i = 0 ; i < size ; i ++ ) 636cdf0e10cSrcweir { 637cdf0e10cSrcweir Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i)); 638cdf0e10cSrcweir a >>= ret[i]; 639cdf0e10cSrcweir } 640cdf0e10cSrcweir ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 ); 641cdf0e10cSrcweir } 642cdf0e10cSrcweir } 643cdf0e10cSrcweir return ret; 644cdf0e10cSrcweir } 645cdf0e10cSrcweir 646cdf0e10cSrcweir Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const 647cdf0e10cSrcweir throw ( com::sun::star::uno::RuntimeException ) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir if( ! impl->cargo->valid ) 650cdf0e10cSrcweir { 651cdf0e10cSrcweir throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( 652cdf0e10cSrcweir "pyuno runtime must be initialized before calling any2PyObject" )), 653cdf0e10cSrcweir Reference< XInterface > () ); 654cdf0e10cSrcweir } 655cdf0e10cSrcweir 656cdf0e10cSrcweir Any a; 657cdf0e10cSrcweir PyObject *o = source.get(); 658cdf0e10cSrcweir if( Py_None == o ) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir 661cdf0e10cSrcweir } 662cdf0e10cSrcweir else if (PyInt_Check (o)) 663cdf0e10cSrcweir { 664cdf0e10cSrcweir if( o == Py_True ) 665cdf0e10cSrcweir { 666cdf0e10cSrcweir sal_Bool b = sal_True; 667cdf0e10cSrcweir a = Any( &b, getBooleanCppuType() ); 668cdf0e10cSrcweir } 669cdf0e10cSrcweir else if ( o == Py_False ) 670cdf0e10cSrcweir { 671cdf0e10cSrcweir sal_Bool b = sal_False; 672cdf0e10cSrcweir a = Any( &b, getBooleanCppuType() ); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir else 675cdf0e10cSrcweir { 676cdf0e10cSrcweir sal_Int32 l = (sal_Int32) PyInt_AsLong( o ); 677cdf0e10cSrcweir if( l < 128 && l >= -128 ) 678cdf0e10cSrcweir { 679cdf0e10cSrcweir sal_Int8 b = (sal_Int8 ) l; 680cdf0e10cSrcweir a <<= b; 681cdf0e10cSrcweir } 682cdf0e10cSrcweir else if( l <= 0x7fff && l >= -0x8000 ) 683cdf0e10cSrcweir { 684cdf0e10cSrcweir sal_Int16 s = (sal_Int16) l; 685cdf0e10cSrcweir a <<= s; 686cdf0e10cSrcweir } 687cdf0e10cSrcweir else 688cdf0e10cSrcweir { 689cdf0e10cSrcweir a <<= l; 690cdf0e10cSrcweir } 691cdf0e10cSrcweir } 692cdf0e10cSrcweir } 693cdf0e10cSrcweir else if (PyLong_Check (o)) 694cdf0e10cSrcweir { 695cdf0e10cSrcweir sal_Int64 l = (sal_Int64)PyLong_AsLong (o); 696cdf0e10cSrcweir if( l < 128 && l >= -128 ) 697cdf0e10cSrcweir { 698cdf0e10cSrcweir sal_Int8 b = (sal_Int8 ) l; 699cdf0e10cSrcweir a <<= b; 700cdf0e10cSrcweir } 701cdf0e10cSrcweir else if( l <= 0x7fff && l >= -0x8000 ) 702cdf0e10cSrcweir { 703cdf0e10cSrcweir sal_Int16 s = (sal_Int16) l; 704cdf0e10cSrcweir a <<= s; 705cdf0e10cSrcweir } 706cdf0e10cSrcweir else if( l <= SAL_CONST_INT64(0x7fffffff) && 707cdf0e10cSrcweir l >= -SAL_CONST_INT64(0x80000000) ) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir sal_Int32 l32 = (sal_Int32) l; 710cdf0e10cSrcweir a <<= l32; 711cdf0e10cSrcweir } 712cdf0e10cSrcweir else 713cdf0e10cSrcweir { 714cdf0e10cSrcweir a <<= l; 715cdf0e10cSrcweir } 716cdf0e10cSrcweir } 717cdf0e10cSrcweir else if (PyFloat_Check (o)) 718cdf0e10cSrcweir { 719cdf0e10cSrcweir double d = PyFloat_AsDouble (o); 720cdf0e10cSrcweir a <<= d; 721cdf0e10cSrcweir } 722cdf0e10cSrcweir else if (PyString_Check (o)) 723cdf0e10cSrcweir a <<= pyString2ustring(o); 724cdf0e10cSrcweir else if( PyUnicode_Check( o ) ) 725cdf0e10cSrcweir a <<= pyString2ustring(o); 726cdf0e10cSrcweir else if (PyTuple_Check (o)) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir Sequence<Any> s (PyTuple_Size (o)); 729cdf0e10cSrcweir for (int i = 0; i < PyTuple_Size (o); i++) 730cdf0e10cSrcweir { 731cdf0e10cSrcweir s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode ); 732cdf0e10cSrcweir } 733cdf0e10cSrcweir a <<= s; 734cdf0e10cSrcweir } 735cdf0e10cSrcweir else 736cdf0e10cSrcweir { 737cdf0e10cSrcweir Runtime runtime; 738cdf0e10cSrcweir // should be removed, in case ByteSequence gets derived from String 739cdf0e10cSrcweir if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) ) 740cdf0e10cSrcweir { 741cdf0e10cSrcweir PyRef str(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE); 742cdf0e10cSrcweir Sequence< sal_Int8 > seq; 743cdf0e10cSrcweir if( PyString_Check( str.get() ) ) 744cdf0e10cSrcweir { 745cdf0e10cSrcweir seq = Sequence<sal_Int8 > ( 746cdf0e10cSrcweir (sal_Int8*) PyString_AsString(str.get()), PyString_Size(str.get())); 747cdf0e10cSrcweir } 748cdf0e10cSrcweir a <<= seq; 749cdf0e10cSrcweir } 750cdf0e10cSrcweir else 751cdf0e10cSrcweir if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) ) 752cdf0e10cSrcweir { 753cdf0e10cSrcweir Type t = PyType2Type( o ); 754cdf0e10cSrcweir a <<= t; 755cdf0e10cSrcweir } 756cdf0e10cSrcweir else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) ) 757cdf0e10cSrcweir { 758cdf0e10cSrcweir a = PyEnum2Enum( o ); 759cdf0e10cSrcweir } 760cdf0e10cSrcweir else if( isInstanceOfStructOrException( o ) ) 761cdf0e10cSrcweir { 762cdf0e10cSrcweir PyRef struc(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE); 763cdf0e10cSrcweir PyUNO * obj = (PyUNO*)struc.get(); 764cdf0e10cSrcweir Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY ); 765cdf0e10cSrcweir if( holder.is( ) ) 766cdf0e10cSrcweir a = holder->getMaterial(); 767cdf0e10cSrcweir else 768cdf0e10cSrcweir { 769cdf0e10cSrcweir throw RuntimeException( 770cdf0e10cSrcweir USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ), 771cdf0e10cSrcweir Reference< XInterface > () ); 772cdf0e10cSrcweir } 773cdf0e10cSrcweir } 774cdf0e10cSrcweir else if( PyObject_IsInstance( o, getPyUnoClass( runtime ).get() ) ) 775cdf0e10cSrcweir { 776cdf0e10cSrcweir PyUNO* o_pi; 777cdf0e10cSrcweir o_pi = (PyUNO*) o; 778cdf0e10cSrcweir if (o_pi->members->wrappedObject.getValueTypeClass () == 779cdf0e10cSrcweir com::sun::star::uno::TypeClass_STRUCT || 780cdf0e10cSrcweir o_pi->members->wrappedObject.getValueTypeClass () == 781cdf0e10cSrcweir com::sun::star::uno::TypeClass_EXCEPTION) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY); 784cdf0e10cSrcweir 785cdf0e10cSrcweir if (!my_mh.is ()) 786cdf0e10cSrcweir { 787cdf0e10cSrcweir throw RuntimeException( 788cdf0e10cSrcweir USTR_ASCII( "struct wrapper does not support XMaterialHolder" ), 789cdf0e10cSrcweir Reference< XInterface > () ); 790cdf0e10cSrcweir } 791cdf0e10cSrcweir else 792cdf0e10cSrcweir a = my_mh->getMaterial (); 793cdf0e10cSrcweir } 794cdf0e10cSrcweir else 795cdf0e10cSrcweir { 796cdf0e10cSrcweir a = o_pi->members->wrappedObject; 797cdf0e10cSrcweir } 798cdf0e10cSrcweir } 799cdf0e10cSrcweir else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir sal_Unicode c = PyChar2Unicode( o ); 802cdf0e10cSrcweir a.setValue( &c, getCharCppuType( )); 803cdf0e10cSrcweir } 804cdf0e10cSrcweir else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) ) 805cdf0e10cSrcweir { 806cdf0e10cSrcweir if( ACCEPT_UNO_ANY == mode ) 807cdf0e10cSrcweir { 808cdf0e10cSrcweir a = pyObject2Any( PyRef( PyObject_GetAttrString( o , const_cast< char * >("value") ), SAL_NO_ACQUIRE) ); 809cdf0e10cSrcweir Type t; 810cdf0e10cSrcweir pyObject2Any( PyRef( PyObject_GetAttrString( o, const_cast< char * >("type") ), SAL_NO_ACQUIRE ) ) >>= t; 811cdf0e10cSrcweir 812cdf0e10cSrcweir try 813cdf0e10cSrcweir { 814cdf0e10cSrcweir a = getImpl()->cargo->xTypeConverter->convertTo( a, t ); 815cdf0e10cSrcweir } 816cdf0e10cSrcweir catch( com::sun::star::uno::Exception & e ) 817cdf0e10cSrcweir { 818cdf0e10cSrcweir throw RuntimeException( e.Message, e.Context ); 819cdf0e10cSrcweir } 820cdf0e10cSrcweir } 821cdf0e10cSrcweir else 822cdf0e10cSrcweir { 823cdf0e10cSrcweir throw RuntimeException( 824cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 825cdf0e10cSrcweir "uno.Any instance not accepted during method call, " 826cdf0e10cSrcweir "use uno.invoke instead" ) ), 827cdf0e10cSrcweir Reference< XInterface > () ); 828cdf0e10cSrcweir } 829cdf0e10cSrcweir } 830cdf0e10cSrcweir else 831cdf0e10cSrcweir { 832cdf0e10cSrcweir Reference< XInterface > mappedObject; 833cdf0e10cSrcweir Reference< XInvocation > adapterObject; 834cdf0e10cSrcweir 835cdf0e10cSrcweir // instance already mapped out to the world ? 836cdf0e10cSrcweir PyRef2Adapter::iterator ii = impl->cargo->mappedObjects.find( PyRef( o ) ); 837cdf0e10cSrcweir if( ii != impl->cargo->mappedObjects.end() ) 838cdf0e10cSrcweir { 839cdf0e10cSrcweir adapterObject = ii->second; 840cdf0e10cSrcweir } 841cdf0e10cSrcweir 842cdf0e10cSrcweir if( adapterObject.is() ) 843cdf0e10cSrcweir { 844cdf0e10cSrcweir // object got already bridged ! 845cdf0e10cSrcweir Reference< com::sun::star::lang::XUnoTunnel > tunnel( adapterObject, UNO_QUERY ); 846cdf0e10cSrcweir 847cdf0e10cSrcweir Adapter *pAdapter = ( Adapter * ) 848cdf0e10cSrcweir sal::static_int_cast< sal_IntPtr >( 849cdf0e10cSrcweir tunnel->getSomething( 850cdf0e10cSrcweir ::pyuno::Adapter::getUnoTunnelImplementationId() ) ); 851cdf0e10cSrcweir 852cdf0e10cSrcweir mappedObject = impl->cargo->xAdapterFactory->createAdapter( 853cdf0e10cSrcweir adapterObject, pAdapter->getWrappedTypes() ); 854cdf0e10cSrcweir } 855cdf0e10cSrcweir else 856cdf0e10cSrcweir { 857cdf0e10cSrcweir Sequence< Type > interfaces = invokeGetTypes( *this, o ); 858cdf0e10cSrcweir if( interfaces.getLength() ) 859cdf0e10cSrcweir { 860cdf0e10cSrcweir Adapter *pAdapter = new Adapter( o, interfaces ); 861cdf0e10cSrcweir mappedObject = 862cdf0e10cSrcweir getImpl()->cargo->xAdapterFactory->createAdapter( 863cdf0e10cSrcweir pAdapter, interfaces ); 864cdf0e10cSrcweir 865cdf0e10cSrcweir // keep a list of exported objects to ensure object identity ! 866cdf0e10cSrcweir impl->cargo->mappedObjects[ PyRef(o) ] = 867cdf0e10cSrcweir com::sun::star::uno::WeakReference< XInvocation > ( pAdapter ); 868cdf0e10cSrcweir } 869cdf0e10cSrcweir } 870cdf0e10cSrcweir if( mappedObject.is() ) 871cdf0e10cSrcweir { 872cdf0e10cSrcweir a = com::sun::star::uno::makeAny( mappedObject ); 873cdf0e10cSrcweir } 874cdf0e10cSrcweir else 875cdf0e10cSrcweir { 876cdf0e10cSrcweir OUStringBuffer buf; 877cdf0e10cSrcweir buf.appendAscii( "Couldn't convert " ); 878cdf0e10cSrcweir PyRef reprString( PyObject_Str( o ) , SAL_NO_ACQUIRE ); 879cdf0e10cSrcweir buf.appendAscii( PyString_AsString( reprString.get() ) ); 880cdf0e10cSrcweir buf.appendAscii( " to a UNO type" ); 881cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); 882cdf0e10cSrcweir } 883cdf0e10cSrcweir } 884cdf0e10cSrcweir } 885cdf0e10cSrcweir return a; 886cdf0e10cSrcweir } 887cdf0e10cSrcweir 888cdf0e10cSrcweir Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const 889cdf0e10cSrcweir { 890cdf0e10cSrcweir PyRef str; 891cdf0e10cSrcweir Any ret; 892cdf0e10cSrcweir if( excTraceback.is() ) 893cdf0e10cSrcweir { 894cdf0e10cSrcweir PyRef unoModule( impl ? impl->cargo->getUnoModule() : 0 ); 895cdf0e10cSrcweir if( unoModule.is() ) 896cdf0e10cSrcweir { 897cdf0e10cSrcweir PyRef extractTraceback( 898cdf0e10cSrcweir PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) ); 899cdf0e10cSrcweir 900cdf0e10cSrcweir if( extractTraceback.is() ) 901cdf0e10cSrcweir { 902cdf0e10cSrcweir PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE ); 903cdf0e10cSrcweir PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() ); 904cdf0e10cSrcweir str = PyRef( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE); 905cdf0e10cSrcweir } 906cdf0e10cSrcweir else 907cdf0e10cSrcweir { 908cdf0e10cSrcweir str = PyRef( 909cdf0e10cSrcweir PyString_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ), 910cdf0e10cSrcweir SAL_NO_ACQUIRE ); 911cdf0e10cSrcweir } 912cdf0e10cSrcweir } 913cdf0e10cSrcweir else 914cdf0e10cSrcweir { 915cdf0e10cSrcweir str = PyRef( 916cdf0e10cSrcweir PyString_FromString( "Couldn't find uno.py, no stacktrace available" ), 917cdf0e10cSrcweir SAL_NO_ACQUIRE ); 918cdf0e10cSrcweir } 919cdf0e10cSrcweir 920cdf0e10cSrcweir } 921cdf0e10cSrcweir else 922cdf0e10cSrcweir { 923cdf0e10cSrcweir // it may occur, that no traceback is given (e.g. only native code below) 924cdf0e10cSrcweir str = PyRef( PyString_FromString( "no traceback available" ), SAL_NO_ACQUIRE); 925cdf0e10cSrcweir } 926cdf0e10cSrcweir 927cdf0e10cSrcweir if( isInstanceOfStructOrException( excValue.get() ) ) 928cdf0e10cSrcweir { 929cdf0e10cSrcweir ret = pyObject2Any( excValue ); 930cdf0e10cSrcweir } 931cdf0e10cSrcweir else 932cdf0e10cSrcweir { 933cdf0e10cSrcweir OUStringBuffer buf; 934cdf0e10cSrcweir PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE ); 935cdf0e10cSrcweir if( typeName.is() ) 936cdf0e10cSrcweir { 937cdf0e10cSrcweir buf.appendAscii( PyString_AsString( typeName.get() ) ); 938cdf0e10cSrcweir } 939cdf0e10cSrcweir else 940cdf0e10cSrcweir { 941cdf0e10cSrcweir buf.appendAscii( "no typename available" ); 942cdf0e10cSrcweir } 943cdf0e10cSrcweir buf.appendAscii( ": " ); 944cdf0e10cSrcweir PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE ); 945cdf0e10cSrcweir if( valueRep.is() ) 946cdf0e10cSrcweir { 947cdf0e10cSrcweir buf.appendAscii( PyString_AsString( valueRep.get())); 948cdf0e10cSrcweir } 949cdf0e10cSrcweir else 950cdf0e10cSrcweir { 951cdf0e10cSrcweir buf.appendAscii( "Couldn't convert exception value to a string" ); 952cdf0e10cSrcweir } 953cdf0e10cSrcweir buf.appendAscii( ", traceback follows\n" ); 954cdf0e10cSrcweir if( str.is() ) 955cdf0e10cSrcweir { 956cdf0e10cSrcweir buf.appendAscii( PyString_AsString( str.get() ) ); 957cdf0e10cSrcweir } 958cdf0e10cSrcweir else 959cdf0e10cSrcweir { 960cdf0e10cSrcweir buf.appendAscii( ", no traceback available\n" ); 961cdf0e10cSrcweir } 962cdf0e10cSrcweir RuntimeException e; 963cdf0e10cSrcweir e.Message = buf.makeStringAndClear(); 964cdf0e10cSrcweir ret = com::sun::star::uno::makeAny( e ); 965cdf0e10cSrcweir } 966cdf0e10cSrcweir return ret; 967cdf0e10cSrcweir } 968cdf0e10cSrcweir 969cdf0e10cSrcweir 970cdf0e10cSrcweir static const char * g_NUMERICID = "pyuno.lcNumeric"; 971cdf0e10cSrcweir static ::std::vector< rtl::OString > g_localeList; 972cdf0e10cSrcweir 973cdf0e10cSrcweir static const char *ensureUnlimitedLifetime( const char *str ) 974cdf0e10cSrcweir { 975cdf0e10cSrcweir int size = g_localeList.size(); 976cdf0e10cSrcweir int i; 977cdf0e10cSrcweir for( i = 0 ; i < size ; i ++ ) 978cdf0e10cSrcweir { 979cdf0e10cSrcweir if( 0 == strcmp( g_localeList[i].getStr(), str ) ) 980cdf0e10cSrcweir break; 981cdf0e10cSrcweir } 982cdf0e10cSrcweir if( i == size ) 983cdf0e10cSrcweir { 984cdf0e10cSrcweir g_localeList.push_back( str ); 985cdf0e10cSrcweir } 986cdf0e10cSrcweir return g_localeList[i].getStr(); 987cdf0e10cSrcweir } 988cdf0e10cSrcweir 989cdf0e10cSrcweir 990cdf0e10cSrcweir PyThreadAttach::PyThreadAttach( PyInterpreterState *interp) 991cdf0e10cSrcweir throw ( com::sun::star::uno::RuntimeException ) 992cdf0e10cSrcweir { 993cdf0e10cSrcweir tstate = PyThreadState_New( interp ); 994cdf0e10cSrcweir if( !tstate ) 995cdf0e10cSrcweir throw RuntimeException( 996cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ), 997cdf0e10cSrcweir Reference< XInterface > () ); 998cdf0e10cSrcweir PyEval_AcquireThread( tstate); 999cdf0e10cSrcweir // set LC_NUMERIC to "C" 1000cdf0e10cSrcweir const char * oldLocale = 1001cdf0e10cSrcweir ensureUnlimitedLifetime( setlocale( LC_NUMERIC, 0 ) ); 1002cdf0e10cSrcweir setlocale( LC_NUMERIC, "C" ); 1003cdf0e10cSrcweir PyRef locale( // python requires C locale 1004cdf0e10cSrcweir PyLong_FromVoidPtr( (void*)oldLocale ), SAL_NO_ACQUIRE); 1005cdf0e10cSrcweir PyDict_SetItemString( 1006cdf0e10cSrcweir PyThreadState_GetDict(), g_NUMERICID, locale.get() ); 1007cdf0e10cSrcweir } 1008cdf0e10cSrcweir 1009cdf0e10cSrcweir PyThreadAttach::~PyThreadAttach() 1010cdf0e10cSrcweir { 1011cdf0e10cSrcweir PyObject *value = 1012cdf0e10cSrcweir PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID ); 1013cdf0e10cSrcweir if( value ) 1014cdf0e10cSrcweir setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) ); 1015cdf0e10cSrcweir PyThreadState_Clear( tstate ); 1016cdf0e10cSrcweir PyEval_ReleaseThread( tstate ); 1017cdf0e10cSrcweir PyThreadState_Delete( tstate ); 1018cdf0e10cSrcweir 1019cdf0e10cSrcweir } 1020cdf0e10cSrcweir 1021cdf0e10cSrcweir PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException ) 1022cdf0e10cSrcweir { 1023cdf0e10cSrcweir tstate = PyThreadState_Get(); 1024cdf0e10cSrcweir PyObject *value = 1025cdf0e10cSrcweir PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID ); 1026cdf0e10cSrcweir if( value ) 1027cdf0e10cSrcweir setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) ); 1028cdf0e10cSrcweir PyEval_ReleaseThread( tstate ); 1029cdf0e10cSrcweir } 1030cdf0e10cSrcweir 1031cdf0e10cSrcweir /** Acquires the global interpreter lock again 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir */ 1034cdf0e10cSrcweir PyThreadDetach::~PyThreadDetach() 1035cdf0e10cSrcweir { 1036cdf0e10cSrcweir PyEval_AcquireThread( tstate ); 1037cdf0e10cSrcweir // PyObject *value = 1038cdf0e10cSrcweir // PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID ); 1039cdf0e10cSrcweir 1040cdf0e10cSrcweir // python requires C LC_NUMERIC locale, 1041cdf0e10cSrcweir // always set even when it is already "C" 1042cdf0e10cSrcweir setlocale( LC_NUMERIC, "C" ); 1043cdf0e10cSrcweir } 1044cdf0e10cSrcweir 1045cdf0e10cSrcweir 1046cdf0e10cSrcweir PyRef RuntimeCargo::getUnoModule() 1047cdf0e10cSrcweir { 1048cdf0e10cSrcweir if( ! dictUnoModule.is() ) 1049cdf0e10cSrcweir { 1050cdf0e10cSrcweir dictUnoModule = importUnoModule(); 1051cdf0e10cSrcweir } 1052cdf0e10cSrcweir return dictUnoModule; 1053cdf0e10cSrcweir } 1054cdf0e10cSrcweir } 1055