Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / pyuno / source / module / pyuno_runtime.cxx
blobbb7cb8e65d81c4bbcf690f0428722c0f9e9dc303
1 /* -*- Mode: C++; eval:(c-set-style "bsd"); tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
31 #include <locale.h>
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;
67 #include <vector>
69 namespace pyuno
72 static PyTypeObject RuntimeImpl_Type =
74 PyVarObject_HEAD_INIT (&PyType_Type, 0)
75 "pyuno_runtime",
76 sizeof (RuntimeImpl),
78 (destructor) RuntimeImpl::del,
79 (printfunc) 0,
80 (getattrfunc) 0,
81 (setattrfunc) 0,
83 (reprfunc) 0,
87 (hashfunc) 0,
88 (ternaryfunc) 0,
89 (reprfunc) 0,
90 (getattrofunc)0,
91 (setattrofunc)0,
92 NULL,
94 NULL,
95 (traverseproc)0,
96 (inquiry)0,
97 (richcmpfunc)0,
99 (getiterfunc)0,
100 (iternextfunc)0,
101 NULL,
102 NULL,
103 NULL,
104 NULL,
105 NULL,
106 (descrgetfunc)0,
107 (descrsetfunc)0,
109 (initproc)0,
110 (allocfunc)0,
111 (newfunc)0,
112 (freefunc)0,
113 (inquiry)0,
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 (destructor)0
120 #if PY_VERSION_HEX >= 0x02060000
122 #endif
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();
132 if( ! state )
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 );
160 OUStringBuffer buf;
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() ) );
169 return dict;
172 static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
174 *pLevel = LogLevel::NONE;
175 *ppFile = 0;
176 OUString fileName;
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 "/";
183 #endif
184 fileName += SAL_CONFIGFILE("pyuno" );
185 rtl::Bootstrap bootstrapHandle( fileName );
187 OUString str;
188 if( bootstrapHandle.getFrom( "PYUNO_LOGLEVEL", str ) )
190 if ( str == "NONE" )
191 *pLevel = LogLevel::NONE;
192 else if ( str == "CALL" )
193 *pLevel = LogLevel::CALL;
194 else if ( str == "ARGS" )
195 *pLevel = LogLevel::ARGS;
196 else
198 fprintf( stderr, "unknown loglevel %s\n",
199 OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
202 if( *pLevel > LogLevel::NONE )
204 *ppFile = stdout;
205 if( bootstrapHandle.getFrom( "PYUNO_LOGTARGET", str ) )
207 if ( str == "stdout" )
208 *ppFile = stdout;
209 else if ( str == "stderr" )
210 *ppFile = stderr;
211 else
213 oslProcessInfo data;
214 data.Size = sizeof( data );
215 osl_getProcessInfo(
216 0 , osl_Process_IDENTIFIER , &data );
217 osl_getSystemPathFromFileURL( str.pData, &str.pData);
218 OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
219 o += ".";
220 o += OString::number( data.Ident );
222 *ppFile = fopen( o.getStr() , "w" );
223 if ( *ppFile )
225 // do not buffer (useful if e.g. analyzing a crash)
226 setvbuf( *ppFile, 0, _IONBF, 0 );
228 else
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);
246 if( ! me )
247 throw RuntimeException(
248 OUString( "cannot instantiate pyuno::RuntimeImpl" ),
249 Reference< XInterface > () );
250 me->cargo = 0;
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" );
257 c->valid = 1;
258 c->xContext = ctx;
259 c->xInvocation = Reference< XSingleServiceFactory > (
260 ctx->getServiceManager()->createInstanceWithContext(
261 OUString( "com.sun.star.script.Invocation" ),
262 ctx ),
263 UNO_QUERY );
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");
282 a >>= c->xTdMgr;
283 if( ! c->xTdMgr.is() )
284 throw RuntimeException(
285 OUString( "pyuno: couldn't retrieve typedescriptionmanager" ),
286 Reference< XInterface > () );
288 me->cargo =c;
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 );
297 delete me->cargo;
298 PyObject_Del (self);
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 )
329 : impl( 0 )
331 PyRef globalDict, runtime;
332 getRuntimeImpl( globalDict , runtime );
333 if( ! runtime.is() )
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 )
346 impl = r.impl;
347 Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
350 Runtime::~Runtime()
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) );
360 impl = r.impl;
361 return *this;
364 PyRef Runtime::any2PyObject (const Any &a ) const
365 throw ( com::sun::star::script::CannotConvertException,
366 com::sun::star::lang::IllegalArgumentException,
367 RuntimeException)
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:
379 Py_INCREF (Py_None);
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();
390 if ((a >>= b) && b)
391 return Py_True;
392 else
393 return Py_False;
395 case typelib_TypeClass_BYTE:
396 case typelib_TypeClass_SHORT:
397 case typelib_TypeClass_UNSIGNED_SHORT:
398 case typelib_TypeClass_LONG:
400 sal_Int32 l = 0;
401 a >>= l;
402 return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
404 case typelib_TypeClass_UNSIGNED_LONG:
406 sal_uInt32 l = 0;
407 a >>= l;
408 return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
410 case typelib_TypeClass_HYPER:
412 sal_Int64 l = 0;
413 a >>= l;
414 return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
416 case typelib_TypeClass_UNSIGNED_HYPER:
418 sal_uInt64 l = 0;
419 a >>= l;
420 return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
422 case typelib_TypeClass_FLOAT:
424 float f = 0.0;
425 a >>= f;
426 return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
428 case typelib_TypeClass_DOUBLE:
430 double d = 0.0;
431 a >>= d;
432 return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
434 case typelib_TypeClass_STRING:
436 OUString tmp_ostr;
437 a >>= tmp_ostr;
438 return ustring2PyUnicode( tmp_ostr );
440 case typelib_TypeClass_TYPE:
442 Type t;
443 a >>= t;
444 OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
445 return PyRef(
446 PyUNO_Type_new (
447 o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
448 SAL_NO_ACQUIRE);
450 case typelib_TypeClass_ANY:
452 //I don't think this can happen.
453 Py_INCREF (Py_None);
454 return Py_None;
456 case typelib_TypeClass_ENUM:
458 sal_Int32 l = *(sal_Int32 *) a.getValue();
459 TypeDescription desc( a.getValueType() );
460 if( desc.is() )
462 desc.makeComplete();
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 );
475 OUStringBuffer buf;
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 );
489 if( ! ret.is() )
491 OUStringBuffer buf;
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() );
511 return ret;
513 case typelib_TypeClass_SEQUENCE:
515 Sequence<Any> s;
517 Sequence< sal_Int8 > byteSequence;
518 if( a >>= byteSequence )
520 // byte sequence is treated in a special way because of peformance reasons
521 // @since 0.9.2
522 return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
524 else
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);
530 int i=0;
533 for ( i = 0; i < s.getLength (); i++)
535 PyRef element;
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 );
548 throw;
550 return tuple;
553 case typelib_TypeClass_INTERFACE:
555 Reference< XUnoTunnel > tunnel;
556 a >>= tunnel;
557 if( tunnel.is() )
559 sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
560 if( that )
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 );
566 default:
568 OUStringBuffer buf;
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));
595 a >>= ret[i];
597 ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
600 return ret;
603 static OUString
604 lcl_ExceptionMessage(PyObject *const o, OUString const*const pWrapped)
606 OUStringBuffer buf;
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");
611 if (pWrapped)
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 > () );
628 Any a;
629 PyObject *o = source.get();
630 if( Py_None == o )
634 // In Python 3, there is no PyInt type.
635 #if PY_MAJOR_VERSION < 3
636 else if (PyInt_Check (o))
638 if( o == Py_True )
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() );
648 else
650 sal_Int32 l = (sal_Int32) PyLong_AsLong( o );
651 if( l < 128 && l >= -128 )
653 sal_Int8 b = (sal_Int8 ) l;
654 a <<= b;
656 else if( l <= 0x7fff && l >= -0x8000 )
658 sal_Int16 s = (sal_Int16) l;
659 a <<= s;
661 else
663 a <<= 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.
672 if(o == Py_True)
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());
682 else
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;
689 a <<= b;
691 else if( l <= 0x7fff && l >= -0x8000 )
693 sal_Int16 s = (sal_Int16) l;
694 a <<= s;
696 else if( l <= SAL_CONST_INT64(0x7fffffff) &&
697 l >= -SAL_CONST_INT64(0x80000000) )
699 sal_Int32 l32 = (sal_Int32) l;
700 a <<= l32;
702 else
704 a <<= l;
706 #if PY_MAJOR_VERSION >= 3
708 #endif
710 else if (PyFloat_Check (o))
712 double d = PyFloat_AsDouble (o);
713 a <<= d;
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 );
726 a <<= s;
728 else
730 Runtime runtime;
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()));
741 a <<= seq;
743 else
744 if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
746 Type t = PyType2Type( o );
747 a <<= t;
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 );
758 if( holder.is( ) )
759 a = holder->getMaterial();
760 else
762 throw RuntimeException(
763 "struct or exception wrapper does not support XMaterialHolder",
764 Reference< XInterface > () );
767 else if( PyObject_IsInstance( o, getPyUnoClass().get() ) )
769 PyUNO* o_pi;
770 o_pi = (PyUNO*) o;
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);
778 if (!my_mh.is ())
780 throw RuntimeException(
781 "struct wrapper does not support XMaterialHolder",
782 Reference< XInterface > () );
784 else
785 a = my_mh->getMaterial ();
787 else
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) );
802 Type t;
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));
815 else
817 throw RuntimeException(
818 OUString( "uno.Any instance not accepted during method call, "
819 "use uno.invoke instead" ),
820 Reference< XInterface > () );
823 else
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() );
848 else
850 try {
851 Sequence<Type> interfaces = invokeGetTypes(*this, o);
852 if (interfaces.getLength())
854 Adapter *pAdapter = new Adapter( o, interfaces );
855 mappedObject =
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 );
873 else
875 OUString const msg(lcl_ExceptionMessage(o, 0));
876 throw RuntimeException(msg, Reference<XInterface>());
880 return a;
883 Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
885 OUString str;
886 Any ret;
887 if( excTraceback.is() )
889 Exception e;
890 PyRef unoModule;
891 if ( impl )
895 unoModule = impl->cargo->getUnoModule();
897 catch (const Exception &ei)
899 e=ei;
902 if( unoModule.is() )
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()) );
914 else
916 str = "Couldn't find uno._uno_extract_printable_stacktrace";
919 else
921 str = "Could not load uno.py, no stacktrace available";
922 if ( !e.Message.isEmpty() )
924 str += OUString (" (Error loading uno.py: ");
925 str += e.Message;
926 str += OUString (")");
931 else
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 );
941 else
943 OUStringBuffer buf;
944 PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
945 if( typeName.is() )
947 buf.appendAscii( PyStr_AsString( typeName.get() ) );
949 else
951 buf.appendAscii( "no typename available" );
953 buf.appendAscii( ": " );
954 PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
955 if( valueRep.is() )
957 buf.appendAscii( PyStr_AsString( valueRep.get()));
959 else
961 buf.appendAscii( "Couldn't convert exception value to a string" );
963 buf.appendAscii( ", traceback follows\n" );
964 if( !str.isEmpty() )
966 buf.append( str );
967 buf.appendAscii( "\n" );
969 else
971 buf.appendAscii( ", no traceback available\n" );
973 RuntimeException e;
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() );
978 #endif
979 ret = com::sun::star::uno::makeAny( e );
981 return ret;
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();
991 int i;
992 for( i = 0 ; i < size ; i ++ )
994 if( 0 == strcmp( g_localeList[i].getStr(), str ) )
995 break;
997 if( i == size )
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 );
1009 if( !tstate )
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()
1026 PyObject *value =
1027 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1028 if( value )
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();
1039 PyObject *value =
1040 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1041 if( value )
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: */