1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pyuno_runtime.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "pyuno_impl.hxx"
33 #include <osl/thread.h>
34 #include <osl/module.h>
35 #include <osl/process.h>
36 #include <rtl/strbuf.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <rtl/bootstrap.hxx>
41 #include <typelib/typedescription.hxx>
43 #include <com/sun/star/beans/XMaterialHolder.hpp>
46 using rtl::OUStringToOString
;
47 using rtl::OUStringBuffer
;
48 using rtl::OStringBuffer
;
51 using com::sun::star::uno::Reference
;
52 using com::sun::star::uno::XInterface
;
53 using com::sun::star::uno::Any
;
54 using com::sun::star::uno::TypeDescription
;
55 using com::sun::star::uno::Sequence
;
56 using com::sun::star::uno::Type
;
57 using com::sun::star::uno::UNO_QUERY
;
58 using com::sun::star::uno::RuntimeException
;
59 using com::sun::star::uno::XComponentContext
;
60 using com::sun::star::lang::XSingleServiceFactory
;
61 using com::sun::star::lang::XUnoTunnel
;
62 using com::sun::star::reflection::XIdlReflection
;
63 using com::sun::star::script::XTypeConverter
;
64 using com::sun::star::script::XInvocationAdapterFactory2
;
65 using com::sun::star::script::XInvocation
;
66 using com::sun::star::beans::XMaterialHolder
;
67 using com::sun::star::beans::XIntrospection
;
71 #define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
73 static PyTypeObject RuntimeImpl_Type
=
75 PyObject_HEAD_INIT (&PyType_Type
)
77 const_cast< char * >("pyuno_runtime"),
80 (destructor
) RuntimeImpl::del
,
122 #if PY_VERSION_HEX >= 0x02060000
127 /*----------------------------------------------------------------------
128 Runtime implementation
129 -----------------------------------------------------------------------*/
130 static void getRuntimeImpl( PyRef
& globalDict
, PyRef
&runtimeImpl
)
131 throw ( com::sun::star::uno::RuntimeException
)
133 PyThreadState
* state
= PyThreadState_Get();
136 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
137 "python global interpreter must be held (thread must be attached)" )),
138 Reference
< XInterface
> () );
141 globalDict
= PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
143 if( ! globalDict
.is() ) // FATAL !
145 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
146 "can't find __main__ module" )), Reference
< XInterface
> ());
148 runtimeImpl
= PyDict_GetItemString( globalDict
.get() , "pyuno_runtime" );
151 static PyRef
importUnoModule( ) throw ( RuntimeException
)
153 PyRef globalDict
= PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
154 // import the uno module
155 PyRef
module( PyImport_ImportModule( const_cast< char * >("uno") ), SAL_NO_ACQUIRE
);
156 if( PyErr_Occurred() )
158 PyRef excType
, excValue
, excTraceback
;
159 PyErr_Fetch( (PyObject
**)&excType
, (PyObject
**)&excValue
,(PyObject
**)&excTraceback
);
160 PyRef
str( PyObject_Repr( excTraceback
.get() ), SAL_NO_ACQUIRE
);
163 buf
.appendAscii( "python object raised an unknown exception (" );
164 PyRef
valueRep( PyObject_Repr( excValue
.get() ), SAL_NO_ACQUIRE
);
165 buf
.appendAscii( PyString_AsString( valueRep
.get())).appendAscii( ", traceback follows\n" );
166 buf
.appendAscii( PyString_AsString( str
.get() ) );
167 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
169 PyRef
dict( PyModule_GetDict( module
.get() ) );
173 static void readLoggingConfig( sal_Int32
*pLevel
, FILE **ppFile
)
175 *pLevel
= LogLevel::NONE
;
178 osl_getModuleURLFromFunctionAddress(
179 reinterpret_cast< oslGenericFunction
>(readLoggingConfig
),
180 (rtl_uString
**) &fileName
);
181 fileName
= OUString( fileName
.getStr(), fileName
.lastIndexOf( '/' )+1 );
182 fileName
+= OUString::createFromAscii( SAL_CONFIGFILE("pyuno") );
183 rtl::Bootstrap
bootstrapHandle( fileName
);
186 if( bootstrapHandle
.getFrom( USTR_ASCII( "PYUNO_LOGLEVEL" ), str
) )
188 if( str
.equalsAscii( "NONE" ) )
189 *pLevel
= LogLevel::NONE
;
190 else if( str
.equalsAscii( "CALL" ) )
191 *pLevel
= LogLevel::CALL
;
192 else if( str
.equalsAscii( "ARGS" ) )
193 *pLevel
= LogLevel::ARGS
;
196 fprintf( stderr
, "unknown loglevel %s\n",
197 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
200 if( *pLevel
> LogLevel::NONE
)
203 if( bootstrapHandle
.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str
) )
205 if( str
.equalsAscii( "stdout" ) )
207 else if( str
.equalsAscii( "stderr" ) )
212 data
.Size
= sizeof( data
);
214 0 , osl_Process_IDENTIFIER
, &data
);
215 osl_getSystemPathFromFileURL( str
.pData
, &str
.pData
);
216 OString o
= OUStringToOString( str
, osl_getThreadTextEncoding() );
218 o
+= OString::valueOf( (sal_Int32
)data
.Ident
);
220 *ppFile
= fopen( o
.getStr() , "w" );
223 // do not buffer (useful if e.g. analyzing a crash)
224 setvbuf( *ppFile
, 0, _IONBF
, 0 );
228 fprintf( stderr
, "couldn't create file %s\n",
229 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
237 /*-------------------------------------------------------------------
238 RuntimeImpl implementations
239 *-------------------------------------------------------------------*/
240 PyRef
stRuntimeImpl::create( const Reference
< XComponentContext
> &ctx
)
241 throw( com::sun::star::uno::RuntimeException
)
243 RuntimeImpl
*me
= PyObject_New (RuntimeImpl
, &RuntimeImpl_Type
);
245 throw RuntimeException(
246 OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ),
247 Reference
< XInterface
> () );
249 // must use a different struct here, as the PyObject_New
250 // makes C++ unusable
251 RuntimeCargo
*c
= new RuntimeCargo();
252 readLoggingConfig( &(c
->logLevel
) , &(c
->logFile
) );
253 log( c
, LogLevel::CALL
, "Instantiating pyuno bridge" );
257 c
->xInvocation
= Reference
< XSingleServiceFactory
> (
258 ctx
->getServiceManager()->createInstanceWithContext(
259 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ),
262 if( ! c
->xInvocation
.is() )
263 throw RuntimeException(
264 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ),
265 Reference
< XInterface
> () );
267 c
->xTypeConverter
= Reference
< XTypeConverter
> (
268 ctx
->getServiceManager()->createInstanceWithContext(
269 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ),
272 if( ! c
->xTypeConverter
.is() )
273 throw RuntimeException(
274 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )),
275 Reference
< XInterface
> () );
277 c
->xCoreReflection
= Reference
< XIdlReflection
> (
278 ctx
->getServiceManager()->createInstanceWithContext(
279 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ),
282 if( ! c
->xCoreReflection
.is() )
283 throw RuntimeException(
284 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )),
285 Reference
< XInterface
> () );
287 c
->xAdapterFactory
= Reference
< XInvocationAdapterFactory2
> (
288 ctx
->getServiceManager()->createInstanceWithContext(
289 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ),
292 if( ! c
->xAdapterFactory
.is() )
293 throw RuntimeException(
294 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )),
295 Reference
< XInterface
> () );
297 c
->xIntrospection
= Reference
< XIntrospection
> (
298 ctx
->getServiceManager()->createInstanceWithContext(
299 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ),
302 if( ! c
->xIntrospection
.is() )
303 throw RuntimeException(
304 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )),
305 Reference
< XInterface
> () );
307 Any a
= ctx
->getValueByName(OUString(
308 RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) );
310 if( ! c
->xTdMgr
.is() )
311 throw RuntimeException(
312 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )),
313 Reference
< XInterface
> () );
316 return PyRef( reinterpret_cast< PyObject
* > ( me
), SAL_NO_ACQUIRE
);
319 void stRuntimeImpl::del(PyObject
* self
)
321 RuntimeImpl
*me
= reinterpret_cast< RuntimeImpl
* > ( self
);
322 if( me
->cargo
->logFile
)
323 fclose( me
->cargo
->logFile
);
329 void Runtime::initialize( const Reference
< XComponentContext
> & ctx
)
330 throw ( RuntimeException
)
332 PyRef globalDict
, runtime
;
333 getRuntimeImpl( globalDict
, runtime
);
334 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
336 if( runtime
.is() && impl
->cargo
->valid
)
338 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
339 "pyuno runtime has already been initialized before" ) ),
340 Reference
< XInterface
> () );
342 PyRef
keep( RuntimeImpl::create( ctx
) );
343 PyDict_SetItemString( globalDict
.get(), "pyuno_runtime" , keep
.get() );
344 Py_XINCREF( keep
.get() );
348 bool Runtime::isInitialized() throw ( RuntimeException
)
350 PyRef globalDict
, runtime
;
351 getRuntimeImpl( globalDict
, runtime
);
352 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
353 return runtime
.is() && impl
->cargo
->valid
;
356 void Runtime::finalize() throw (RuntimeException
)
358 PyRef globalDict
, runtime
;
359 getRuntimeImpl( globalDict
, runtime
);
360 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
361 if( !runtime
.is() || ! impl
->cargo
->valid
)
363 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
364 "pyuno bridge must have been initialized before finalizing" )),
365 Reference
< XInterface
> () );
367 impl
->cargo
->valid
= false;
368 impl
->cargo
->xInvocation
.clear();
369 impl
->cargo
->xContext
.clear();
370 impl
->cargo
->xTypeConverter
.clear();
373 Runtime::Runtime() throw( RuntimeException
)
376 PyRef globalDict
, runtime
;
377 getRuntimeImpl( globalDict
, runtime
);
380 throw RuntimeException(
381 OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, "
382 "(the pyuno.bootstrap needs to be called before using any uno classes)")),
383 Reference
< XInterface
> () );
385 impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
386 Py_XINCREF( runtime
.get() );
389 Runtime::Runtime( const Runtime
& r
)
392 Py_XINCREF( reinterpret_cast< PyObject
* >(impl
) );
397 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
400 Runtime
& Runtime::operator = ( const Runtime
& r
)
402 PyRef
temp( reinterpret_cast< PyObject
* >(r
.impl
) );
403 Py_XINCREF( temp
.get() );
404 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
409 PyRef
Runtime::any2PyObject (const Any
&a
) const
410 throw ( com::sun::star::script::CannotConvertException
,
411 com::sun::star::lang::IllegalArgumentException
,
414 if( ! impl
->cargo
->valid
)
416 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
417 "pyuno runtime must be initialized before calling any2PyObject" )),
418 Reference
< XInterface
> () );
421 switch (a
.getValueTypeClass ())
423 case typelib_TypeClass_VOID
:
426 return PyRef(Py_None
);
428 case typelib_TypeClass_CHAR
:
430 sal_Unicode c
= *(sal_Unicode
*)a
.getValue();
431 return PyRef( PyUNO_char_new( c
, *this ), SAL_NO_ACQUIRE
);
433 case typelib_TypeClass_BOOLEAN
:
435 sal_Bool b
= sal_Bool();
441 case typelib_TypeClass_BYTE
:
442 case typelib_TypeClass_SHORT
:
443 case typelib_TypeClass_UNSIGNED_SHORT
:
444 case typelib_TypeClass_LONG
:
448 return PyRef( PyInt_FromLong (l
), SAL_NO_ACQUIRE
);
450 case typelib_TypeClass_UNSIGNED_LONG
:
454 return PyRef( PyLong_FromUnsignedLong (l
), SAL_NO_ACQUIRE
);
456 case typelib_TypeClass_HYPER
:
460 return PyRef( PyLong_FromLongLong (l
), SAL_NO_ACQUIRE
);
462 case typelib_TypeClass_UNSIGNED_HYPER
:
466 return PyRef( PyLong_FromUnsignedLongLong (l
), SAL_NO_ACQUIRE
);
468 case typelib_TypeClass_FLOAT
:
472 return PyRef(PyFloat_FromDouble (f
), SAL_NO_ACQUIRE
);
474 case typelib_TypeClass_DOUBLE
:
478 return PyRef( PyFloat_FromDouble (d
), SAL_NO_ACQUIRE
);
480 case typelib_TypeClass_STRING
:
484 return ustring2PyUnicode( tmp_ostr
);
486 case typelib_TypeClass_TYPE
:
490 OString o
= OUStringToOString( t
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
493 o
.getStr(), (com::sun::star::uno::TypeClass
)t
.getTypeClass(), *this),
496 case typelib_TypeClass_ANY
:
498 //I don't think this can happen.
502 case typelib_TypeClass_ENUM
:
504 sal_Int32 l
= *(sal_Int32
*) a
.getValue();
505 TypeDescription
desc( a
.getValueType() );
509 typelib_EnumTypeDescription
*pEnumDesc
=
510 (typelib_EnumTypeDescription
*) desc
.get();
511 for( int i
= 0 ; i
< pEnumDesc
->nEnumValues
; i
++ )
513 if( pEnumDesc
->pEnumValues
[i
] == l
)
515 OString v
= OUStringToOString( pEnumDesc
->ppEnumNames
[i
], RTL_TEXTENCODING_ASCII_US
);
516 OString e
= OUStringToOString( pEnumDesc
->aBase
.pTypeName
, RTL_TEXTENCODING_ASCII_US
);
517 return PyRef( PyUNO_Enum_new(e
.getStr(),v
.getStr(), *this ), SAL_NO_ACQUIRE
);
522 buf
.appendAscii( "Any carries enum " );
523 buf
.append( a
.getValueType().getTypeName());
524 buf
.appendAscii( " with invalid value " ).append( l
);
525 throw RuntimeException( buf
.makeStringAndClear() , Reference
< XInterface
> () );
527 case typelib_TypeClass_EXCEPTION
:
528 case typelib_TypeClass_STRUCT
:
530 PyRef excClass
= getClass( a
.getValueType().getTypeName(), *this );
531 PyRef value
= PyRef( PyUNO_new_UNCHECKED (a
, getImpl()->cargo
->xInvocation
), SAL_NO_ACQUIRE
);
532 PyRef
argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE
);
533 PyTuple_SetItem( argsTuple
.get() , 0 , value
.getAcquired() );
534 PyRef
ret( PyObject_CallObject( excClass
.get() , argsTuple
.get() ), SAL_NO_ACQUIRE
);
538 buf
.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
539 buf
.append( a
.getValueType().getTypeName() );
540 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
543 if( com::sun::star::uno::TypeClass_EXCEPTION
== a
.getValueTypeClass() )
545 // add the message in a standard python way !
546 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
);
548 // assuming that the Message is always the first member, wuuuu
549 void *pData
= (void*)a
.getValue();
550 OUString message
= *(OUString
* )pData
;
551 PyRef pymsg
= ustring2PyString( message
);
552 PyTuple_SetItem( args
.get(), 0 , pymsg
.getAcquired() );
553 // the exception base functions want to have an "args" tuple,
554 // which contains the message
555 PyObject_SetAttrString( ret
.get(), const_cast< char * >("args"), args
.get() );
559 case typelib_TypeClass_SEQUENCE
:
563 Sequence
< sal_Int8
> byteSequence
;
564 if( a
>>= byteSequence
)
566 // byte sequence is treated in a special way because of peformance reasons
568 return PyRef( PyUNO_ByteSequence_new( byteSequence
, *this ), SAL_NO_ACQUIRE
);
572 Reference
< XTypeConverter
> tc
= getImpl()->cargo
->xTypeConverter
;
573 Reference
< XSingleServiceFactory
> ssf
= getImpl()->cargo
->xInvocation
;
574 tc
->convertTo (a
, ::getCppuType (&s
)) >>= s
;
575 PyRef
tuple( PyTuple_New (s
.getLength()), SAL_NO_ACQUIRE
);
580 for ( i
= 0; i
< s
.getLength (); i
++)
583 element
= any2PyObject (tc
->convertTo (s
[i
], s
[i
].getValueType() ));
584 OSL_ASSERT( element
.is() );
585 PyTuple_SetItem( tuple
.get(), i
, element
.getAcquired() );
588 catch( com::sun::star::uno::Exception
& )
590 for( ; i
< s
.getLength() ; i
++ )
592 Py_INCREF( Py_None
);
593 PyTuple_SetItem( tuple
.get(), i
, Py_None
);
600 case typelib_TypeClass_INTERFACE
:
602 Reference
< XUnoTunnel
> tunnel
;
606 sal_Int64 that
= tunnel
->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
608 return ((Adapter
*)sal::static_int_cast
< sal_IntPtr
>(that
))->getWrappedObject();
610 //This is just like the struct case:
611 return PyRef( PyUNO_new (a
, getImpl()->cargo
->xInvocation
), SAL_NO_ACQUIRE
);
616 buf
.appendAscii( "Unknonwn UNO type class " );
617 buf
.append( (sal_Int32
) a
.getValueTypeClass() );
618 throw RuntimeException(buf
.makeStringAndClear( ), Reference
< XInterface
> () );
621 //We shouldn't be here...
622 Py_INCREF( Py_None
);
626 static Sequence
< Type
> invokeGetTypes( const Runtime
& r
, PyObject
* o
)
628 Sequence
< Type
> ret
;
630 PyRef
method( PyObject_GetAttrString( o
, const_cast< char * >("getTypes") ), SAL_NO_ACQUIRE
);
631 raiseInvocationTargetExceptionWhenNeeded( r
);
632 if( method
.is() && PyCallable_Check( method
.get() ) )
634 PyRef
types( PyObject_CallObject( method
.get(), 0 ) , SAL_NO_ACQUIRE
);
635 raiseInvocationTargetExceptionWhenNeeded( r
);
636 if( types
.is() && PyTuple_Check( types
.get() ) )
638 int size
= PyTuple_Size( types
.get() );
640 // add the XUnoTunnel interface for uno object identity concept (hack)
641 ret
.realloc( size
+ 1 );
642 for( int i
= 0 ; i
< size
; i
++ )
644 Any a
= r
.pyObject2Any(PyTuple_GetItem(types
.get(),i
));
647 ret
[size
] = getCppuType( (Reference
< com::sun::star::lang::XUnoTunnel
> *) 0 );
653 Any
Runtime::pyObject2Any ( const PyRef
& source
, enum ConversionMode mode
) const
654 throw ( com::sun::star::uno::RuntimeException
)
656 if( ! impl
->cargo
->valid
)
658 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
659 "pyuno runtime must be initialized before calling any2PyObject" )),
660 Reference
< XInterface
> () );
664 PyObject
*o
= source
.get();
669 else if (PyInt_Check (o
))
673 sal_Bool b
= sal_True
;
674 a
= Any( &b
, getBooleanCppuType() );
676 else if ( o
== Py_False
)
678 sal_Bool b
= sal_False
;
679 a
= Any( &b
, getBooleanCppuType() );
683 sal_Int32 l
= (sal_Int32
) PyInt_AsLong( o
);
684 if( l
< 128 && l
>= -128 )
686 sal_Int8 b
= (sal_Int8
) l
;
689 else if( l
<= 0x7fff && l
>= -0x8000 )
691 sal_Int16 s
= (sal_Int16
) l
;
700 else if (PyLong_Check (o
))
702 sal_Int64 l
= (sal_Int64
)PyLong_AsLong (o
);
703 if( l
< 128 && l
>= -128 )
705 sal_Int8 b
= (sal_Int8
) l
;
708 else if( l
<= 0x7fff && l
>= -0x8000 )
710 sal_Int16 s
= (sal_Int16
) l
;
713 else if( l
<= SAL_CONST_INT64(0x7fffffff) &&
714 l
>= -SAL_CONST_INT64(0x80000000) )
716 sal_Int32 l32
= (sal_Int32
) l
;
724 else if (PyFloat_Check (o
))
726 double d
= PyFloat_AsDouble (o
);
729 else if (PyString_Check (o
))
730 a
<<= pyString2ustring(o
);
731 else if( PyUnicode_Check( o
) )
732 a
<<= pyString2ustring(o
);
733 else if (PyTuple_Check (o
))
735 Sequence
<Any
> s (PyTuple_Size (o
));
736 for (int i
= 0; i
< PyTuple_Size (o
); i
++)
738 s
[i
] = pyObject2Any (PyTuple_GetItem (o
, i
), mode
);
745 // should be removed, in case ByteSequence gets derived from String
746 if( PyObject_IsInstance( o
, getByteSequenceClass( runtime
).get() ) )
748 PyRef
str(PyObject_GetAttrString( o
, const_cast< char * >("value") ),SAL_NO_ACQUIRE
);
749 Sequence
< sal_Int8
> seq
;
750 if( PyString_Check( str
.get() ) )
752 seq
= Sequence
<sal_Int8
> (
753 (sal_Int8
*) PyString_AsString(str
.get()), PyString_Size(str
.get()));
758 if( PyObject_IsInstance( o
, getTypeClass( runtime
).get() ) )
760 Type t
= PyType2Type( o
);
763 else if( PyObject_IsInstance( o
, getEnumClass( runtime
).get() ) )
765 a
= PyEnum2Enum( o
);
767 else if( isInstanceOfStructOrException( o
) )
769 PyRef
struc(PyObject_GetAttrString( o
, const_cast< char * >("value") ),SAL_NO_ACQUIRE
);
770 PyUNO
* obj
= (PyUNO
*)struc
.get();
771 Reference
< XMaterialHolder
> holder( obj
->members
->xInvocation
, UNO_QUERY
);
773 a
= holder
->getMaterial();
776 throw RuntimeException(
777 USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ),
778 Reference
< XInterface
> () );
781 else if( PyObject_IsInstance( o
, getPyUnoClass( runtime
).get() ) )
785 if (o_pi
->members
->wrappedObject
.getValueTypeClass () ==
786 com::sun::star::uno::TypeClass_STRUCT
||
787 o_pi
->members
->wrappedObject
.getValueTypeClass () ==
788 com::sun::star::uno::TypeClass_EXCEPTION
)
790 Reference
<XMaterialHolder
> my_mh (o_pi
->members
->xInvocation
, UNO_QUERY
);
794 throw RuntimeException(
795 USTR_ASCII( "struct wrapper does not support XMaterialHolder" ),
796 Reference
< XInterface
> () );
799 a
= my_mh
->getMaterial ();
803 a
= o_pi
->members
->wrappedObject
;
806 else if( PyObject_IsInstance( o
, getCharClass( runtime
).get() ) )
808 sal_Unicode c
= PyChar2Unicode( o
);
809 a
.setValue( &c
, getCharCppuType( ));
811 else if( PyObject_IsInstance( o
, getAnyClass( runtime
).get() ) )
813 if( ACCEPT_UNO_ANY
== mode
)
815 a
= pyObject2Any( PyRef( PyObject_GetAttrString( o
, const_cast< char * >("value") ), SAL_NO_ACQUIRE
) );
817 pyObject2Any( PyRef( PyObject_GetAttrString( o
, const_cast< char * >("type") ), SAL_NO_ACQUIRE
) ) >>= t
;
821 a
= getImpl()->cargo
->xTypeConverter
->convertTo( a
, t
);
823 catch( com::sun::star::uno::Exception
& e
)
825 throw RuntimeException( e
.Message
, e
.Context
);
830 throw RuntimeException(
831 OUString( RTL_CONSTASCII_USTRINGPARAM(
832 "uno.Any instance not accepted during method call, "
833 "use uno.invoke instead" ) ),
834 Reference
< XInterface
> () );
839 Reference
< XInterface
> mappedObject
;
840 Reference
< XInvocation
> adapterObject
;
842 // instance already mapped out to the world ?
843 PyRef2Adapter::iterator ii
= impl
->cargo
->mappedObjects
.find( PyRef( o
) );
844 if( ii
!= impl
->cargo
->mappedObjects
.end() )
846 adapterObject
= ii
->second
;
849 if( adapterObject
.is() )
851 // object got already bridged !
852 Reference
< com::sun::star::lang::XUnoTunnel
> tunnel( adapterObject
, UNO_QUERY
);
854 Adapter
*pAdapter
= ( Adapter
* )
855 sal::static_int_cast
< sal_IntPtr
>(
856 tunnel
->getSomething(
857 ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
859 mappedObject
= impl
->cargo
->xAdapterFactory
->createAdapter(
860 adapterObject
, pAdapter
->getWrappedTypes() );
864 Sequence
< Type
> interfaces
= invokeGetTypes( *this, o
);
865 if( interfaces
.getLength() )
867 Adapter
*pAdapter
= new Adapter( o
, interfaces
);
869 getImpl()->cargo
->xAdapterFactory
->createAdapter(
870 pAdapter
, interfaces
);
872 // keep a list of exported objects to ensure object identity !
873 impl
->cargo
->mappedObjects
[ PyRef(o
) ] =
874 com::sun::star::uno::WeakReference
< XInvocation
> ( pAdapter
);
877 if( mappedObject
.is() )
879 a
= com::sun::star::uno::makeAny( mappedObject
);
884 buf
.appendAscii( "Couldn't convert " );
885 PyRef
reprString( PyObject_Str( o
) , SAL_NO_ACQUIRE
);
886 buf
.appendAscii( PyString_AsString( reprString
.get() ) );
887 buf
.appendAscii( " to a UNO type" );
888 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
895 Any
Runtime::extractUnoException( const PyRef
& excType
, const PyRef
&excValue
, const PyRef
&excTraceback
) const
899 if( excTraceback
.is() )
901 PyRef
unoModule( impl
? impl
->cargo
->getUnoModule() : 0 );
904 PyRef
extractTraceback(
905 PyDict_GetItemString(unoModule
.get(),"_uno_extract_printable_stacktrace" ) );
907 if( extractTraceback
.is() )
909 PyRef
args( PyTuple_New( 1), SAL_NO_ACQUIRE
);
910 PyTuple_SetItem( args
.get(), 0, excTraceback
.getAcquired() );
911 str
= PyRef( PyObject_CallObject( extractTraceback
.get(),args
.get() ), SAL_NO_ACQUIRE
);
916 PyString_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ),
923 PyString_FromString( "Couldn't find uno.py, no stacktrace available" ),
930 // it may occur, that no traceback is given (e.g. only native code below)
931 str
= PyRef( PyString_FromString( "no traceback available" ), SAL_NO_ACQUIRE
);
934 if( isInstanceOfStructOrException( excValue
.get() ) )
936 ret
= pyObject2Any( excValue
);
941 PyRef
typeName( PyObject_Str( excType
.get() ), SAL_NO_ACQUIRE
);
944 buf
.appendAscii( PyString_AsString( typeName
.get() ) );
948 buf
.appendAscii( "no typename available" );
950 buf
.appendAscii( ": " );
951 PyRef
valueRep( PyObject_Str( excValue
.get() ), SAL_NO_ACQUIRE
);
954 buf
.appendAscii( PyString_AsString( valueRep
.get()));
958 buf
.appendAscii( "Couldn't convert exception value to a string" );
960 buf
.appendAscii( ", traceback follows\n" );
963 buf
.appendAscii( PyString_AsString( str
.get() ) );
967 buf
.appendAscii( ", no traceback available\n" );
970 e
.Message
= buf
.makeStringAndClear();
971 ret
= com::sun::star::uno::makeAny( e
);
977 static const char * g_NUMERICID
= "pyuno.lcNumeric";
978 static ::std::vector
< rtl::OString
> g_localeList
;
980 static const char *ensureUnlimitedLifetime( const char *str
)
982 int size
= g_localeList
.size();
984 for( i
= 0 ; i
< size
; i
++ )
986 if( 0 == strcmp( g_localeList
[i
].getStr(), str
) )
991 g_localeList
.push_back( str
);
993 return g_localeList
[i
].getStr();
997 PyThreadAttach::PyThreadAttach( PyInterpreterState
*interp
)
998 throw ( com::sun::star::uno::RuntimeException
)
1000 tstate
= PyThreadState_New( interp
);
1002 throw RuntimeException(
1003 OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ),
1004 Reference
< XInterface
> () );
1005 PyEval_AcquireThread( tstate
);
1006 // set LC_NUMERIC to "C"
1007 const char * oldLocale
=
1008 ensureUnlimitedLifetime( setlocale( LC_NUMERIC
, 0 ) );
1009 setlocale( LC_NUMERIC
, "C" );
1010 PyRef
locale( // python requires C locale
1011 PyLong_FromVoidPtr( (void*)oldLocale
), SAL_NO_ACQUIRE
);
1012 PyDict_SetItemString(
1013 PyThreadState_GetDict(), g_NUMERICID
, locale
.get() );
1016 PyThreadAttach::~PyThreadAttach()
1019 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID
);
1021 setlocale( LC_NUMERIC
, (const char * ) PyLong_AsVoidPtr( value
) );
1022 PyThreadState_Clear( tstate
);
1023 PyEval_ReleaseThread( tstate
);
1024 PyThreadState_Delete( tstate
);
1028 PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException
)
1030 tstate
= PyThreadState_Get();
1032 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID
);
1034 setlocale( LC_NUMERIC
, (const char * ) PyLong_AsVoidPtr( value
) );
1035 PyEval_ReleaseThread( tstate
);
1038 /** Acquires the global interpreter lock again
1041 PyThreadDetach::~PyThreadDetach()
1043 PyEval_AcquireThread( tstate
);
1044 // PyObject *value =
1045 // PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1047 // python requires C LC_NUMERIC locale,
1048 // always set even when it is already "C"
1049 setlocale( LC_NUMERIC
, "C" );
1053 PyRef
RuntimeCargo::getUnoModule()
1055 if( ! dictUnoModule
.is() )
1057 dictUnoModule
= importUnoModule();
1059 return dictUnoModule
;