1 /* -*- Mode: C++; eval:(c-set-style "bsd"); tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <config_folders.h>
23 #include "pyuno_impl.hxx"
25 #include <osl/thread.h>
26 #include <osl/module.h>
27 #include <osl/process.h>
28 #include <rtl/strbuf.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <rtl/bootstrap.hxx>
33 #include <typelib/typedescription.hxx>
35 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
36 #include <com/sun/star/beans/XMaterialHolder.hpp>
37 #include <com/sun/star/beans/Introspection.hpp>
38 #include <com/sun/star/script/Converter.hpp>
39 #include <com/sun/star/script/InvocationAdapterFactory.hpp>
40 #include <com/sun/star/reflection/theCoreReflection.hpp>
43 using com::sun::star::uno::Reference
;
44 using com::sun::star::uno::XInterface
;
45 using com::sun::star::uno::Any
;
46 using com::sun::star::uno::TypeDescription
;
47 using com::sun::star::uno::Sequence
;
48 using com::sun::star::uno::Type
;
49 using com::sun::star::uno::UNO_QUERY
;
50 using com::sun::star::uno::Exception
;
51 using com::sun::star::uno::RuntimeException
;
52 using com::sun::star::uno::XComponentContext
;
53 using com::sun::star::lang::WrappedTargetRuntimeException
;
54 using com::sun::star::lang::XSingleServiceFactory
;
55 using com::sun::star::lang::XUnoTunnel
;
56 using com::sun::star::reflection::theCoreReflection
;
57 using com::sun::star::reflection::XIdlReflection
;
58 using com::sun::star::reflection::InvocationTargetException
;
59 using com::sun::star::script::Converter
;
60 using com::sun::star::script::XTypeConverter
;
61 using com::sun::star::script::XInvocationAdapterFactory2
;
62 using com::sun::star::script::XInvocation
;
63 using com::sun::star::beans::XMaterialHolder
;
64 using com::sun::star::beans::XIntrospection
;
65 using com::sun::star::beans::Introspection
;
72 static PyTypeObject RuntimeImpl_Type
=
74 PyVarObject_HEAD_INIT (&PyType_Type
, 0)
78 (destructor
) RuntimeImpl::del
,
120 #if PY_VERSION_HEX >= 0x02060000
125 /*----------------------------------------------------------------------
126 Runtime implementation
127 -----------------------------------------------------------------------*/
128 static void getRuntimeImpl( PyRef
& globalDict
, PyRef
&runtimeImpl
)
129 throw ( com::sun::star::uno::RuntimeException
)
131 PyThreadState
* state
= PyThreadState_Get();
134 throw RuntimeException( OUString( "python global interpreter must be held (thread must be attached)" ),
135 Reference
< XInterface
> () );
138 globalDict
= PyRef( PyModule_GetDict(PyImport_AddModule("__main__")));
140 if( ! globalDict
.is() ) // FATAL !
142 throw RuntimeException("can't find __main__ module", Reference
< XInterface
> ());
144 runtimeImpl
= PyDict_GetItemString( globalDict
.get() , "pyuno_runtime" );
147 static PyRef
importUnoModule( ) throw ( RuntimeException
)
149 // import the uno module
150 PyRef
module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE
);
151 if( PyErr_Occurred() )
153 PyRef excType
, excValue
, excTraceback
;
154 PyErr_Fetch( (PyObject
**)&excType
, (PyObject
**)&excValue
,(PyObject
**)&excTraceback
);
155 // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
156 // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
157 // Who knows, a future Python might print something better.
158 PyRef
str( PyObject_Str( excTraceback
.get() ), SAL_NO_ACQUIRE
);
161 buf
.appendAscii( "python object raised an unknown exception (" );
162 PyRef
valueRep( PyObject_Repr( excValue
.get() ), SAL_NO_ACQUIRE
);
163 buf
.appendAscii( PyStr_AsString( valueRep
.get())).appendAscii( ", traceback follows\n" );
164 buf
.appendAscii( PyStr_AsString( str
.get() ) );
165 buf
.appendAscii( ")" );
166 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
168 PyRef
dict( PyModule_GetDict( module
.get() ) );
172 static void readLoggingConfig( sal_Int32
*pLevel
, FILE **ppFile
)
174 *pLevel
= LogLevel::NONE
;
177 osl_getModuleURLFromFunctionAddress(
178 reinterpret_cast< oslGenericFunction
>(readLoggingConfig
),
179 (rtl_uString
**) &fileName
);
180 fileName
= fileName
.copy( fileName
.lastIndexOf( '/' )+1 );
181 #if HAVE_FEATURE_MACOSX_MACLIKE_APP_STRUCTURE
182 fileName
+= "../" LIBO_ETC_FOLDER
"/";
184 fileName
+= SAL_CONFIGFILE("pyuno" );
185 rtl::Bootstrap
bootstrapHandle( fileName
);
188 if( bootstrapHandle
.getFrom( "PYUNO_LOGLEVEL", str
) )
191 *pLevel
= LogLevel::NONE
;
192 else if ( str
== "CALL" )
193 *pLevel
= LogLevel::CALL
;
194 else if ( str
== "ARGS" )
195 *pLevel
= LogLevel::ARGS
;
198 fprintf( stderr
, "unknown loglevel %s\n",
199 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
202 if( *pLevel
> LogLevel::NONE
)
205 if( bootstrapHandle
.getFrom( "PYUNO_LOGTARGET", str
) )
207 if ( str
== "stdout" )
209 else if ( str
== "stderr" )
214 data
.Size
= sizeof( data
);
216 0 , osl_Process_IDENTIFIER
, &data
);
217 osl_getSystemPathFromFileURL( str
.pData
, &str
.pData
);
218 OString o
= OUStringToOString( str
, osl_getThreadTextEncoding() );
220 o
+= OString::number( data
.Ident
);
222 *ppFile
= fopen( o
.getStr() , "w" );
225 // do not buffer (useful if e.g. analyzing a crash)
226 setvbuf( *ppFile
, 0, _IONBF
, 0 );
230 fprintf( stderr
, "couldn't create file %s\n",
231 OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr() );
239 /*-------------------------------------------------------------------
240 RuntimeImpl implementations
241 *-------------------------------------------------------------------*/
242 PyRef
stRuntimeImpl::create( const Reference
< XComponentContext
> &ctx
)
243 throw( com::sun::star::uno::RuntimeException
)
245 RuntimeImpl
*me
= PyObject_New (RuntimeImpl
, &RuntimeImpl_Type
);
247 throw RuntimeException(
248 OUString( "cannot instantiate pyuno::RuntimeImpl" ),
249 Reference
< XInterface
> () );
251 // must use a different struct here, as the PyObject_New
252 // makes C++ unusable
253 RuntimeCargo
*c
= new RuntimeCargo();
254 readLoggingConfig( &(c
->logLevel
) , &(c
->logFile
) );
255 log( c
, LogLevel::CALL
, "Instantiating pyuno bridge" );
259 c
->xInvocation
= Reference
< XSingleServiceFactory
> (
260 ctx
->getServiceManager()->createInstanceWithContext(
261 OUString( "com.sun.star.script.Invocation" ),
264 if( ! c
->xInvocation
.is() )
265 throw RuntimeException(
266 OUString( "pyuno: couldn't instantiate invocation service" ),
267 Reference
< XInterface
> () );
269 c
->xTypeConverter
= Converter::create(ctx
);
270 if( ! c
->xTypeConverter
.is() )
271 throw RuntimeException(
272 OUString( "pyuno: couldn't instantiate typeconverter service" ),
273 Reference
< XInterface
> () );
275 c
->xCoreReflection
= theCoreReflection::get(ctx
);
277 c
->xAdapterFactory
= css::script::InvocationAdapterFactory::create(ctx
);
279 c
->xIntrospection
= Introspection::create(ctx
);
281 Any a
= ctx
->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
283 if( ! c
->xTdMgr
.is() )
284 throw RuntimeException(
285 OUString( "pyuno: couldn't retrieve typedescriptionmanager" ),
286 Reference
< XInterface
> () );
289 return PyRef( reinterpret_cast< PyObject
* > ( me
), SAL_NO_ACQUIRE
);
292 void stRuntimeImpl::del(PyObject
* self
)
294 RuntimeImpl
*me
= reinterpret_cast< RuntimeImpl
* > ( self
);
295 if( me
->cargo
->logFile
)
296 fclose( me
->cargo
->logFile
);
302 void Runtime::initialize( const Reference
< XComponentContext
> & ctx
)
303 throw ( RuntimeException
)
305 PyRef globalDict
, runtime
;
306 getRuntimeImpl( globalDict
, runtime
);
307 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
309 if( runtime
.is() && impl
->cargo
->valid
)
311 throw RuntimeException("pyuno runtime has already been initialized before",
312 Reference
< XInterface
> () );
314 PyRef
keep( RuntimeImpl::create( ctx
) );
315 PyDict_SetItemString( globalDict
.get(), "pyuno_runtime" , keep
.get() );
316 Py_XINCREF( keep
.get() );
320 bool Runtime::isInitialized() throw ( RuntimeException
)
322 PyRef globalDict
, runtime
;
323 getRuntimeImpl( globalDict
, runtime
);
324 RuntimeImpl
*impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
325 return runtime
.is() && impl
->cargo
->valid
;
328 Runtime::Runtime() throw( RuntimeException
)
331 PyRef globalDict
, runtime
;
332 getRuntimeImpl( globalDict
, runtime
);
335 throw RuntimeException(
336 OUString( "pyuno runtime is not initialized, "
337 "(the pyuno.bootstrap needs to be called before using any uno classes)"),
338 Reference
< XInterface
> () );
340 impl
= reinterpret_cast< RuntimeImpl
* > (runtime
.get());
341 Py_XINCREF( runtime
.get() );
344 Runtime::Runtime( const Runtime
& r
)
347 Py_XINCREF( reinterpret_cast< PyObject
* >(impl
) );
352 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
355 Runtime
& Runtime::operator = ( const Runtime
& r
)
357 PyRef
temp( reinterpret_cast< PyObject
* >(r
.impl
) );
358 Py_XINCREF( temp
.get() );
359 Py_XDECREF( reinterpret_cast< PyObject
* >(impl
) );
364 PyRef
Runtime::any2PyObject (const Any
&a
) const
365 throw ( com::sun::star::script::CannotConvertException
,
366 com::sun::star::lang::IllegalArgumentException
,
369 if( ! impl
->cargo
->valid
)
371 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject",
372 Reference
< XInterface
> () );
375 switch (a
.getValueTypeClass ())
377 case typelib_TypeClass_VOID
:
380 return PyRef(Py_None
);
382 case typelib_TypeClass_CHAR
:
384 sal_Unicode c
= *(sal_Unicode
*)a
.getValue();
385 return PyRef( PyUNO_char_new( c
, *this ), SAL_NO_ACQUIRE
);
387 case typelib_TypeClass_BOOLEAN
:
389 sal_Bool b
= sal_Bool();
395 case typelib_TypeClass_BYTE
:
396 case typelib_TypeClass_SHORT
:
397 case typelib_TypeClass_UNSIGNED_SHORT
:
398 case typelib_TypeClass_LONG
:
402 return PyRef( PyLong_FromLong (l
), SAL_NO_ACQUIRE
);
404 case typelib_TypeClass_UNSIGNED_LONG
:
408 return PyRef( PyLong_FromUnsignedLong (l
), SAL_NO_ACQUIRE
);
410 case typelib_TypeClass_HYPER
:
414 return PyRef( PyLong_FromLongLong (l
), SAL_NO_ACQUIRE
);
416 case typelib_TypeClass_UNSIGNED_HYPER
:
420 return PyRef( PyLong_FromUnsignedLongLong (l
), SAL_NO_ACQUIRE
);
422 case typelib_TypeClass_FLOAT
:
426 return PyRef(PyFloat_FromDouble (f
), SAL_NO_ACQUIRE
);
428 case typelib_TypeClass_DOUBLE
:
432 return PyRef( PyFloat_FromDouble (d
), SAL_NO_ACQUIRE
);
434 case typelib_TypeClass_STRING
:
438 return ustring2PyUnicode( tmp_ostr
);
440 case typelib_TypeClass_TYPE
:
444 OString o
= OUStringToOString( t
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
447 o
.getStr(), (com::sun::star::uno::TypeClass
)t
.getTypeClass(), *this),
450 case typelib_TypeClass_ANY
:
452 //I don't think this can happen.
456 case typelib_TypeClass_ENUM
:
458 sal_Int32 l
= *(sal_Int32
*) a
.getValue();
459 TypeDescription
desc( a
.getValueType() );
463 typelib_EnumTypeDescription
*pEnumDesc
=
464 (typelib_EnumTypeDescription
*) desc
.get();
465 for( int i
= 0 ; i
< pEnumDesc
->nEnumValues
; i
++ )
467 if( pEnumDesc
->pEnumValues
[i
] == l
)
469 OString v
= OUStringToOString( pEnumDesc
->ppEnumNames
[i
], RTL_TEXTENCODING_ASCII_US
);
470 OString e
= OUStringToOString( pEnumDesc
->aBase
.pTypeName
, RTL_TEXTENCODING_ASCII_US
);
471 return PyRef( PyUNO_Enum_new(e
.getStr(),v
.getStr(), *this ), SAL_NO_ACQUIRE
);
476 buf
.appendAscii( "Any carries enum " );
477 buf
.append( a
.getValueType().getTypeName());
478 buf
.appendAscii( " with invalid value " ).append( l
);
479 throw RuntimeException( buf
.makeStringAndClear() , Reference
< XInterface
> () );
481 case typelib_TypeClass_EXCEPTION
:
482 case typelib_TypeClass_STRUCT
:
484 PyRef excClass
= getClass( a
.getValueType().getTypeName(), *this );
485 PyRef value
= PyRef( PyUNO_new_UNCHECKED (a
, getImpl()->cargo
->xInvocation
), SAL_NO_ACQUIRE
);
486 PyRef
argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE
);
487 PyTuple_SetItem( argsTuple
.get() , 0 , value
.getAcquired() );
488 PyRef
ret( PyObject_CallObject( excClass
.get() , argsTuple
.get() ), SAL_NO_ACQUIRE
);
492 buf
.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
493 buf
.append( a
.getValueType().getTypeName() );
494 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
497 if( com::sun::star::uno::TypeClass_EXCEPTION
== a
.getValueTypeClass() )
499 // add the message in a standard python way !
500 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
);
502 // assuming that the Message is always the first member, wuuuu
503 void *pData
= (void*)a
.getValue();
504 OUString message
= *(OUString
* )pData
;
505 PyRef pymsg
= ustring2PyString( message
);
506 PyTuple_SetItem( args
.get(), 0 , pymsg
.getAcquired() );
507 // the exception base functions want to have an "args" tuple,
508 // which contains the message
509 PyObject_SetAttrString( ret
.get(), "args", args
.get() );
513 case typelib_TypeClass_SEQUENCE
:
517 Sequence
< sal_Int8
> byteSequence
;
518 if( a
>>= byteSequence
)
520 // byte sequence is treated in a special way because of peformance reasons
522 return PyRef( PyUNO_ByteSequence_new( byteSequence
, *this ), SAL_NO_ACQUIRE
);
526 Reference
< XTypeConverter
> tc
= getImpl()->cargo
->xTypeConverter
;
527 Reference
< XSingleServiceFactory
> ssf
= getImpl()->cargo
->xInvocation
;
528 tc
->convertTo (a
, ::getCppuType (&s
)) >>= s
;
529 PyRef
tuple( PyTuple_New (s
.getLength()), SAL_NO_ACQUIRE
);
533 for ( i
= 0; i
< s
.getLength (); i
++)
536 element
= any2PyObject (tc
->convertTo (s
[i
], s
[i
].getValueType() ));
537 OSL_ASSERT( element
.is() );
538 PyTuple_SetItem( tuple
.get(), i
, element
.getAcquired() );
541 catch( com::sun::star::uno::Exception
& )
543 for( ; i
< s
.getLength() ; i
++ )
545 Py_INCREF( Py_None
);
546 PyTuple_SetItem( tuple
.get(), i
, Py_None
);
553 case typelib_TypeClass_INTERFACE
:
555 Reference
< XUnoTunnel
> tunnel
;
559 sal_Int64 that
= tunnel
->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
561 return ((Adapter
*)sal::static_int_cast
< sal_IntPtr
>(that
))->getWrappedObject();
563 //This is just like the struct case:
564 return PyRef( PyUNO_new (a
, getImpl()->cargo
->xInvocation
), SAL_NO_ACQUIRE
);
569 buf
.appendAscii( "Unknonwn UNO type class " );
570 buf
.append( (sal_Int32
) a
.getValueTypeClass() );
571 throw RuntimeException(buf
.makeStringAndClear( ), Reference
< XInterface
> () );
576 static Sequence
< Type
> invokeGetTypes( const Runtime
& r
, PyObject
* o
)
578 Sequence
< Type
> ret
;
580 PyRef
method( PyObject_GetAttrString( o
, "getTypes" ), SAL_NO_ACQUIRE
);
581 raiseInvocationTargetExceptionWhenNeeded( r
);
582 if( method
.is() && PyCallable_Check( method
.get() ) )
584 PyRef
types( PyObject_CallObject( method
.get(), 0 ) , SAL_NO_ACQUIRE
);
585 raiseInvocationTargetExceptionWhenNeeded( r
);
586 if( types
.is() && PyTuple_Check( types
.get() ) )
588 int size
= PyTuple_Size( types
.get() );
590 // add the XUnoTunnel interface for uno object identity concept (hack)
591 ret
.realloc( size
+ 1 );
592 for( int i
= 0 ; i
< size
; i
++ )
594 Any a
= r
.pyObject2Any(PyTuple_GetItem(types
.get(),i
));
597 ret
[size
] = getCppuType( (Reference
< com::sun::star::lang::XUnoTunnel
> *) 0 );
604 lcl_ExceptionMessage(PyObject
*const o
, OUString
const*const pWrapped
)
607 buf
.appendAscii("Couldn't convert ");
608 PyRef
reprString( PyObject_Str(o
), SAL_NO_ACQUIRE
);
609 buf
.appendAscii( PyStr_AsString(reprString
.get()) );
610 buf
.appendAscii(" to a UNO type");
613 buf
.appendAscii("; caught exception: ");
614 buf
.append(*pWrapped
);
616 return buf
.makeStringAndClear();
619 Any
Runtime::pyObject2Any ( const PyRef
& source
, enum ConversionMode mode
) const
620 throw ( com::sun::star::uno::RuntimeException
)
622 if( ! impl
->cargo
->valid
)
624 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject",
625 Reference
< XInterface
> () );
629 PyObject
*o
= source
.get();
634 // In Python 3, there is no PyInt type.
635 #if PY_MAJOR_VERSION < 3
636 else if (PyInt_Check (o
))
640 sal_Bool b
= sal_True
;
641 a
= Any( &b
, getBooleanCppuType() );
643 else if ( o
== Py_False
)
645 sal_Bool b
= sal_False
;
646 a
= Any( &b
, getBooleanCppuType() );
650 sal_Int32 l
= (sal_Int32
) PyLong_AsLong( o
);
651 if( l
< 128 && l
>= -128 )
653 sal_Int8 b
= (sal_Int8
) l
;
656 else if( l
<= 0x7fff && l
>= -0x8000 )
658 sal_Int16 s
= (sal_Int16
) l
;
667 #endif /* PY_MAJOR_VERSION < 3 */
668 else if (PyLong_Check (o
))
670 #if PY_MAJOR_VERSION >= 3
671 // Convert the Python 3 booleans that are actually of type PyLong.
674 sal_Bool b
= sal_True
;
675 a
= Any(&b
, getBooleanCppuType());
677 else if(o
== Py_False
)
679 sal_Bool b
= sal_False
;
680 a
= Any(&b
, getBooleanCppuType());
684 #endif /* PY_MAJOR_VERSION >= 3 */
685 sal_Int64 l
= (sal_Int64
)PyLong_AsLong (o
);
686 if( l
< 128 && l
>= -128 )
688 sal_Int8 b
= (sal_Int8
) l
;
691 else if( l
<= 0x7fff && l
>= -0x8000 )
693 sal_Int16 s
= (sal_Int16
) l
;
696 else if( l
<= SAL_CONST_INT64(0x7fffffff) &&
697 l
>= -SAL_CONST_INT64(0x80000000) )
699 sal_Int32 l32
= (sal_Int32
) l
;
706 #if PY_MAJOR_VERSION >= 3
710 else if (PyFloat_Check (o
))
712 double d
= PyFloat_AsDouble (o
);
715 else if (PyStrBytes_Check(o
) || PyUnicode_Check(o
))
717 a
<<= pyString2ustring(o
);
719 else if (PyTuple_Check (o
))
721 Sequence
<Any
> s (PyTuple_Size (o
));
722 for (int i
= 0; i
< PyTuple_Size (o
); i
++)
724 s
[i
] = pyObject2Any (PyTuple_GetItem (o
, i
), mode
);
731 // should be removed, in case ByteSequence gets derived from String
732 if( PyObject_IsInstance( o
, getByteSequenceClass( runtime
).get() ) )
734 PyRef
str(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
735 Sequence
< sal_Int8
> seq
;
736 if( PyStrBytes_Check( str
.get() ) )
738 seq
= Sequence
<sal_Int8
> (
739 (sal_Int8
*) PyStrBytes_AsString(str
.get()), PyStrBytes_Size(str
.get()));
744 if( PyObject_IsInstance( o
, getTypeClass( runtime
).get() ) )
746 Type t
= PyType2Type( o
);
749 else if( PyObject_IsInstance( o
, getEnumClass( runtime
).get() ) )
751 a
= PyEnum2Enum( o
);
753 else if( isInstanceOfStructOrException( o
) )
755 PyRef
struc(PyObject_GetAttrString( o
, "value" ),SAL_NO_ACQUIRE
);
756 PyUNO
* obj
= (PyUNO
*)struc
.get();
757 Reference
< XMaterialHolder
> holder( obj
->members
->xInvocation
, UNO_QUERY
);
759 a
= holder
->getMaterial();
762 throw RuntimeException(
763 "struct or exception wrapper does not support XMaterialHolder",
764 Reference
< XInterface
> () );
767 else if( PyObject_IsInstance( o
, getPyUnoClass().get() ) )
771 if (o_pi
->members
->wrappedObject
.getValueTypeClass () ==
772 com::sun::star::uno::TypeClass_STRUCT
||
773 o_pi
->members
->wrappedObject
.getValueTypeClass () ==
774 com::sun::star::uno::TypeClass_EXCEPTION
)
776 Reference
<XMaterialHolder
> my_mh (o_pi
->members
->xInvocation
, UNO_QUERY
);
780 throw RuntimeException(
781 "struct wrapper does not support XMaterialHolder",
782 Reference
< XInterface
> () );
785 a
= my_mh
->getMaterial ();
789 a
= o_pi
->members
->wrappedObject
;
792 else if( PyObject_IsInstance( o
, getCharClass( runtime
).get() ) )
794 sal_Unicode c
= PyChar2Unicode( o
);
795 a
.setValue( &c
, getCharCppuType( ));
797 else if( PyObject_IsInstance( o
, getAnyClass( runtime
).get() ) )
799 if( ACCEPT_UNO_ANY
== mode
)
801 a
= pyObject2Any( PyRef( PyObject_GetAttrString( o
, "value" ), SAL_NO_ACQUIRE
) );
803 pyObject2Any( PyRef( PyObject_GetAttrString( o
, "type" ), SAL_NO_ACQUIRE
) ) >>= t
;
807 a
= getImpl()->cargo
->xTypeConverter
->convertTo( a
, t
);
809 catch( const com::sun::star::uno::Exception
& e
)
811 throw WrappedTargetRuntimeException(
812 e
.Message
, e
.Context
, makeAny(e
));
817 throw RuntimeException(
818 OUString( "uno.Any instance not accepted during method call, "
819 "use uno.invoke instead" ),
820 Reference
< XInterface
> () );
825 Reference
< XInterface
> mappedObject
;
826 Reference
< XInvocation
> adapterObject
;
828 // instance already mapped out to the world ?
829 PyRef2Adapter::iterator ii
= impl
->cargo
->mappedObjects
.find( PyRef( o
) );
830 if( ii
!= impl
->cargo
->mappedObjects
.end() )
832 adapterObject
= ii
->second
;
835 if( adapterObject
.is() )
837 // object got already bridged !
838 Reference
< com::sun::star::lang::XUnoTunnel
> tunnel( adapterObject
, UNO_QUERY
);
840 Adapter
*pAdapter
= ( Adapter
* )
841 sal::static_int_cast
< sal_IntPtr
>(
842 tunnel
->getSomething(
843 ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
845 mappedObject
= impl
->cargo
->xAdapterFactory
->createAdapter(
846 adapterObject
, pAdapter
->getWrappedTypes() );
851 Sequence
<Type
> interfaces
= invokeGetTypes(*this, o
);
852 if (interfaces
.getLength())
854 Adapter
*pAdapter
= new Adapter( o
, interfaces
);
856 getImpl()->cargo
->xAdapterFactory
->createAdapter(
857 pAdapter
, interfaces
);
859 // keep a list of exported objects to ensure object identity !
860 impl
->cargo
->mappedObjects
[ PyRef(o
) ] =
861 com::sun::star::uno::WeakReference
< XInvocation
> ( pAdapter
);
863 } catch (InvocationTargetException
const& e
) {
864 OUString
const msg(lcl_ExceptionMessage(o
, &e
.Message
));
865 throw WrappedTargetRuntimeException( // re-wrap that
866 msg
, e
.Context
, e
.TargetException
);
869 if( mappedObject
.is() )
871 a
= com::sun::star::uno::makeAny( mappedObject
);
875 OUString
const msg(lcl_ExceptionMessage(o
, 0));
876 throw RuntimeException(msg
, Reference
<XInterface
>());
883 Any
Runtime::extractUnoException( const PyRef
& excType
, const PyRef
&excValue
, const PyRef
&excTraceback
) const
887 if( excTraceback
.is() )
895 unoModule
= impl
->cargo
->getUnoModule();
897 catch (const Exception
&ei
)
904 PyRef
extractTraceback(
905 PyDict_GetItemString(unoModule
.get(),"_uno_extract_printable_stacktrace" ) );
907 if( PyCallable_Check(extractTraceback
.get()) )
909 PyRef
args( PyTuple_New( 1), SAL_NO_ACQUIRE
);
910 PyTuple_SetItem( args
.get(), 0, excTraceback
.getAcquired() );
911 PyRef
pyStr( PyObject_CallObject( extractTraceback
.get(),args
.get() ), SAL_NO_ACQUIRE
);
912 str
= OUString::createFromAscii( PyStr_AsString(pyStr
.get()) );
916 str
= "Couldn't find uno._uno_extract_printable_stacktrace";
921 str
= "Could not load uno.py, no stacktrace available";
922 if ( !e
.Message
.isEmpty() )
924 str
+= OUString (" (Error loading uno.py: ");
926 str
+= OUString (")");
933 // it may occur, that no traceback is given (e.g. only native code below)
934 str
= "no traceback available";
937 if( isInstanceOfStructOrException( excValue
.get() ) )
939 ret
= pyObject2Any( excValue
);
944 PyRef
typeName( PyObject_Str( excType
.get() ), SAL_NO_ACQUIRE
);
947 buf
.appendAscii( PyStr_AsString( typeName
.get() ) );
951 buf
.appendAscii( "no typename available" );
953 buf
.appendAscii( ": " );
954 PyRef
valueRep( PyObject_Str( excValue
.get() ), SAL_NO_ACQUIRE
);
957 buf
.appendAscii( PyStr_AsString( valueRep
.get()));
961 buf
.appendAscii( "Couldn't convert exception value to a string" );
963 buf
.appendAscii( ", traceback follows\n" );
967 buf
.appendAscii( "\n" );
971 buf
.appendAscii( ", no traceback available\n" );
974 e
.Message
= buf
.makeStringAndClear();
975 #if OSL_DEBUG_LEVEL > 0
976 fprintf( stderr
, "Python exception: %s\n",
977 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
979 ret
= com::sun::star::uno::makeAny( e
);
985 static const char * g_NUMERICID
= "pyuno.lcNumeric";
986 static ::std::vector
< OString
> g_localeList
;
988 static const char *ensureUnlimitedLifetime( const char *str
)
990 int size
= g_localeList
.size();
992 for( i
= 0 ; i
< size
; i
++ )
994 if( 0 == strcmp( g_localeList
[i
].getStr(), str
) )
999 g_localeList
.push_back( str
);
1001 return g_localeList
[i
].getStr();
1005 PyThreadAttach::PyThreadAttach( PyInterpreterState
*interp
)
1006 throw ( com::sun::star::uno::RuntimeException
)
1008 tstate
= PyThreadState_New( interp
);
1010 throw RuntimeException(
1011 OUString( "Couldn't create a pythreadstate" ),
1012 Reference
< XInterface
> () );
1013 PyEval_AcquireThread( tstate
);
1014 // set LC_NUMERIC to "C"
1015 const char * oldLocale
=
1016 ensureUnlimitedLifetime( setlocale( LC_NUMERIC
, 0 ) );
1017 setlocale( LC_NUMERIC
, "C" );
1018 PyRef
locale( // python requires C locale
1019 PyLong_FromVoidPtr( (void*)oldLocale
), SAL_NO_ACQUIRE
);
1020 PyDict_SetItemString(
1021 PyThreadState_GetDict(), g_NUMERICID
, locale
.get() );
1024 PyThreadAttach::~PyThreadAttach()
1027 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID
);
1029 setlocale( LC_NUMERIC
, (const char * ) PyLong_AsVoidPtr( value
) );
1030 PyThreadState_Clear( tstate
);
1031 PyEval_ReleaseThread( tstate
);
1032 PyThreadState_Delete( tstate
);
1036 PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException
)
1038 tstate
= PyThreadState_Get();
1040 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID
);
1042 setlocale( LC_NUMERIC
, (const char * ) PyLong_AsVoidPtr( value
) );
1043 PyEval_ReleaseThread( tstate
);
1046 /** Acquires the global interpreter lock again
1049 PyThreadDetach::~PyThreadDetach()
1051 PyEval_AcquireThread( tstate
);
1052 // PyObject *value =
1053 // PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1055 // python requires C LC_NUMERIC locale,
1056 // always set even when it is already "C"
1057 setlocale( LC_NUMERIC
, "C" );
1061 PyRef
RuntimeCargo::getUnoModule()
1063 if( ! dictUnoModule
.is() )
1065 dictUnoModule
= importUnoModule();
1067 return dictUnoModule
;
1071 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */