update emoji autocorrect entries from po-files
[LibreOffice.git] / pyuno / source / module / pyuno_runtime.cxx
blobe0f58ae2c08db5cf7c3fba2155e905e261e1714f
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/diagnose.h>
26 #include <osl/thread.h>
27 #include <osl/module.h>
28 #include <osl/process.h>
29 #include <rtl/strbuf.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #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/theIntrospection.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::theIntrospection;
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
123 #if PY_VERSION_HEX >= 0x03040000
125 #endif
128 /*----------------------------------------------------------------------
129 Runtime implementation
130 -----------------------------------------------------------------------*/
131 static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl )
132 throw ( com::sun::star::uno::RuntimeException )
134 PyThreadState * state = PyThreadState_Get();
135 if( ! state )
137 throw RuntimeException( "python global interpreter must be held (thread must be attached)" );
140 PyObject* pModule = PyImport_AddModule("__main__");
142 if (!pModule)
144 throw RuntimeException("can't import __main__ module");
147 globalDict = PyRef( PyModule_GetDict(pModule));
149 if( ! globalDict.is() ) // FATAL !
151 throw RuntimeException("can't find __main__ module");
153 runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" );
156 static PyRef importUnoModule( ) throw ( RuntimeException )
158 // import the uno module
159 PyRef module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE, NOT_NULL );
160 if( PyErr_Occurred() )
162 PyRef excType, excValue, excTraceback;
163 PyErr_Fetch( reinterpret_cast<PyObject **>(&excType), reinterpret_cast<PyObject**>(&excValue), reinterpret_cast<PyObject**>(&excTraceback));
164 // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
165 // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
166 // Who knows, a future Python might print something better.
167 PyRef str( PyObject_Str( excTraceback.get() ), SAL_NO_ACQUIRE );
169 OUStringBuffer buf;
170 buf.appendAscii( "python object raised an unknown exception (" );
171 PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
172 buf.appendAscii( PyStr_AsString( valueRep.get())).appendAscii( ", traceback follows\n" );
173 buf.appendAscii( PyStr_AsString( str.get() ) );
174 buf.appendAscii( ")" );
175 throw RuntimeException( buf.makeStringAndClear() );
177 PyRef dict( PyModule_GetDict( module.get() ) );
178 return dict;
181 static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
183 *pLevel = LogLevel::NONE;
184 *ppFile = 0;
185 OUString fileName;
186 osl_getModuleURLFromFunctionAddress(
187 reinterpret_cast< oslGenericFunction >(readLoggingConfig),
188 &fileName.pData );
189 fileName = fileName.copy( fileName.lastIndexOf( '/' )+1 );
190 #ifdef MACOSX
191 fileName += "../" LIBO_ETC_FOLDER "/";
192 #endif
193 fileName += SAL_CONFIGFILE("pyuno" );
194 rtl::Bootstrap bootstrapHandle( fileName );
196 OUString str;
197 if( bootstrapHandle.getFrom( "PYUNO_LOGLEVEL", str ) )
199 if ( str == "NONE" )
200 *pLevel = LogLevel::NONE;
201 else if ( str == "CALL" )
202 *pLevel = LogLevel::CALL;
203 else if ( str == "ARGS" )
204 *pLevel = LogLevel::ARGS;
205 else
207 fprintf( stderr, "unknown loglevel %s\n",
208 OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
211 if( *pLevel > LogLevel::NONE )
213 *ppFile = stdout;
214 if( bootstrapHandle.getFrom( "PYUNO_LOGTARGET", str ) )
216 if ( str == "stdout" )
217 *ppFile = stdout;
218 else if ( str == "stderr" )
219 *ppFile = stderr;
220 else
222 oslProcessInfo data;
223 data.Size = sizeof( data );
224 osl_getProcessInfo(
225 0 , osl_Process_IDENTIFIER , &data );
226 osl_getSystemPathFromFileURL( str.pData, &str.pData);
227 OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
228 o += ".";
229 o += OString::number( data.Ident );
231 *ppFile = fopen( o.getStr() , "w" );
232 if ( *ppFile )
234 // do not buffer (useful if e.g. analyzing a crash)
235 setvbuf( *ppFile, 0, _IONBF, 0 );
237 else
239 fprintf( stderr, "couldn't create file %s\n",
240 OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
248 /*-------------------------------------------------------------------
249 RuntimeImpl implementations
250 *-------------------------------------------------------------------*/
251 PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx )
252 throw( com::sun::star::uno::RuntimeException )
254 RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type);
255 if( ! me )
256 throw RuntimeException( "cannot instantiate pyuno::RuntimeImpl" );
257 me->cargo = 0;
258 // must use a different struct here, as the PyObject_New
259 // makes C++ unusable
260 RuntimeCargo *c = new RuntimeCargo();
261 readLoggingConfig( &(c->logLevel) , &(c->logFile) );
262 log( c, LogLevel::CALL, "Instantiating pyuno bridge" );
264 c->valid = true;
265 c->xContext = ctx;
266 c->xInvocation = Reference< XSingleServiceFactory > (
267 ctx->getServiceManager()->createInstanceWithContext(
268 OUString( "com.sun.star.script.Invocation" ),
269 ctx ),
270 UNO_QUERY );
271 if( ! c->xInvocation.is() )
272 throw RuntimeException( "pyuno: couldn't instantiate invocation service" );
274 c->xTypeConverter = Converter::create(ctx);
275 if( ! c->xTypeConverter.is() )
276 throw RuntimeException( "pyuno: couldn't instantiate typeconverter service" );
278 c->xCoreReflection = theCoreReflection::get(ctx);
280 c->xAdapterFactory = css::script::InvocationAdapterFactory::create(ctx);
282 c->xIntrospection = theIntrospection::get(ctx);
284 Any a = ctx->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
285 a >>= c->xTdMgr;
286 if( ! c->xTdMgr.is() )
287 throw RuntimeException( "pyuno: couldn't retrieve typedescriptionmanager" );
289 me->cargo =c;
290 return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE );
293 void stRuntimeImpl::del(PyObject* self)
295 RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self );
296 if( me->cargo->logFile )
297 fclose( me->cargo->logFile );
298 delete me->cargo;
299 PyObject_Del (self);
303 void Runtime::initialize( const Reference< XComponentContext > & ctx )
304 throw ( RuntimeException )
306 PyRef globalDict, runtime;
307 getRuntimeImpl( globalDict , runtime );
308 RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
310 if( runtime.is() && impl->cargo->valid )
312 throw RuntimeException("pyuno runtime has already been initialized before" );
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 "pyuno runtime is not initialized, "
337 "(the pyuno.bootstrap needs to be called before using any uno classes)" );
339 impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
340 Py_XINCREF( runtime.get() );
343 Runtime::Runtime( const Runtime & r )
345 impl = r.impl;
346 Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
349 Runtime::~Runtime()
351 Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
354 Runtime & Runtime::operator = ( const Runtime & r )
356 PyRef temp( reinterpret_cast< PyObject * >(r.impl) );
357 Py_XINCREF( temp.get() );
358 Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
359 impl = r.impl;
360 return *this;
363 PyRef Runtime::any2PyObject (const Any &a ) const
364 throw ( com::sun::star::script::CannotConvertException,
365 com::sun::star::lang::IllegalArgumentException,
366 RuntimeException)
368 if( ! impl->cargo->valid )
370 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
373 switch (a.getValueTypeClass ())
375 case typelib_TypeClass_VOID:
377 Py_INCREF (Py_None);
378 return PyRef(Py_None);
380 case typelib_TypeClass_CHAR:
382 sal_Unicode c = *static_cast<sal_Unicode const *>(a.getValue());
383 return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE );
385 case typelib_TypeClass_BOOLEAN:
387 bool b;
388 if ((a >>= b) && b)
389 return Py_True;
390 else
391 return Py_False;
393 case typelib_TypeClass_BYTE:
394 case typelib_TypeClass_SHORT:
395 case typelib_TypeClass_UNSIGNED_SHORT:
396 case typelib_TypeClass_LONG:
398 sal_Int32 l = 0;
399 a >>= l;
400 return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
402 case typelib_TypeClass_UNSIGNED_LONG:
404 sal_uInt32 l = 0;
405 a >>= l;
406 return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
408 case typelib_TypeClass_HYPER:
410 sal_Int64 l = 0;
411 a >>= l;
412 return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
414 case typelib_TypeClass_UNSIGNED_HYPER:
416 sal_uInt64 l = 0;
417 a >>= l;
418 return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
420 case typelib_TypeClass_FLOAT:
422 float f = 0.0;
423 a >>= f;
424 return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
426 case typelib_TypeClass_DOUBLE:
428 double d = 0.0;
429 a >>= d;
430 return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
432 case typelib_TypeClass_STRING:
434 OUString tmp_ostr;
435 a >>= tmp_ostr;
436 return ustring2PyUnicode( tmp_ostr );
438 case typelib_TypeClass_TYPE:
440 Type t;
441 a >>= t;
442 OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
443 return PyRef(
444 PyUNO_Type_new (
445 o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
446 SAL_NO_ACQUIRE);
448 case typelib_TypeClass_ANY:
450 //I don't think this can happen.
451 Py_INCREF (Py_None);
452 return Py_None;
454 case typelib_TypeClass_ENUM:
456 sal_Int32 l = *static_cast<sal_Int32 const *>(a.getValue());
457 TypeDescription desc( a.getValueType() );
458 if( desc.is() )
460 desc.makeComplete();
461 typelib_EnumTypeDescription *pEnumDesc =
462 reinterpret_cast<typelib_EnumTypeDescription *>(desc.get());
463 for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ )
465 if( pEnumDesc->pEnumValues[i] == l )
467 OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US);
468 OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US);
469 return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE );
473 OUStringBuffer buf;
474 buf.appendAscii( "Any carries enum " );
475 buf.append( a.getValueType().getTypeName());
476 buf.appendAscii( " with invalid value " ).append( l );
477 throw RuntimeException( buf.makeStringAndClear() );
479 case typelib_TypeClass_EXCEPTION:
480 case typelib_TypeClass_STRUCT:
482 PyRef excClass = getClass( a.getValueType().getTypeName(), *this );
483 PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE);
484 PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE, NOT_NULL );
485 PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() );
486 PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE );
487 if( ! ret.is() )
489 OUStringBuffer buf;
490 buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
491 buf.append( a.getValueType().getTypeName() );
492 throw RuntimeException( buf.makeStringAndClear() );
495 if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() )
497 // add the message in a standard python way !
498 PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE, NOT_NULL );
500 // assuming that the Message is always the first member, wuuuu
501 void const *pData = a.getValue();
502 OUString message = *static_cast<OUString const *>(pData);
503 PyRef pymsg = ustring2PyString( message );
504 PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() );
505 // the exception base functions want to have an "args" tuple,
506 // which contains the message
507 PyObject_SetAttrString( ret.get(), "args", args.get() );
509 return ret;
511 case typelib_TypeClass_SEQUENCE:
513 Sequence<Any> s;
515 Sequence< sal_Int8 > byteSequence;
516 if( a >>= byteSequence )
518 // byte sequence is treated in a special way because of peformance reasons
519 // @since 0.9.2
520 return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
522 else
524 Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter;
525 Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation;
526 tc->convertTo (a, cppu::UnoType<decltype(s)>::get()) >>= s;
527 PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE, NOT_NULL);
528 int i=0;
531 for ( i = 0; i < s.getLength (); i++)
533 PyRef element;
534 element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() ));
535 OSL_ASSERT( element.is() );
536 PyTuple_SetItem( tuple.get(), i, element.getAcquired() );
539 catch( com::sun::star::uno::Exception & )
541 for( ; i < s.getLength() ; i ++ )
543 Py_INCREF( Py_None );
544 PyTuple_SetItem( tuple.get(), i, Py_None );
546 throw;
548 return tuple;
551 case typelib_TypeClass_INTERFACE:
553 // fdo#46678 must unlock GIL because getSomething could acquire locks,
554 // and queryInterface too...
556 PyThreadDetach d;
558 Reference<XUnoTunnel> tunnel;
559 a >>= tunnel;
560 if (tunnel.is())
562 sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
563 if( that )
564 return reinterpret_cast<Adapter*>(that)->getWrappedObject();
567 //This is just like the struct case:
568 return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE );
570 default:
572 OUStringBuffer buf;
573 buf.appendAscii( "Unknown UNO type class " );
574 buf.append( (sal_Int32 ) a.getValueTypeClass() );
575 throw RuntimeException(buf.makeStringAndClear( ) );
580 static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o )
582 Sequence< Type > ret;
584 PyRef method( PyObject_GetAttrString( o , "getTypes" ), SAL_NO_ACQUIRE );
585 raiseInvocationTargetExceptionWhenNeeded( r );
586 if( method.is() && PyCallable_Check( method.get() ) )
588 PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE );
589 raiseInvocationTargetExceptionWhenNeeded( r );
590 if( types.is() && PyTuple_Check( types.get() ) )
592 int size = PyTuple_Size( types.get() );
594 // add the XUnoTunnel interface for uno object identity concept (hack)
595 ret.realloc( size + 1 );
596 for( int i = 0 ; i < size ; i ++ )
598 Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i));
599 a >>= ret[i];
601 ret[size] = cppu::UnoType<com::sun::star::lang::XUnoTunnel>::get();
604 return ret;
607 static OUString
608 lcl_ExceptionMessage(PyObject *const o, OUString const*const pWrapped)
610 OUStringBuffer buf;
611 buf.appendAscii("Couldn't convert ");
612 PyRef reprString( PyObject_Str(o), SAL_NO_ACQUIRE );
613 buf.appendAscii( PyStr_AsString(reprString.get()) );
614 buf.appendAscii(" to a UNO type");
615 if (pWrapped)
617 buf.appendAscii("; caught exception: ");
618 buf.append(*pWrapped);
620 return buf.makeStringAndClear();
623 Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const
624 throw ( com::sun::star::uno::RuntimeException )
626 if( ! impl->cargo->valid )
628 throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject" );
631 Any a;
632 PyObject *o = source.get();
633 if( Py_None == o )
637 // In Python 3, there is no PyInt type.
638 #if PY_MAJOR_VERSION < 3
639 else if (PyInt_Check (o))
641 if( o == Py_True )
643 sal_Bool b = sal_True;
644 a = Any( &b, cppu::UnoType<bool>::get() );
646 else if ( o == Py_False )
648 sal_Bool b = sal_False;
649 a = Any( &b, cppu::UnoType<bool>::get() );
651 else
653 sal_Int32 l = (sal_Int32) PyLong_AsLong( o );
654 if( l < 128 && l >= -128 )
656 sal_Int8 b = (sal_Int8 ) l;
657 a <<= b;
659 else if( l <= 0x7fff && l >= -0x8000 )
661 sal_Int16 s = (sal_Int16) l;
662 a <<= s;
664 else
666 a <<= l;
670 #endif /* PY_MAJOR_VERSION < 3 */
671 else if (PyLong_Check (o))
673 #if PY_MAJOR_VERSION >= 3
674 // Convert the Python 3 booleans that are actually of type PyLong.
675 if(o == Py_True)
677 sal_Bool b = sal_True;
678 a = Any(&b, cppu::UnoType<bool>::get());
680 else if(o == Py_False)
682 sal_Bool b = sal_False;
683 a = Any(&b, cppu::UnoType<bool>::get());
685 else
687 #endif /* PY_MAJOR_VERSION >= 3 */
688 sal_Int64 l = (sal_Int64)PyLong_AsLong (o);
689 if( l < 128 && l >= -128 )
691 sal_Int8 b = (sal_Int8 ) l;
692 a <<= b;
694 else if( l <= 0x7fff && l >= -0x8000 )
696 sal_Int16 s = (sal_Int16) l;
697 a <<= s;
699 else if( l <= SAL_CONST_INT64(0x7fffffff) &&
700 l >= -SAL_CONST_INT64(0x80000000) )
702 sal_Int32 l32 = (sal_Int32) l;
703 a <<= l32;
705 else
707 a <<= l;
709 #if PY_MAJOR_VERSION >= 3
711 #endif
713 else if (PyFloat_Check (o))
715 double d = PyFloat_AsDouble (o);
716 a <<= d;
718 else if (PyStrBytes_Check(o) || PyUnicode_Check(o))
720 a <<= pyString2ustring(o);
722 else if (PyTuple_Check (o))
724 Sequence<Any> s (PyTuple_Size (o));
725 for (int i = 0; i < PyTuple_Size (o); i++)
727 s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
729 a <<= s;
731 else
733 Runtime runtime;
734 // should be removed, in case ByteSequence gets derived from String
735 if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) )
737 PyRef str(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE);
738 Sequence< sal_Int8 > seq;
739 if( PyStrBytes_Check( str.get() ) )
741 seq = Sequence<sal_Int8 > (
742 reinterpret_cast<sal_Int8*>(PyStrBytes_AsString(str.get())), PyStrBytes_Size(str.get()));
744 a <<= seq;
746 else
747 if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
749 Type t = PyType2Type( o );
750 a <<= t;
752 else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) )
754 a = PyEnum2Enum( o );
756 else if( isInstanceOfStructOrException( o ) )
758 PyRef struc(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE);
759 PyUNO * obj = reinterpret_cast<PyUNO*>(struc.get());
760 Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY );
761 if( holder.is( ) )
762 a = holder->getMaterial();
763 else
765 throw RuntimeException(
766 "struct or exception wrapper does not support XMaterialHolder" );
769 else if( PyObject_IsInstance( o, getPyUnoClass().get() ) )
771 PyUNO* o_pi;
772 o_pi = reinterpret_cast<PyUNO*>(o);
773 if (o_pi->members->wrappedObject.getValueTypeClass () ==
774 com::sun::star::uno::TypeClass_STRUCT ||
775 o_pi->members->wrappedObject.getValueTypeClass () ==
776 com::sun::star::uno::TypeClass_EXCEPTION)
778 Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY);
780 if (!my_mh.is ())
782 throw RuntimeException(
783 "struct wrapper does not support XMaterialHolder" );
785 else
786 a = my_mh->getMaterial ();
788 else
790 a = o_pi->members->wrappedObject;
793 else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) )
795 sal_Unicode c = PyChar2Unicode( o );
796 a.setValue( &c, cppu::UnoType<cppu::UnoCharType>::get());
798 else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
800 if( ACCEPT_UNO_ANY == mode )
802 a = pyObject2Any( PyRef( PyObject_GetAttrString( o , "value" ), SAL_NO_ACQUIRE) );
803 Type t;
804 pyObject2Any( PyRef( PyObject_GetAttrString( o, "type" ), SAL_NO_ACQUIRE ) ) >>= t;
808 a = getImpl()->cargo->xTypeConverter->convertTo( a, t );
810 catch( const com::sun::star::uno::Exception & e )
812 throw WrappedTargetRuntimeException(
813 e.Message, e.Context, makeAny(e));
816 else
818 throw RuntimeException(
819 "uno.Any instance not accepted during method call, "
820 "use uno.invoke instead" );
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 = reinterpret_cast<Adapter*>(
841 tunnel->getSomething(
842 ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
844 mappedObject = impl->cargo->xAdapterFactory->createAdapter(
845 adapterObject, pAdapter->getWrappedTypes() );
847 else
849 try {
850 Sequence<Type> interfaces = invokeGetTypes(*this, o);
851 if (interfaces.getLength())
853 Adapter *pAdapter = new Adapter( o, interfaces );
854 mappedObject =
855 getImpl()->cargo->xAdapterFactory->createAdapter(
856 pAdapter, interfaces );
858 // keep a list of exported objects to ensure object identity !
859 impl->cargo->mappedObjects[ PyRef(o) ] =
860 com::sun::star::uno::WeakReference< XInvocation > ( pAdapter );
862 } catch (InvocationTargetException const& e) {
863 OUString const msg(lcl_ExceptionMessage(o, &e.Message));
864 throw WrappedTargetRuntimeException( // re-wrap that
865 msg, e.Context, e.TargetException);
868 if( mappedObject.is() )
870 a = com::sun::star::uno::makeAny( mappedObject );
872 else
874 OUString const msg(lcl_ExceptionMessage(o, 0));
875 throw RuntimeException(msg);
879 return a;
882 Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
884 OUString str;
885 Any ret;
886 if( excTraceback.is() )
888 Exception e;
889 PyRef unoModule;
890 if ( impl )
894 unoModule = impl->cargo->getUnoModule();
896 catch (const Exception &ei)
898 e=ei;
901 if( unoModule.is() )
903 PyRef extractTraceback(
904 PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) );
906 if( PyCallable_Check(extractTraceback.get()) )
908 PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE, NOT_NULL );
909 PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
910 PyRef pyStr( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
911 str = OUString::createFromAscii( PyStr_AsString(pyStr.get()) );
913 else
915 str = "Couldn't find uno._uno_extract_printable_stacktrace";
918 else
920 str = "Could not load uno.py, no stacktrace available";
921 if ( !e.Message.isEmpty() )
923 str += OUString (" (Error loading uno.py: ");
924 str += e.Message;
925 str += OUString (")");
930 else
932 // it may occur, that no traceback is given (e.g. only native code below)
933 str = "no traceback available";
936 if( isInstanceOfStructOrException( excValue.get() ) )
938 ret = pyObject2Any( excValue );
940 else
942 OUStringBuffer buf;
943 PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
944 if( typeName.is() )
946 buf.appendAscii( PyStr_AsString( typeName.get() ) );
948 else
950 buf.appendAscii( "no typename available" );
952 buf.appendAscii( ": " );
953 PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
954 if( valueRep.is() )
956 buf.appendAscii( PyStr_AsString( valueRep.get()));
958 else
960 buf.appendAscii( "Couldn't convert exception value to a string" );
962 buf.appendAscii( ", traceback follows\n" );
963 if( !str.isEmpty() )
965 buf.append( str );
966 buf.appendAscii( "\n" );
968 else
970 buf.appendAscii( ", no traceback available\n" );
972 RuntimeException e;
973 e.Message = buf.makeStringAndClear();
974 #if OSL_DEBUG_LEVEL > 0
975 fprintf( stderr, "Python exception: %s\n",
976 OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() );
977 #endif
978 ret = com::sun::star::uno::makeAny( e );
980 return ret;
984 PyThreadAttach::PyThreadAttach( PyInterpreterState *interp)
985 throw ( com::sun::star::uno::RuntimeException )
987 tstate = PyThreadState_New( interp );
988 if( !tstate )
989 throw RuntimeException( "Couldn't create a pythreadstate" );
990 PyEval_AcquireThread( tstate);
993 PyThreadAttach::~PyThreadAttach()
995 PyThreadState_Clear( tstate );
996 PyEval_ReleaseThread( tstate );
997 PyThreadState_Delete( tstate );
1000 PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException )
1002 tstate = PyThreadState_Get();
1003 PyEval_ReleaseThread( tstate );
1006 /** Acquires the global interpreter lock again
1009 PyThreadDetach::~PyThreadDetach()
1011 PyEval_AcquireThread( tstate );
1015 PyRef RuntimeCargo::getUnoModule()
1017 if( ! dictUnoModule.is() )
1019 dictUnoModule = importUnoModule();
1021 return dictUnoModule;
1025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */