Update ooo320-m1
[ooovba.git] / pyuno / source / module / pyuno_runtime.cxx
blob388cb040d82d5b0bb60375c2ce3003e749aaee78
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pyuno_runtime.cxx,v $
10 * $Revision: 1.18 $
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>
39 #include <locale.h>
41 #include <typelib/typedescription.hxx>
43 #include <com/sun/star/beans/XMaterialHolder.hpp>
45 using rtl::OUString;
46 using rtl::OUStringToOString;
47 using rtl::OUStringBuffer;
48 using rtl::OStringBuffer;
49 using rtl::OString;
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;
69 namespace pyuno
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"),
78 sizeof (RuntimeImpl),
80 (destructor) RuntimeImpl::del,
81 (printfunc) 0,
82 (getattrfunc) 0,
83 (setattrfunc) 0,
84 (cmpfunc) 0,
85 (reprfunc) 0,
89 (hashfunc) 0,
90 (ternaryfunc) 0,
91 (reprfunc) 0,
92 (getattrofunc)0,
93 (setattrofunc)0,
94 NULL,
96 NULL,
97 (traverseproc)0,
98 (inquiry)0,
99 (richcmpfunc)0,
101 (getiterfunc)0,
102 (iternextfunc)0,
103 NULL,
104 NULL,
105 NULL,
106 NULL,
107 NULL,
108 (descrgetfunc)0,
109 (descrsetfunc)0,
111 (initproc)0,
112 (allocfunc)0,
113 (newfunc)0,
114 (freefunc)0,
115 (inquiry)0,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL,
121 (destructor)0
122 #if PY_VERSION_HEX >= 0x02060000
124 #endif
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();
134 if( ! state )
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 );
162 OUStringBuffer buf;
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() ) );
170 return dict;
173 static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
175 *pLevel = LogLevel::NONE;
176 *ppFile = 0;
177 OUString fileName;
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 );
185 OUString str;
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;
194 else
196 fprintf( stderr, "unknown loglevel %s\n",
197 OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
200 if( *pLevel > LogLevel::NONE )
202 *ppFile = stdout;
203 if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str ) )
205 if( str.equalsAscii( "stdout" ) )
206 *ppFile = stdout;
207 else if( str.equalsAscii( "stderr" ) )
208 *ppFile = stderr;
209 else
211 oslProcessInfo data;
212 data.Size = sizeof( data );
213 osl_getProcessInfo(
214 0 , osl_Process_IDENTIFIER , &data );
215 osl_getSystemPathFromFileURL( str.pData, &str.pData);
216 OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
217 o += ".";
218 o += OString::valueOf( (sal_Int32)data.Ident );
220 *ppFile = fopen( o.getStr() , "w" );
221 if ( *ppFile )
223 // do not buffer (useful if e.g. analyzing a crash)
224 setvbuf( *ppFile, 0, _IONBF, 0 );
226 else
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);
244 if( ! me )
245 throw RuntimeException(
246 OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ),
247 Reference< XInterface > () );
248 me->cargo = 0;
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" );
255 c->valid = 1;
256 c->xContext = ctx;
257 c->xInvocation = Reference< XSingleServiceFactory > (
258 ctx->getServiceManager()->createInstanceWithContext(
259 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ),
260 ctx ),
261 UNO_QUERY );
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" ) ),
270 ctx ),
271 UNO_QUERY );
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" ) ),
280 ctx ),
281 UNO_QUERY );
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" ) ),
290 ctx ),
291 UNO_QUERY );
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" ) ),
300 ctx ),
301 UNO_QUERY );
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" )) );
309 a >>= c->xTdMgr;
310 if( ! c->xTdMgr.is() )
311 throw RuntimeException(
312 OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )),
313 Reference< XInterface > () );
315 me->cargo =c;
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 );
324 delete me->cargo;
325 PyObject_Del (self);
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 )
374 : impl( 0 )
376 PyRef globalDict, runtime;
377 getRuntimeImpl( globalDict , runtime );
378 if( ! runtime.is() )
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 )
391 impl = r.impl;
392 Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
395 Runtime::~Runtime()
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) );
405 impl = r.impl;
406 return *this;
409 PyRef Runtime::any2PyObject (const Any &a ) const
410 throw ( com::sun::star::script::CannotConvertException,
411 com::sun::star::lang::IllegalArgumentException,
412 RuntimeException)
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:
425 Py_INCREF (Py_None);
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();
436 if ((a >>= b) && b)
437 return Py_True;
438 else
439 return Py_False;
441 case typelib_TypeClass_BYTE:
442 case typelib_TypeClass_SHORT:
443 case typelib_TypeClass_UNSIGNED_SHORT:
444 case typelib_TypeClass_LONG:
446 sal_Int32 l = 0;
447 a >>= l;
448 return PyRef( PyInt_FromLong (l), SAL_NO_ACQUIRE );
450 case typelib_TypeClass_UNSIGNED_LONG:
452 sal_uInt32 l;
453 a >>= l;
454 return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
456 case typelib_TypeClass_HYPER:
458 sal_Int64 l;
459 a >>= l;
460 return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
462 case typelib_TypeClass_UNSIGNED_HYPER:
464 sal_uInt64 l;
465 a >>= l;
466 return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
468 case typelib_TypeClass_FLOAT:
470 float f;
471 a >>= f;
472 return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
474 case typelib_TypeClass_DOUBLE:
476 double d;
477 a >>= d;
478 return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
480 case typelib_TypeClass_STRING:
482 OUString tmp_ostr;
483 a >>= tmp_ostr;
484 return ustring2PyUnicode( tmp_ostr );
486 case typelib_TypeClass_TYPE:
488 Type t;
489 a >>= t;
490 OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
491 return PyRef(
492 PyUNO_Type_new (
493 o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
494 SAL_NO_ACQUIRE);
496 case typelib_TypeClass_ANY:
498 //I don't think this can happen.
499 Py_INCREF (Py_None);
500 return Py_None;
502 case typelib_TypeClass_ENUM:
504 sal_Int32 l = *(sal_Int32 *) a.getValue();
505 TypeDescription desc( a.getValueType() );
506 if( desc.is() )
508 desc.makeComplete();
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 );
521 OUStringBuffer buf;
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 );
535 if( ! ret.is() )
537 OUStringBuffer buf;
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() );
557 return ret;
559 case typelib_TypeClass_SEQUENCE:
561 Sequence<Any> s;
563 Sequence< sal_Int8 > byteSequence;
564 if( a >>= byteSequence )
566 // byte sequence is treated in a special way because of peformance reasons
567 // @since 0.9.2
568 return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
570 else
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);
576 int i=0;
577 OUString errMsg;
580 for ( i = 0; i < s.getLength (); i++)
582 PyRef element;
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 );
595 throw;
597 return tuple;
600 case typelib_TypeClass_INTERFACE:
602 Reference< XUnoTunnel > tunnel;
603 a >>= tunnel;
604 if( tunnel.is() )
606 sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
607 if( that )
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 );
613 default:
615 OUStringBuffer buf;
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 );
623 return 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));
645 a >>= ret[i];
647 ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
650 return ret;
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 > () );
663 Any a;
664 PyObject *o = source.get();
665 if( Py_None == o )
669 else if (PyInt_Check (o))
671 if( o == Py_True )
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() );
681 else
683 sal_Int32 l = (sal_Int32) PyInt_AsLong( o );
684 if( l < 128 && l >= -128 )
686 sal_Int8 b = (sal_Int8 ) l;
687 a <<= b;
689 else if( l <= 0x7fff && l >= -0x8000 )
691 sal_Int16 s = (sal_Int16) l;
692 a <<= s;
694 else
696 a <<= 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;
706 a <<= b;
708 else if( l <= 0x7fff && l >= -0x8000 )
710 sal_Int16 s = (sal_Int16) l;
711 a <<= s;
713 else if( l <= SAL_CONST_INT64(0x7fffffff) &&
714 l >= -SAL_CONST_INT64(0x80000000) )
716 sal_Int32 l32 = (sal_Int32) l;
717 a <<= l32;
719 else
721 a <<= l;
724 else if (PyFloat_Check (o))
726 double d = PyFloat_AsDouble (o);
727 a <<= d;
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 );
740 a <<= s;
742 else
744 Runtime runtime;
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()));
755 a <<= seq;
757 else
758 if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
760 Type t = PyType2Type( o );
761 a <<= t;
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 );
772 if( holder.is( ) )
773 a = holder->getMaterial();
774 else
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() ) )
783 PyUNO* o_pi;
784 o_pi = (PyUNO*) o;
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);
792 if (!my_mh.is ())
794 throw RuntimeException(
795 USTR_ASCII( "struct wrapper does not support XMaterialHolder" ),
796 Reference< XInterface > () );
798 else
799 a = my_mh->getMaterial ();
801 else
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) );
816 Type t;
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 );
828 else
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 > () );
837 else
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() );
862 else
864 Sequence< Type > interfaces = invokeGetTypes( *this, o );
865 if( interfaces.getLength() )
867 Adapter *pAdapter = new Adapter( o, interfaces );
868 mappedObject =
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 );
881 else
883 OUStringBuffer buf;
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 > () );
892 return a;
895 Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
897 PyRef str;
898 Any ret;
899 if( excTraceback.is() )
901 PyRef unoModule( impl ? impl->cargo->getUnoModule() : 0 );
902 if( unoModule.is() )
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);
913 else
915 str = PyRef(
916 PyString_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ),
917 SAL_NO_ACQUIRE );
920 else
922 str = PyRef(
923 PyString_FromString( "Couldn't find uno.py, no stacktrace available" ),
924 SAL_NO_ACQUIRE );
928 else
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 );
938 else
940 OUStringBuffer buf;
941 PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
942 if( typeName.is() )
944 buf.appendAscii( PyString_AsString( typeName.get() ) );
946 else
948 buf.appendAscii( "no typename available" );
950 buf.appendAscii( ": " );
951 PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
952 if( valueRep.is() )
954 buf.appendAscii( PyString_AsString( valueRep.get()));
956 else
958 buf.appendAscii( "Couldn't convert exception value to a string" );
960 buf.appendAscii( ", traceback follows\n" );
961 if( str.is() )
963 buf.appendAscii( PyString_AsString( str.get() ) );
965 else
967 buf.appendAscii( ", no traceback available\n" );
969 RuntimeException e;
970 e.Message = buf.makeStringAndClear();
971 ret = com::sun::star::uno::makeAny( e );
973 return ret;
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();
983 int i;
984 for( i = 0 ; i < size ; i ++ )
986 if( 0 == strcmp( g_localeList[i].getStr(), str ) )
987 break;
989 if( i == size )
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 );
1001 if( !tstate )
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()
1018 PyObject *value =
1019 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1020 if( value )
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();
1031 PyObject *value =
1032 PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1033 if( value )
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;