167c7d1c1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
367c7d1c1SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
467c7d1c1SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
567c7d1c1SAndrew Rist  * distributed with this work for additional information
667c7d1c1SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
767c7d1c1SAndrew Rist  * to you under the Apache License, Version 2.0 (the
867c7d1c1SAndrew Rist  * "License"); you may not use this file except in compliance
967c7d1c1SAndrew Rist  * with the License.  You may obtain a copy of the License at
1067c7d1c1SAndrew Rist  *
1167c7d1c1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1267c7d1c1SAndrew Rist  *
1367c7d1c1SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1467c7d1c1SAndrew Rist  * software distributed under the License is distributed on an
1567c7d1c1SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1667c7d1c1SAndrew Rist  * KIND, either express or implied.  See the License for the
1767c7d1c1SAndrew Rist  * specific language governing permissions and limitations
1867c7d1c1SAndrew Rist  * under the License.
1967c7d1c1SAndrew Rist  *
2067c7d1c1SAndrew Rist  *************************************************************/
2167c7d1c1SAndrew Rist 
2267c7d1c1SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "pyuno_impl.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <osl/thread.h>
27cdf0e10cSrcweir #include <osl/module.h>
28cdf0e10cSrcweir #include <osl/process.h>
29cdf0e10cSrcweir #include <rtl/strbuf.hxx>
30cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
31cdf0e10cSrcweir #include <rtl/bootstrap.hxx>
32cdf0e10cSrcweir #include <locale.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <typelib/typedescription.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <com/sun/star/beans/XMaterialHolder.hpp>
37cdf0e10cSrcweir 
38*fd44edf3SHerbert Dürr #include <vector>
39*fd44edf3SHerbert Dürr 
40cdf0e10cSrcweir using rtl::OUString;
41cdf0e10cSrcweir using rtl::OUStringToOString;
42cdf0e10cSrcweir using rtl::OUStringBuffer;
43cdf0e10cSrcweir using rtl::OStringBuffer;
44cdf0e10cSrcweir using rtl::OString;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using com::sun::star::uno::Reference;
47cdf0e10cSrcweir using com::sun::star::uno::XInterface;
48cdf0e10cSrcweir using com::sun::star::uno::Any;
49cdf0e10cSrcweir using com::sun::star::uno::TypeDescription;
50cdf0e10cSrcweir using com::sun::star::uno::Sequence;
51cdf0e10cSrcweir using com::sun::star::uno::Type;
52cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY;
53cdf0e10cSrcweir using com::sun::star::uno::RuntimeException;
54cdf0e10cSrcweir using com::sun::star::uno::XComponentContext;
55cdf0e10cSrcweir using com::sun::star::lang::XSingleServiceFactory;
56cdf0e10cSrcweir using com::sun::star::lang::XUnoTunnel;
57cdf0e10cSrcweir using com::sun::star::reflection::XIdlReflection;
58cdf0e10cSrcweir using com::sun::star::script::XTypeConverter;
59cdf0e10cSrcweir using com::sun::star::script::XInvocationAdapterFactory2;
60cdf0e10cSrcweir using com::sun::star::script::XInvocation;
61cdf0e10cSrcweir using com::sun::star::beans::XMaterialHolder;
62cdf0e10cSrcweir using com::sun::star::beans::XIntrospection;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir namespace pyuno
65cdf0e10cSrcweir {
66cdf0e10cSrcweir #define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
67cdf0e10cSrcweir 
68cdf0e10cSrcweir static PyTypeObject RuntimeImpl_Type =
69cdf0e10cSrcweir {
705c3821d8SPedro Giffuni     PyVarObject_HEAD_INIT(&PyType_Type, 0)
71cdf0e10cSrcweir     const_cast< char * >("pyuno_runtime"),
72cdf0e10cSrcweir     sizeof (RuntimeImpl),
73cdf0e10cSrcweir     0,
74cdf0e10cSrcweir     (destructor) RuntimeImpl::del,
75cdf0e10cSrcweir     (printfunc) 0,
76cdf0e10cSrcweir     (getattrfunc) 0,
77cdf0e10cSrcweir     (setattrfunc) 0,
7877dc4149SPedro Giffuni #if PY_MAJOR_VERSION >= 3
7977dc4149SPedro Giffuni     0,
8077dc4149SPedro Giffuni #else
81cdf0e10cSrcweir     (cmpfunc) 0,
8277dc4149SPedro Giffuni #endif
83cdf0e10cSrcweir     (reprfunc) 0,
84cdf0e10cSrcweir     0,
85cdf0e10cSrcweir     0,
86cdf0e10cSrcweir     0,
87cdf0e10cSrcweir     (hashfunc) 0,
88cdf0e10cSrcweir     (ternaryfunc) 0,
89cdf0e10cSrcweir     (reprfunc) 0,
90cdf0e10cSrcweir     (getattrofunc)0,
91cdf0e10cSrcweir     (setattrofunc)0,
92cdf0e10cSrcweir     NULL,
93cdf0e10cSrcweir     0,
94cdf0e10cSrcweir     NULL,
95cdf0e10cSrcweir     (traverseproc)0,
96cdf0e10cSrcweir     (inquiry)0,
97cdf0e10cSrcweir     (richcmpfunc)0,
98cdf0e10cSrcweir     0,
99cdf0e10cSrcweir     (getiterfunc)0,
100cdf0e10cSrcweir     (iternextfunc)0,
101cdf0e10cSrcweir     NULL,
102cdf0e10cSrcweir     NULL,
103cdf0e10cSrcweir     NULL,
104cdf0e10cSrcweir     NULL,
105cdf0e10cSrcweir     NULL,
106cdf0e10cSrcweir     (descrgetfunc)0,
107cdf0e10cSrcweir     (descrsetfunc)0,
108cdf0e10cSrcweir     0,
109cdf0e10cSrcweir     (initproc)0,
110cdf0e10cSrcweir     (allocfunc)0,
111cdf0e10cSrcweir     (newfunc)0,
112cdf0e10cSrcweir     (freefunc)0,
113cdf0e10cSrcweir     (inquiry)0,
114cdf0e10cSrcweir     NULL,
115cdf0e10cSrcweir     NULL,
116cdf0e10cSrcweir     NULL,
117cdf0e10cSrcweir     NULL,
118cdf0e10cSrcweir     NULL,
119cdf0e10cSrcweir     (destructor)0
120cdf0e10cSrcweir #if PY_VERSION_HEX >= 0x02060000
121cdf0e10cSrcweir     , 0
122cdf0e10cSrcweir #endif
123cdf0e10cSrcweir };
124cdf0e10cSrcweir 
125cdf0e10cSrcweir /*----------------------------------------------------------------------
126cdf0e10cSrcweir   Runtime implementation
127cdf0e10cSrcweir  -----------------------------------------------------------------------*/
getRuntimeImpl(PyRef & globalDict,PyRef & runtimeImpl)128cdf0e10cSrcweir static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl )
129cdf0e10cSrcweir     throw ( com::sun::star::uno::RuntimeException )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir     PyThreadState * state = PyThreadState_Get();
132cdf0e10cSrcweir     if( ! state )
133cdf0e10cSrcweir     {
134cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
135cdf0e10cSrcweir             "python global interpreter must be held (thread must be attached)" )),
136cdf0e10cSrcweir                                 Reference< XInterface > () );
137cdf0e10cSrcweir     }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     if( ! globalDict.is() ) // FATAL !
142cdf0e10cSrcweir     {
143cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
144cdf0e10cSrcweir             "can't find __main__ module" )), Reference< XInterface > ());
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir     runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" );
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
importUnoModule()149cdf0e10cSrcweir static PyRef importUnoModule( ) throw ( RuntimeException )
150cdf0e10cSrcweir {
151cdf0e10cSrcweir     PyRef globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
152cdf0e10cSrcweir     // import the uno module
153cdf0e10cSrcweir     PyRef module( PyImport_ImportModule( const_cast< char * >("uno") ), SAL_NO_ACQUIRE );
154cdf0e10cSrcweir     if( PyErr_Occurred() )
155cdf0e10cSrcweir     {
156cdf0e10cSrcweir         PyRef excType, excValue, excTraceback;
157cdf0e10cSrcweir         PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
158cdf0e10cSrcweir         PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir         OUStringBuffer buf;
161cdf0e10cSrcweir         buf.appendAscii( "python object raised an unknown exception (" );
162cdf0e10cSrcweir         PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
16377dc4149SPedro Giffuni 
16477dc4149SPedro Giffuni         buf.append( pyString2ustring( valueRep.get() ) ).appendAscii( ", traceback follows\n" );
16577dc4149SPedro Giffuni         buf.append( pyString2ustring( str.get() ) );
166cdf0e10cSrcweir         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
167cdf0e10cSrcweir     }
168cdf0e10cSrcweir     PyRef dict( PyModule_GetDict( module.get() ) );
169cdf0e10cSrcweir     return dict;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
readLoggingConfig(sal_Int32 * pLevel,FILE ** ppFile)172cdf0e10cSrcweir static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
173cdf0e10cSrcweir {
174cdf0e10cSrcweir     *pLevel = LogLevel::NONE;
175cdf0e10cSrcweir     *ppFile = 0;
176cdf0e10cSrcweir     OUString fileName;
177cdf0e10cSrcweir     osl_getModuleURLFromFunctionAddress(
178cdf0e10cSrcweir         reinterpret_cast< oslGenericFunction >(readLoggingConfig),
179cdf0e10cSrcweir         (rtl_uString **) &fileName );
180cdf0e10cSrcweir     fileName = OUString( fileName.getStr(), fileName.lastIndexOf( '/' )+1 );
181cdf0e10cSrcweir     fileName += OUString::createFromAscii(  SAL_CONFIGFILE("pyuno") );
182cdf0e10cSrcweir     rtl::Bootstrap bootstrapHandle( fileName );
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     OUString str;
185cdf0e10cSrcweir     if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGLEVEL" ), str ) )
186cdf0e10cSrcweir     {
187cdf0e10cSrcweir         if( str.equalsAscii( "NONE" ) )
188cdf0e10cSrcweir             *pLevel = LogLevel::NONE;
189cdf0e10cSrcweir         else if( str.equalsAscii( "CALL" ) )
190cdf0e10cSrcweir             *pLevel = LogLevel::CALL;
191cdf0e10cSrcweir         else if( str.equalsAscii( "ARGS" ) )
192cdf0e10cSrcweir             *pLevel = LogLevel::ARGS;
193cdf0e10cSrcweir         else
194cdf0e10cSrcweir         {
195cdf0e10cSrcweir             fprintf( stderr, "unknown loglevel %s\n",
196cdf0e10cSrcweir                      OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
197cdf0e10cSrcweir         }
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir     if( *pLevel > LogLevel::NONE )
200cdf0e10cSrcweir     {
201cdf0e10cSrcweir         *ppFile = stdout;
202cdf0e10cSrcweir         if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str ) )
203cdf0e10cSrcweir         {
204cdf0e10cSrcweir             if( str.equalsAscii( "stdout" ) )
205cdf0e10cSrcweir                 *ppFile = stdout;
206cdf0e10cSrcweir             else if( str.equalsAscii( "stderr" ) )
207cdf0e10cSrcweir                 *ppFile = stderr;
208cdf0e10cSrcweir             else
209cdf0e10cSrcweir             {
210cdf0e10cSrcweir                 oslProcessInfo data;
211cdf0e10cSrcweir                 data.Size = sizeof( data );
212cdf0e10cSrcweir                 osl_getProcessInfo(
213cdf0e10cSrcweir                     0 , osl_Process_IDENTIFIER , &data );
214cdf0e10cSrcweir                 osl_getSystemPathFromFileURL( str.pData, &str.pData);
215cdf0e10cSrcweir                 OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
216cdf0e10cSrcweir                 o += ".";
217cdf0e10cSrcweir                 o += OString::valueOf( (sal_Int32)data.Ident );
218cdf0e10cSrcweir 
219cdf0e10cSrcweir                 *ppFile = fopen( o.getStr() , "w" );
220cdf0e10cSrcweir                 if ( *ppFile )
221cdf0e10cSrcweir                 {
222cdf0e10cSrcweir                     // do not buffer (useful if e.g. analyzing a crash)
223cdf0e10cSrcweir                     setvbuf( *ppFile, 0, _IONBF, 0 );
224cdf0e10cSrcweir                 }
225cdf0e10cSrcweir                 else
226cdf0e10cSrcweir                 {
227cdf0e10cSrcweir                     fprintf( stderr, "couldn't create file %s\n",
228cdf0e10cSrcweir                              OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
229cdf0e10cSrcweir 
230cdf0e10cSrcweir                 }
231cdf0e10cSrcweir             }
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir     }
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir /*-------------------------------------------------------------------
237cdf0e10cSrcweir  RuntimeImpl implementations
238cdf0e10cSrcweir  *-------------------------------------------------------------------*/
create(const Reference<XComponentContext> & ctx)239cdf0e10cSrcweir PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx )
240cdf0e10cSrcweir     throw( com::sun::star::uno::RuntimeException )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type);
243cdf0e10cSrcweir     if( ! me )
244cdf0e10cSrcweir         throw RuntimeException(
245cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ),
246cdf0e10cSrcweir             Reference< XInterface > () );
247cdf0e10cSrcweir     me->cargo = 0;
248cdf0e10cSrcweir     // must use a different struct here, as the PyObject_New
249cdf0e10cSrcweir     // makes C++ unusable
250cdf0e10cSrcweir     RuntimeCargo *c = new RuntimeCargo();
251cdf0e10cSrcweir     readLoggingConfig( &(c->logLevel) , &(c->logFile) );
252cdf0e10cSrcweir     log( c, LogLevel::CALL, "Instantiating pyuno bridge" );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     c->valid = 1;
255cdf0e10cSrcweir     c->xContext = ctx;
256cdf0e10cSrcweir     c->xInvocation = Reference< XSingleServiceFactory > (
257cdf0e10cSrcweir         ctx->getServiceManager()->createInstanceWithContext(
258cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ),
259cdf0e10cSrcweir             ctx ),
260cdf0e10cSrcweir         UNO_QUERY );
261cdf0e10cSrcweir     if( ! c->xInvocation.is() )
262cdf0e10cSrcweir         throw RuntimeException(
263cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ),
264cdf0e10cSrcweir             Reference< XInterface > () );
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     c->xTypeConverter = Reference< XTypeConverter > (
267cdf0e10cSrcweir         ctx->getServiceManager()->createInstanceWithContext(
268cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ),
269cdf0e10cSrcweir             ctx ),
270cdf0e10cSrcweir         UNO_QUERY );
271cdf0e10cSrcweir     if( ! c->xTypeConverter.is() )
272cdf0e10cSrcweir         throw RuntimeException(
273cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )),
274cdf0e10cSrcweir             Reference< XInterface > () );
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     c->xCoreReflection = Reference< XIdlReflection > (
277cdf0e10cSrcweir         ctx->getServiceManager()->createInstanceWithContext(
278cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ),
279cdf0e10cSrcweir             ctx ),
280cdf0e10cSrcweir         UNO_QUERY );
281cdf0e10cSrcweir     if( ! c->xCoreReflection.is() )
282cdf0e10cSrcweir         throw RuntimeException(
283cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )),
284cdf0e10cSrcweir             Reference< XInterface > () );
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     c->xAdapterFactory = Reference< XInvocationAdapterFactory2 > (
287cdf0e10cSrcweir         ctx->getServiceManager()->createInstanceWithContext(
288cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ),
289cdf0e10cSrcweir             ctx ),
290cdf0e10cSrcweir         UNO_QUERY );
291cdf0e10cSrcweir     if( ! c->xAdapterFactory.is() )
292cdf0e10cSrcweir         throw RuntimeException(
293cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )),
294cdf0e10cSrcweir             Reference< XInterface > () );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     c->xIntrospection = Reference< XIntrospection > (
297cdf0e10cSrcweir         ctx->getServiceManager()->createInstanceWithContext(
298cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ),
299cdf0e10cSrcweir             ctx ),
300cdf0e10cSrcweir         UNO_QUERY );
301cdf0e10cSrcweir     if( ! c->xIntrospection.is() )
302cdf0e10cSrcweir         throw RuntimeException(
303cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )),
304cdf0e10cSrcweir             Reference< XInterface > () );
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     Any a = ctx->getValueByName(OUString(
307cdf0e10cSrcweir         RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) );
308cdf0e10cSrcweir     a >>= c->xTdMgr;
309cdf0e10cSrcweir     if( ! c->xTdMgr.is() )
310cdf0e10cSrcweir         throw RuntimeException(
311cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )),
312cdf0e10cSrcweir             Reference< XInterface > () );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     me->cargo =c;
315cdf0e10cSrcweir     return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE );
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
del(PyObject * self)318cdf0e10cSrcweir void  stRuntimeImpl::del(PyObject* self)
319cdf0e10cSrcweir {
320cdf0e10cSrcweir     RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self );
321cdf0e10cSrcweir     if( me->cargo->logFile )
322cdf0e10cSrcweir         fclose( me->cargo->logFile );
323cdf0e10cSrcweir     delete me->cargo;
324cdf0e10cSrcweir     PyObject_Del (self);
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
initialize(const Reference<XComponentContext> & ctx)328cdf0e10cSrcweir void Runtime::initialize( const Reference< XComponentContext > & ctx )
329cdf0e10cSrcweir     throw ( RuntimeException )
330cdf0e10cSrcweir {
331cdf0e10cSrcweir     PyRef globalDict, runtime;
332cdf0e10cSrcweir     getRuntimeImpl( globalDict , runtime );
333cdf0e10cSrcweir     RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     if( runtime.is() && impl->cargo->valid )
336cdf0e10cSrcweir     {
337cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
338cdf0e10cSrcweir             "pyuno runtime has already been initialized before" ) ),
339cdf0e10cSrcweir                                 Reference< XInterface > () );
340cdf0e10cSrcweir     }
341cdf0e10cSrcweir     PyRef keep( RuntimeImpl::create( ctx ) );
342cdf0e10cSrcweir     PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() );
343cdf0e10cSrcweir     Py_XINCREF( keep.get() );
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 
isInitialized()347cdf0e10cSrcweir bool Runtime::isInitialized() throw ( RuntimeException )
348cdf0e10cSrcweir {
349cdf0e10cSrcweir     PyRef globalDict, runtime;
350cdf0e10cSrcweir     getRuntimeImpl( globalDict , runtime );
351cdf0e10cSrcweir     RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
352cdf0e10cSrcweir     return runtime.is() && impl->cargo->valid;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir 
finalize()355cdf0e10cSrcweir void Runtime::finalize() throw (RuntimeException)
356cdf0e10cSrcweir {
357cdf0e10cSrcweir     PyRef globalDict, runtime;
358cdf0e10cSrcweir     getRuntimeImpl( globalDict , runtime );
359cdf0e10cSrcweir     RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
360cdf0e10cSrcweir     if( !runtime.is() || ! impl->cargo->valid )
361cdf0e10cSrcweir     {
362cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
363cdf0e10cSrcweir             "pyuno bridge must have been initialized before finalizing" )),
364cdf0e10cSrcweir                                 Reference< XInterface > () );
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir     impl->cargo->valid = false;
367cdf0e10cSrcweir     impl->cargo->xInvocation.clear();
368cdf0e10cSrcweir     impl->cargo->xContext.clear();
369cdf0e10cSrcweir     impl->cargo->xTypeConverter.clear();
370cdf0e10cSrcweir }
371cdf0e10cSrcweir 
Runtime()372cdf0e10cSrcweir Runtime::Runtime() throw(  RuntimeException )
373cdf0e10cSrcweir     : impl( 0 )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir     PyRef globalDict, runtime;
376cdf0e10cSrcweir     getRuntimeImpl( globalDict , runtime );
377cdf0e10cSrcweir     if( ! runtime.is() )
378cdf0e10cSrcweir     {
379cdf0e10cSrcweir         throw RuntimeException(
380cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, "
381cdf0e10cSrcweir                                                   "(the pyuno.bootstrap needs to be called before using any uno classes)")),
382cdf0e10cSrcweir             Reference< XInterface > () );
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir     impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
385cdf0e10cSrcweir     Py_XINCREF( runtime.get() );
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
Runtime(const Runtime & r)388cdf0e10cSrcweir Runtime::Runtime( const Runtime & r )
389cdf0e10cSrcweir {
390cdf0e10cSrcweir     impl = r.impl;
391cdf0e10cSrcweir     Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
392cdf0e10cSrcweir }
393cdf0e10cSrcweir 
~Runtime()394cdf0e10cSrcweir Runtime::~Runtime()
395cdf0e10cSrcweir {
396cdf0e10cSrcweir     Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
operator =(const Runtime & r)399cdf0e10cSrcweir Runtime & Runtime::operator = ( const Runtime & r )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir     PyRef temp( reinterpret_cast< PyObject * >(r.impl) );
402cdf0e10cSrcweir     Py_XINCREF( temp.get() );
403cdf0e10cSrcweir     Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
404cdf0e10cSrcweir     impl = r.impl;
405cdf0e10cSrcweir     return *this;
406cdf0e10cSrcweir }
407cdf0e10cSrcweir 
any2PyObject(const Any & a) const408cdf0e10cSrcweir PyRef Runtime::any2PyObject (const Any &a ) const
409cdf0e10cSrcweir     throw ( com::sun::star::script::CannotConvertException,
410cdf0e10cSrcweir             com::sun::star::lang::IllegalArgumentException,
411cdf0e10cSrcweir             RuntimeException)
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     if( ! impl->cargo->valid )
414cdf0e10cSrcweir     {
415cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
416cdf0e10cSrcweir             "pyuno runtime must be initialized before calling any2PyObject" )),
417cdf0e10cSrcweir                                 Reference< XInterface > () );
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     switch (a.getValueTypeClass ())
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir     case typelib_TypeClass_VOID:
423cdf0e10cSrcweir 	{
424cdf0e10cSrcweir         Py_INCREF (Py_None);
425cdf0e10cSrcweir         return PyRef(Py_None);
426cdf0e10cSrcweir 	}
427cdf0e10cSrcweir     case typelib_TypeClass_CHAR:
428cdf0e10cSrcweir 	{
429cdf0e10cSrcweir         sal_Unicode c = *(sal_Unicode*)a.getValue();
430cdf0e10cSrcweir         return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE );
431cdf0e10cSrcweir 	}
432cdf0e10cSrcweir     case typelib_TypeClass_BOOLEAN:
433cdf0e10cSrcweir 	{
434cdf0e10cSrcweir         sal_Bool b = sal_Bool();
435cdf0e10cSrcweir         if ((a >>= b) && b)
436cdf0e10cSrcweir             return Py_True;
437cdf0e10cSrcweir         else
438cdf0e10cSrcweir             return Py_False;
439cdf0e10cSrcweir 	}
440cdf0e10cSrcweir     case typelib_TypeClass_BYTE:
441cdf0e10cSrcweir     case typelib_TypeClass_SHORT:
442cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_SHORT:
443cdf0e10cSrcweir     case typelib_TypeClass_LONG:
444cdf0e10cSrcweir 	{
445cdf0e10cSrcweir         sal_Int32 l = 0;
446cdf0e10cSrcweir         a >>= l;
4475c3821d8SPedro Giffuni #if PY_MAJOR_VERSION >= 3
4485c3821d8SPedro Giffuni         return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
4495c3821d8SPedro Giffuni #else
450cdf0e10cSrcweir         return PyRef( PyInt_FromLong (l), SAL_NO_ACQUIRE );
4515c3821d8SPedro Giffuni #endif
452cdf0e10cSrcweir 	}
453cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_LONG:
454cdf0e10cSrcweir 	{
455cdf0e10cSrcweir         sal_uInt32 l = 0;
456cdf0e10cSrcweir         a >>= l;
457cdf0e10cSrcweir         return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
458cdf0e10cSrcweir 	}
459cdf0e10cSrcweir     case typelib_TypeClass_HYPER:
460cdf0e10cSrcweir 	{
461cdf0e10cSrcweir         sal_Int64 l = 0;
462cdf0e10cSrcweir         a >>= l;
463cdf0e10cSrcweir         return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
464cdf0e10cSrcweir 	}
465cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_HYPER:
466cdf0e10cSrcweir 	{
467cdf0e10cSrcweir         sal_uInt64 l = 0;
468cdf0e10cSrcweir         a >>= l;
469cdf0e10cSrcweir         return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
470cdf0e10cSrcweir 	}
471cdf0e10cSrcweir     case typelib_TypeClass_FLOAT:
472cdf0e10cSrcweir 	{
473cdf0e10cSrcweir         float f = 0.0;
474cdf0e10cSrcweir         a >>= f;
475cdf0e10cSrcweir         return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
476cdf0e10cSrcweir 	}
477cdf0e10cSrcweir     case typelib_TypeClass_DOUBLE:
478cdf0e10cSrcweir 	{
479cdf0e10cSrcweir         double d = 0.0;
480cdf0e10cSrcweir         a >>= d;
481cdf0e10cSrcweir         return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
482cdf0e10cSrcweir 	}
483cdf0e10cSrcweir     case typelib_TypeClass_STRING:
484cdf0e10cSrcweir 	{
485cdf0e10cSrcweir         OUString tmp_ostr;
486cdf0e10cSrcweir         a >>= tmp_ostr;
487cdf0e10cSrcweir         return ustring2PyUnicode( tmp_ostr );
488cdf0e10cSrcweir 	}
489cdf0e10cSrcweir     case typelib_TypeClass_TYPE:
490cdf0e10cSrcweir 	{
491cdf0e10cSrcweir         Type t;
492cdf0e10cSrcweir         a >>= t;
493cdf0e10cSrcweir         OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
494cdf0e10cSrcweir         return PyRef(
495cdf0e10cSrcweir             PyUNO_Type_new (
496cdf0e10cSrcweir                 o.getStr(),  (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
497cdf0e10cSrcweir             SAL_NO_ACQUIRE);
498cdf0e10cSrcweir 	}
499cdf0e10cSrcweir     case typelib_TypeClass_ANY:
500cdf0e10cSrcweir 	{
501cdf0e10cSrcweir         //I don't think this can happen.
502cdf0e10cSrcweir         Py_INCREF (Py_None);
503cdf0e10cSrcweir         return Py_None;
504cdf0e10cSrcweir 	}
505cdf0e10cSrcweir     case typelib_TypeClass_ENUM:
506cdf0e10cSrcweir 	{
507cdf0e10cSrcweir         sal_Int32 l = *(sal_Int32 *) a.getValue();
508cdf0e10cSrcweir         TypeDescription desc( a.getValueType() );
509cdf0e10cSrcweir         if( desc.is() )
510cdf0e10cSrcweir         {
511cdf0e10cSrcweir             desc.makeComplete();
512cdf0e10cSrcweir             typelib_EnumTypeDescription *pEnumDesc =
513cdf0e10cSrcweir                 (typelib_EnumTypeDescription *) desc.get();
514cdf0e10cSrcweir             for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ )
515cdf0e10cSrcweir             {
516cdf0e10cSrcweir                 if( pEnumDesc->pEnumValues[i] == l )
517cdf0e10cSrcweir                 {
518cdf0e10cSrcweir                     OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US);
519cdf0e10cSrcweir                     OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US);
520cdf0e10cSrcweir                     return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE );
521cdf0e10cSrcweir                 }
522cdf0e10cSrcweir             }
523cdf0e10cSrcweir         }
524cdf0e10cSrcweir         OUStringBuffer buf;
525cdf0e10cSrcweir         buf.appendAscii( "Any carries enum " );
526cdf0e10cSrcweir         buf.append( a.getValueType().getTypeName());
527cdf0e10cSrcweir         buf.appendAscii( " with invalid value " ).append( l );
528cdf0e10cSrcweir         throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > ()  );
529cdf0e10cSrcweir 	}
530cdf0e10cSrcweir     case typelib_TypeClass_EXCEPTION:
531cdf0e10cSrcweir     case typelib_TypeClass_STRUCT:
532cdf0e10cSrcweir     {
533cdf0e10cSrcweir         PyRef excClass = getClass( a.getValueType().getTypeName(), *this );
534cdf0e10cSrcweir         PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE);
535cdf0e10cSrcweir         PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE );
536cdf0e10cSrcweir         PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() );
537cdf0e10cSrcweir         PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE );
538cdf0e10cSrcweir         if( ! ret.is() )
539cdf0e10cSrcweir         {
540cdf0e10cSrcweir             OUStringBuffer buf;
541cdf0e10cSrcweir             buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
542cdf0e10cSrcweir             buf.append( a.getValueType().getTypeName() );
543cdf0e10cSrcweir             throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
544cdf0e10cSrcweir         }
545cdf0e10cSrcweir 
546cdf0e10cSrcweir         if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() )
547cdf0e10cSrcweir         {
548cdf0e10cSrcweir             // add the message in a standard python way !
549cdf0e10cSrcweir             PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
550cdf0e10cSrcweir 
551cdf0e10cSrcweir             // assuming that the Message is always the first member, wuuuu
552cdf0e10cSrcweir             void *pData = (void*)a.getValue();
553cdf0e10cSrcweir             OUString message = *(OUString * )pData;
55477dc4149SPedro Giffuni             PyRef pymsg = USTR_TO_PYSTR( message );
555cdf0e10cSrcweir             PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() );
556cdf0e10cSrcweir             // the exception base functions want to have an "args" tuple,
557cdf0e10cSrcweir             // which contains the message
558cdf0e10cSrcweir             PyObject_SetAttrString( ret.get(), const_cast< char * >("args"), args.get() );
559cdf0e10cSrcweir         }
560cdf0e10cSrcweir         return ret;
561cdf0e10cSrcweir     }
562cdf0e10cSrcweir     case typelib_TypeClass_SEQUENCE:
563cdf0e10cSrcweir 	{
564cdf0e10cSrcweir         Sequence<Any> s;
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         Sequence< sal_Int8 > byteSequence;
567cdf0e10cSrcweir         if( a >>= byteSequence )
568cdf0e10cSrcweir         {
569cdf0e10cSrcweir             // byte sequence is treated in a special way because of peformance reasons
570cdf0e10cSrcweir             // @since 0.9.2
571cdf0e10cSrcweir             return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
572cdf0e10cSrcweir         }
573cdf0e10cSrcweir         else
574cdf0e10cSrcweir         {
575cdf0e10cSrcweir             Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter;
576cdf0e10cSrcweir             Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation;
577cdf0e10cSrcweir             tc->convertTo (a, ::getCppuType (&s)) >>= s;
578cdf0e10cSrcweir             PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE);
579cdf0e10cSrcweir             int i=0;
580cdf0e10cSrcweir             OUString errMsg;
581cdf0e10cSrcweir             try
582cdf0e10cSrcweir             {
583cdf0e10cSrcweir                 for ( i = 0; i < s.getLength (); i++)
584cdf0e10cSrcweir                 {
585cdf0e10cSrcweir                     PyRef element;
586cdf0e10cSrcweir                     element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() ));
587cdf0e10cSrcweir                     OSL_ASSERT( element.is() );
588cdf0e10cSrcweir                     PyTuple_SetItem( tuple.get(), i, element.getAcquired() );
589cdf0e10cSrcweir                 }
590cdf0e10cSrcweir             }
591cdf0e10cSrcweir             catch( com::sun::star::uno::Exception & )
592cdf0e10cSrcweir             {
593cdf0e10cSrcweir                 for( ; i < s.getLength() ; i ++ )
594cdf0e10cSrcweir                 {
595cdf0e10cSrcweir                     Py_INCREF( Py_None );
596cdf0e10cSrcweir                     PyTuple_SetItem( tuple.get(), i,  Py_None );
597cdf0e10cSrcweir                 }
598cdf0e10cSrcweir                 throw;
599cdf0e10cSrcweir             }
600cdf0e10cSrcweir             return tuple;
601cdf0e10cSrcweir 	    }
602cdf0e10cSrcweir 	}
603cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE:
604cdf0e10cSrcweir 	{
605cdf0e10cSrcweir         Reference< XUnoTunnel > tunnel;
606cdf0e10cSrcweir         a >>= tunnel;
607cdf0e10cSrcweir         if( tunnel.is() )
608cdf0e10cSrcweir         {
609cdf0e10cSrcweir             sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
610cdf0e10cSrcweir             if( that )
611cdf0e10cSrcweir                 return ((Adapter*)sal::static_int_cast< sal_IntPtr >(that))->getWrappedObject();
612cdf0e10cSrcweir         }
613cdf0e10cSrcweir         //This is just like the struct case:
614cdf0e10cSrcweir         return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE );
615cdf0e10cSrcweir 	}
616cdf0e10cSrcweir     default:
617cdf0e10cSrcweir 	{
618cdf0e10cSrcweir         OUStringBuffer buf;
619cdf0e10cSrcweir         buf.appendAscii( "Unknonwn UNO type class " );
620cdf0e10cSrcweir         buf.append( (sal_Int32 ) a.getValueTypeClass() );
621cdf0e10cSrcweir         throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () );
622cdf0e10cSrcweir 	}
623cdf0e10cSrcweir     }
624cdf0e10cSrcweir     //We shouldn't be here...
625cdf0e10cSrcweir     Py_INCREF( Py_None );
626cdf0e10cSrcweir     return Py_None;
627cdf0e10cSrcweir }
628cdf0e10cSrcweir 
invokeGetTypes(const Runtime & r,PyObject * o)629cdf0e10cSrcweir static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o )
630cdf0e10cSrcweir {
631cdf0e10cSrcweir     Sequence< Type > ret;
632cdf0e10cSrcweir 
633cdf0e10cSrcweir     PyRef method( PyObject_GetAttrString( o , const_cast< char * >("getTypes") ), SAL_NO_ACQUIRE );
634cdf0e10cSrcweir     raiseInvocationTargetExceptionWhenNeeded( r );
635cdf0e10cSrcweir     if( method.is() && PyCallable_Check( method.get() ) )
636cdf0e10cSrcweir     {
637cdf0e10cSrcweir         PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE );
638cdf0e10cSrcweir         raiseInvocationTargetExceptionWhenNeeded( r );
639cdf0e10cSrcweir         if( types.is() && PyTuple_Check( types.get() ) )
640cdf0e10cSrcweir         {
641cdf0e10cSrcweir             int size = PyTuple_Size( types.get() );
642cdf0e10cSrcweir 
643cdf0e10cSrcweir             // add the XUnoTunnel interface  for uno object identity concept (hack)
644cdf0e10cSrcweir             ret.realloc( size + 1 );
645cdf0e10cSrcweir             for( int i = 0 ; i < size ; i ++ )
646cdf0e10cSrcweir             {
647cdf0e10cSrcweir                 Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i));
648cdf0e10cSrcweir                 a >>= ret[i];
649cdf0e10cSrcweir             }
650cdf0e10cSrcweir             ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
651cdf0e10cSrcweir         }
652cdf0e10cSrcweir     }
653cdf0e10cSrcweir     return ret;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
pyObject2Any(const PyRef & source,enum ConversionMode mode) const656cdf0e10cSrcweir Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const
657cdf0e10cSrcweir     throw ( com::sun::star::uno::RuntimeException )
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     if( ! impl->cargo->valid )
660cdf0e10cSrcweir     {
661cdf0e10cSrcweir         throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
662cdf0e10cSrcweir             "pyuno runtime must be initialized before calling any2PyObject" )),
663cdf0e10cSrcweir                                 Reference< XInterface > () );
664cdf0e10cSrcweir     }
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     Any a;
667cdf0e10cSrcweir     PyObject *o = source.get();
668cdf0e10cSrcweir     if( Py_None == o )
669cdf0e10cSrcweir     {
670cdf0e10cSrcweir 
671cdf0e10cSrcweir     }
67277dc4149SPedro Giffuni #if PY_MAJOR_VERSION >= 3	// Python 3 has no PyInt
67377dc4149SPedro Giffuni     else if (PyBool_Check(o))
67477dc4149SPedro Giffuni     {
67577dc4149SPedro Giffuni         if( o == Py_True )
67677dc4149SPedro Giffuni         {
67777dc4149SPedro Giffuni             sal_Bool b = sal_True;
67877dc4149SPedro Giffuni             a = Any( &b, getBooleanCppuType() );
67977dc4149SPedro Giffuni         }
68077dc4149SPedro Giffuni         else
68177dc4149SPedro Giffuni         {
68277dc4149SPedro Giffuni             sal_Bool b = sal_False;
68377dc4149SPedro Giffuni             a = Any( &b, getBooleanCppuType() );
68477dc4149SPedro Giffuni         }
68577dc4149SPedro Giffuni     }
68677dc4149SPedro Giffuni #else
687cdf0e10cSrcweir     else if (PyInt_Check (o))
688cdf0e10cSrcweir     {
689cdf0e10cSrcweir         if( o == Py_True )
690cdf0e10cSrcweir         {
691cdf0e10cSrcweir             sal_Bool b = sal_True;
692cdf0e10cSrcweir             a = Any( &b, getBooleanCppuType() );
693cdf0e10cSrcweir         }
694cdf0e10cSrcweir         else if ( o == Py_False )
695cdf0e10cSrcweir         {
696cdf0e10cSrcweir             sal_Bool b = sal_False;
697cdf0e10cSrcweir             a = Any( &b, getBooleanCppuType() );
698cdf0e10cSrcweir         }
699cdf0e10cSrcweir         else
700cdf0e10cSrcweir         {
701cdf0e10cSrcweir             sal_Int32 l = (sal_Int32) PyInt_AsLong( o );
702cdf0e10cSrcweir             if( l < 128 && l >= -128 )
703cdf0e10cSrcweir             {
704cdf0e10cSrcweir                 sal_Int8 b = (sal_Int8 ) l;
705cdf0e10cSrcweir                 a <<= b;
706cdf0e10cSrcweir             }
707cdf0e10cSrcweir             else if( l <= 0x7fff && l >= -0x8000 )
708cdf0e10cSrcweir             {
709cdf0e10cSrcweir                 sal_Int16 s = (sal_Int16) l;
710cdf0e10cSrcweir                 a <<= s;
711cdf0e10cSrcweir             }
712cdf0e10cSrcweir             else
713cdf0e10cSrcweir             {
714cdf0e10cSrcweir                 a <<= l;
715cdf0e10cSrcweir             }
716cdf0e10cSrcweir         }
717cdf0e10cSrcweir     }
7180ce050feSPedro Giffuni #endif				// Python 3 has no PyInt
719cdf0e10cSrcweir     else if (PyLong_Check (o))
720cdf0e10cSrcweir     {
721cdf0e10cSrcweir         sal_Int64 l = (sal_Int64)PyLong_AsLong (o);
722cdf0e10cSrcweir         if( l < 128 && l >= -128 )
723cdf0e10cSrcweir         {
724cdf0e10cSrcweir             sal_Int8 b = (sal_Int8 ) l;
725cdf0e10cSrcweir             a <<= b;
726cdf0e10cSrcweir         }
727cdf0e10cSrcweir         else if( l <= 0x7fff && l >= -0x8000 )
728cdf0e10cSrcweir         {
729cdf0e10cSrcweir             sal_Int16 s = (sal_Int16) l;
730cdf0e10cSrcweir             a <<= s;
731cdf0e10cSrcweir         }
732cdf0e10cSrcweir         else if( l <= SAL_CONST_INT64(0x7fffffff) &&
733cdf0e10cSrcweir                  l >= -SAL_CONST_INT64(0x80000000) )
734cdf0e10cSrcweir         {
735cdf0e10cSrcweir             sal_Int32 l32 = (sal_Int32) l;
736cdf0e10cSrcweir             a <<= l32;
737cdf0e10cSrcweir         }
738cdf0e10cSrcweir         else
739cdf0e10cSrcweir         {
740cdf0e10cSrcweir             a <<= l;
741cdf0e10cSrcweir         }
742cdf0e10cSrcweir     }
743cdf0e10cSrcweir     else if (PyFloat_Check (o))
744cdf0e10cSrcweir     {
745cdf0e10cSrcweir         double d = PyFloat_AsDouble (o);
746cdf0e10cSrcweir         a <<= d;
747cdf0e10cSrcweir     }
74877dc4149SPedro Giffuni #if PY_MAJOR_VERSION < 3
749564d9007SPedro Giffuni     else if (PyBytes_Check (o))
750cdf0e10cSrcweir 	a <<= pyString2ustring(o);
75177dc4149SPedro Giffuni #endif
752cdf0e10cSrcweir     else if( PyUnicode_Check( o ) )
753cdf0e10cSrcweir 	a <<= pyString2ustring(o);
754cdf0e10cSrcweir     else if (PyTuple_Check (o))
755cdf0e10cSrcweir     {
756cdf0e10cSrcweir         Sequence<Any> s (PyTuple_Size (o));
757cdf0e10cSrcweir         for (int i = 0; i < PyTuple_Size (o); i++)
758cdf0e10cSrcweir         {
759cdf0e10cSrcweir             s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
760cdf0e10cSrcweir         }
761cdf0e10cSrcweir         a <<= s;
762cdf0e10cSrcweir     }
763cdf0e10cSrcweir     else
764cdf0e10cSrcweir     {
765cdf0e10cSrcweir         Runtime runtime;
766cdf0e10cSrcweir         // should be removed, in case ByteSequence gets derived from String
767cdf0e10cSrcweir         if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) )
768cdf0e10cSrcweir         {
769cdf0e10cSrcweir             PyRef str(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
770cdf0e10cSrcweir             Sequence< sal_Int8 > seq;
771564d9007SPedro Giffuni             if( PyBytes_Check( str.get() ) )
772cdf0e10cSrcweir             {
773cdf0e10cSrcweir                 seq = Sequence<sal_Int8 > (
774564d9007SPedro Giffuni                     (sal_Int8*) PyBytes_AsString(str.get()), PyBytes_Size(str.get()));
775cdf0e10cSrcweir             }
77677dc4149SPedro Giffuni #if PY_MAJOR_VERSION >= 3
77777dc4149SPedro Giffuni             else if ( PyByteArray_Check( str.get() ) )
77877dc4149SPedro Giffuni             {
77977dc4149SPedro Giffuni                 seq = Sequence< sal_Int8 >(
78077dc4149SPedro Giffuni                     (sal_Int8 *) PyByteArray_AS_STRING(str.get()), PyByteArray_GET_SIZE(str.get()));
78177dc4149SPedro Giffuni             }
78277dc4149SPedro Giffuni #endif
783cdf0e10cSrcweir             a <<= seq;
784cdf0e10cSrcweir         }
785cdf0e10cSrcweir         else
786cdf0e10cSrcweir         if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
787cdf0e10cSrcweir         {
788cdf0e10cSrcweir             Type t = PyType2Type( o );
789cdf0e10cSrcweir             a <<= t;
790cdf0e10cSrcweir         }
791cdf0e10cSrcweir         else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) )
792cdf0e10cSrcweir         {
793cdf0e10cSrcweir             a = PyEnum2Enum( o );
794cdf0e10cSrcweir         }
795cdf0e10cSrcweir         else if( isInstanceOfStructOrException( o ) )
796cdf0e10cSrcweir         {
797cdf0e10cSrcweir             PyRef struc(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
798cdf0e10cSrcweir             PyUNO * obj = (PyUNO*)struc.get();
799cdf0e10cSrcweir             Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY );
800cdf0e10cSrcweir             if( holder.is( ) )
801cdf0e10cSrcweir                 a = holder->getMaterial();
802cdf0e10cSrcweir             else
803cdf0e10cSrcweir             {
804cdf0e10cSrcweir                 throw RuntimeException(
805cdf0e10cSrcweir                     USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ),
806cdf0e10cSrcweir                     Reference< XInterface > () );
807cdf0e10cSrcweir             }
808cdf0e10cSrcweir         }
80977dc4149SPedro Giffuni         else if( PyObject_IsInstance( o, getPyUnoClass().get() ) )
810cdf0e10cSrcweir         {
811cdf0e10cSrcweir             PyUNO* o_pi;
812cdf0e10cSrcweir             o_pi = (PyUNO*) o;
813cdf0e10cSrcweir             if (o_pi->members->wrappedObject.getValueTypeClass () ==
814cdf0e10cSrcweir                 com::sun::star::uno::TypeClass_STRUCT ||
815cdf0e10cSrcweir                 o_pi->members->wrappedObject.getValueTypeClass () ==
816cdf0e10cSrcweir                 com::sun::star::uno::TypeClass_EXCEPTION)
817cdf0e10cSrcweir             {
818cdf0e10cSrcweir                 Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY);
819cdf0e10cSrcweir 
820cdf0e10cSrcweir                 if (!my_mh.is ())
821cdf0e10cSrcweir                 {
822cdf0e10cSrcweir                     throw RuntimeException(
823cdf0e10cSrcweir                         USTR_ASCII( "struct wrapper does not support XMaterialHolder" ),
824cdf0e10cSrcweir                         Reference< XInterface > () );
825cdf0e10cSrcweir                 }
826cdf0e10cSrcweir                 else
827cdf0e10cSrcweir                     a = my_mh->getMaterial ();
828cdf0e10cSrcweir             }
829cdf0e10cSrcweir             else
830cdf0e10cSrcweir             {
831cdf0e10cSrcweir                 a = o_pi->members->wrappedObject;
832cdf0e10cSrcweir             }
833cdf0e10cSrcweir         }
834cdf0e10cSrcweir         else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) )
835cdf0e10cSrcweir         {
836cdf0e10cSrcweir             sal_Unicode c = PyChar2Unicode( o );
837cdf0e10cSrcweir             a.setValue( &c, getCharCppuType( ));
838cdf0e10cSrcweir         }
839cdf0e10cSrcweir         else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
840cdf0e10cSrcweir         {
841cdf0e10cSrcweir             if( ACCEPT_UNO_ANY == mode )
842cdf0e10cSrcweir             {
843cdf0e10cSrcweir                 a = pyObject2Any( PyRef( PyObject_GetAttrString( o , const_cast< char * >("value") ), SAL_NO_ACQUIRE) );
844cdf0e10cSrcweir                 Type t;
845cdf0e10cSrcweir                 pyObject2Any( PyRef( PyObject_GetAttrString( o, const_cast< char * >("type") ), SAL_NO_ACQUIRE ) ) >>= t;
846cdf0e10cSrcweir 
847cdf0e10cSrcweir                 try
848cdf0e10cSrcweir                 {
849cdf0e10cSrcweir                     a = getImpl()->cargo->xTypeConverter->convertTo( a, t );
850cdf0e10cSrcweir                 }
851cdf0e10cSrcweir                 catch( com::sun::star::uno::Exception & e )
852cdf0e10cSrcweir                 {
853cdf0e10cSrcweir                     throw RuntimeException( e.Message, e.Context );
854cdf0e10cSrcweir                 }
855cdf0e10cSrcweir             }
856cdf0e10cSrcweir             else
857cdf0e10cSrcweir             {
858cdf0e10cSrcweir                 throw RuntimeException(
859cdf0e10cSrcweir                     OUString( RTL_CONSTASCII_USTRINGPARAM(
860cdf0e10cSrcweir                                   "uno.Any instance not accepted during method call, "
861cdf0e10cSrcweir                                   "use uno.invoke instead" ) ),
862cdf0e10cSrcweir                     Reference< XInterface > () );
863cdf0e10cSrcweir             }
864cdf0e10cSrcweir         }
865cdf0e10cSrcweir         else
866cdf0e10cSrcweir         {
867cdf0e10cSrcweir             Reference< XInterface > mappedObject;
868cdf0e10cSrcweir             Reference< XInvocation > adapterObject;
869cdf0e10cSrcweir 
870cdf0e10cSrcweir             // instance already mapped out to the world ?
871cdf0e10cSrcweir             PyRef2Adapter::iterator ii = impl->cargo->mappedObjects.find( PyRef( o ) );
872cdf0e10cSrcweir             if( ii != impl->cargo->mappedObjects.end() )
873cdf0e10cSrcweir             {
874cdf0e10cSrcweir                 adapterObject = ii->second;
875cdf0e10cSrcweir             }
876cdf0e10cSrcweir 
877cdf0e10cSrcweir             if( adapterObject.is() )
878cdf0e10cSrcweir             {
879cdf0e10cSrcweir                 // object got already bridged !
880cdf0e10cSrcweir                 Reference< com::sun::star::lang::XUnoTunnel > tunnel( adapterObject, UNO_QUERY );
881cdf0e10cSrcweir 
882cdf0e10cSrcweir                 Adapter *pAdapter = ( Adapter * )
883cdf0e10cSrcweir                     sal::static_int_cast< sal_IntPtr >(
884cdf0e10cSrcweir                         tunnel->getSomething(
885cdf0e10cSrcweir                             ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
886cdf0e10cSrcweir 
887cdf0e10cSrcweir                 mappedObject = impl->cargo->xAdapterFactory->createAdapter(
888cdf0e10cSrcweir                     adapterObject, pAdapter->getWrappedTypes() );
889cdf0e10cSrcweir             }
890cdf0e10cSrcweir             else
891cdf0e10cSrcweir             {
892cdf0e10cSrcweir                 Sequence< Type > interfaces = invokeGetTypes( *this, o );
893cdf0e10cSrcweir                 if( interfaces.getLength() )
894cdf0e10cSrcweir                 {
895cdf0e10cSrcweir                     Adapter *pAdapter = new Adapter( o, interfaces );
896cdf0e10cSrcweir                     mappedObject =
897cdf0e10cSrcweir                         getImpl()->cargo->xAdapterFactory->createAdapter(
898cdf0e10cSrcweir                             pAdapter, interfaces );
899cdf0e10cSrcweir 
900cdf0e10cSrcweir                     // keep a list of exported objects to ensure object identity !
901cdf0e10cSrcweir                     impl->cargo->mappedObjects[ PyRef(o) ] =
902cdf0e10cSrcweir                         com::sun::star::uno::WeakReference< XInvocation > ( pAdapter );
903cdf0e10cSrcweir                 }
904cdf0e10cSrcweir             }
905cdf0e10cSrcweir             if( mappedObject.is() )
906cdf0e10cSrcweir             {
907cdf0e10cSrcweir                 a = com::sun::star::uno::makeAny( mappedObject );
908cdf0e10cSrcweir             }
909cdf0e10cSrcweir             else
910cdf0e10cSrcweir             {
911cdf0e10cSrcweir                 OUStringBuffer buf;
912cdf0e10cSrcweir                 buf.appendAscii( "Couldn't convert " );
913cdf0e10cSrcweir                 PyRef reprString( PyObject_Str( o ) , SAL_NO_ACQUIRE );
91477dc4149SPedro Giffuni                 buf.append( pyString2ustring( reprString.get() ) );
915cdf0e10cSrcweir                 buf.appendAscii( " to a UNO type" );
916cdf0e10cSrcweir                 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
917cdf0e10cSrcweir             }
918cdf0e10cSrcweir         }
919cdf0e10cSrcweir     }
920cdf0e10cSrcweir     return a;
921cdf0e10cSrcweir }
922cdf0e10cSrcweir 
extractUnoException(const PyRef & excType,const PyRef & excValue,const PyRef & excTraceback) const923cdf0e10cSrcweir Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
924cdf0e10cSrcweir {
925cdf0e10cSrcweir     PyRef str;
926cdf0e10cSrcweir     Any ret;
927cdf0e10cSrcweir     if( excTraceback.is() )
928cdf0e10cSrcweir     {
929cdf0e10cSrcweir         PyRef unoModule( impl ? impl->cargo->getUnoModule() : 0 );
930cdf0e10cSrcweir         if( unoModule.is() )
931cdf0e10cSrcweir         {
932cdf0e10cSrcweir             PyRef extractTraceback(
933cdf0e10cSrcweir                 PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) );
934cdf0e10cSrcweir 
935cdf0e10cSrcweir             if( extractTraceback.is() )
936cdf0e10cSrcweir             {
937cdf0e10cSrcweir                 PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE );
938cdf0e10cSrcweir                 PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
939cdf0e10cSrcweir                 str = PyRef( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
940cdf0e10cSrcweir             }
941cdf0e10cSrcweir             else
942cdf0e10cSrcweir             {
943cdf0e10cSrcweir                 str = PyRef(
944564d9007SPedro Giffuni                     PyBytes_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ),
945cdf0e10cSrcweir                     SAL_NO_ACQUIRE );
946cdf0e10cSrcweir             }
947cdf0e10cSrcweir         }
948cdf0e10cSrcweir         else
949cdf0e10cSrcweir         {
950cdf0e10cSrcweir             str = PyRef(
951564d9007SPedro Giffuni                 PyBytes_FromString( "Couldn't find uno.py, no stacktrace available" ),
952cdf0e10cSrcweir                 SAL_NO_ACQUIRE );
953cdf0e10cSrcweir         }
954cdf0e10cSrcweir 
955cdf0e10cSrcweir     }
956cdf0e10cSrcweir     else
957cdf0e10cSrcweir     {
958cdf0e10cSrcweir         // it may occur, that no traceback is given (e.g. only native code below)
959564d9007SPedro Giffuni         str = PyRef( PyBytes_FromString( "no traceback available" ), SAL_NO_ACQUIRE);
960cdf0e10cSrcweir     }
961cdf0e10cSrcweir 
962cdf0e10cSrcweir     if( isInstanceOfStructOrException( excValue.get() ) )
963cdf0e10cSrcweir     {
964cdf0e10cSrcweir         ret = pyObject2Any( excValue );
965cdf0e10cSrcweir     }
966cdf0e10cSrcweir     else
967cdf0e10cSrcweir     {
968cdf0e10cSrcweir         OUStringBuffer buf;
969cdf0e10cSrcweir         PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
970cdf0e10cSrcweir         if( typeName.is() )
971cdf0e10cSrcweir         {
97277dc4149SPedro Giffuni             buf.append( pyString2ustring( typeName.get() ) );
973cdf0e10cSrcweir         }
974cdf0e10cSrcweir         else
975cdf0e10cSrcweir         {
976cdf0e10cSrcweir             buf.appendAscii( "no typename available" );
977cdf0e10cSrcweir         }
978cdf0e10cSrcweir         buf.appendAscii( ": " );
979cdf0e10cSrcweir         PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
980cdf0e10cSrcweir         if( valueRep.is() )
981cdf0e10cSrcweir         {
98277dc4149SPedro Giffuni             buf.append( pyString2ustring( valueRep.get()));
983cdf0e10cSrcweir         }
984cdf0e10cSrcweir         else
985cdf0e10cSrcweir         {
986cdf0e10cSrcweir             buf.appendAscii( "Couldn't convert exception value to a string" );
987cdf0e10cSrcweir         }
988cdf0e10cSrcweir         buf.appendAscii( ", traceback follows\n" );
989cdf0e10cSrcweir         if( str.is() )
990cdf0e10cSrcweir         {
99177dc4149SPedro Giffuni             buf.append( pyString2ustring( str.get() ) );
992cdf0e10cSrcweir         }
993cdf0e10cSrcweir         else
994cdf0e10cSrcweir         {
995cdf0e10cSrcweir             buf.appendAscii( ", no traceback available\n" );
996cdf0e10cSrcweir         }
997cdf0e10cSrcweir         RuntimeException e;
998cdf0e10cSrcweir         e.Message = buf.makeStringAndClear();
999cdf0e10cSrcweir         ret = com::sun::star::uno::makeAny( e );
1000cdf0e10cSrcweir     }
1001cdf0e10cSrcweir     return ret;
1002cdf0e10cSrcweir }
1003cdf0e10cSrcweir 
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir static const char * g_NUMERICID = "pyuno.lcNumeric";
1006cdf0e10cSrcweir static ::std::vector< rtl::OString > g_localeList;
1007cdf0e10cSrcweir 
ensureUnlimitedLifetime(const char * str)1008cdf0e10cSrcweir static const char *ensureUnlimitedLifetime( const char *str )
1009cdf0e10cSrcweir {
1010cdf0e10cSrcweir     int size = g_localeList.size();
1011cdf0e10cSrcweir     int i;
1012cdf0e10cSrcweir     for( i = 0 ; i < size ; i ++ )
1013cdf0e10cSrcweir     {
1014cdf0e10cSrcweir         if( 0 == strcmp( g_localeList[i].getStr(), str ) )
1015cdf0e10cSrcweir             break;
1016cdf0e10cSrcweir     }
1017cdf0e10cSrcweir     if( i == size )
1018cdf0e10cSrcweir     {
1019cdf0e10cSrcweir         g_localeList.push_back( str );
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir     return g_localeList[i].getStr();
1022cdf0e10cSrcweir }
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir 
PyThreadAttach(PyInterpreterState * interp)1025cdf0e10cSrcweir PyThreadAttach::PyThreadAttach( PyInterpreterState *interp)
1026cdf0e10cSrcweir     throw ( com::sun::star::uno::RuntimeException )
1027cdf0e10cSrcweir {
1028cdf0e10cSrcweir     tstate = PyThreadState_New( interp );
1029cdf0e10cSrcweir     if( !tstate  )
1030cdf0e10cSrcweir         throw RuntimeException(
1031cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ),
1032cdf0e10cSrcweir             Reference< XInterface > () );
1033cdf0e10cSrcweir     PyEval_AcquireThread( tstate);
1034cdf0e10cSrcweir     // set LC_NUMERIC to "C"
1035cdf0e10cSrcweir     const char * oldLocale =
1036cdf0e10cSrcweir         ensureUnlimitedLifetime( setlocale( LC_NUMERIC, 0 )  );
1037cdf0e10cSrcweir     setlocale( LC_NUMERIC, "C" );
1038cdf0e10cSrcweir     PyRef locale( // python requires C locale
1039cdf0e10cSrcweir         PyLong_FromVoidPtr( (void*)oldLocale ), SAL_NO_ACQUIRE);
1040cdf0e10cSrcweir     PyDict_SetItemString(
1041cdf0e10cSrcweir         PyThreadState_GetDict(), g_NUMERICID, locale.get() );
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir 
~PyThreadAttach()1044cdf0e10cSrcweir PyThreadAttach::~PyThreadAttach()
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir     PyObject *value =
1047cdf0e10cSrcweir         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1048cdf0e10cSrcweir     if( value )
1049cdf0e10cSrcweir         setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
1050cdf0e10cSrcweir     PyThreadState_Clear( tstate );
1051cdf0e10cSrcweir     PyEval_ReleaseThread( tstate );
1052cdf0e10cSrcweir     PyThreadState_Delete( tstate );
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir }
1055cdf0e10cSrcweir 
PyThreadDetach()1056cdf0e10cSrcweir PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException )
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir     tstate = PyThreadState_Get();
1059cdf0e10cSrcweir     PyObject *value =
1060cdf0e10cSrcweir         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1061cdf0e10cSrcweir     if( value )
1062cdf0e10cSrcweir         setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
1063cdf0e10cSrcweir     PyEval_ReleaseThread( tstate );
1064cdf0e10cSrcweir }
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir     /** Acquires the global interpreter lock again
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir     */
~PyThreadDetach()1069cdf0e10cSrcweir PyThreadDetach::~PyThreadDetach()
1070cdf0e10cSrcweir {
1071cdf0e10cSrcweir     PyEval_AcquireThread( tstate );
1072cdf0e10cSrcweir //     PyObject *value =
1073cdf0e10cSrcweir //         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir     // python requires C LC_NUMERIC locale,
1076cdf0e10cSrcweir     // always set even when it is already "C"
1077cdf0e10cSrcweir     setlocale( LC_NUMERIC, "C" );
1078cdf0e10cSrcweir }
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 
getUnoModule()1081cdf0e10cSrcweir PyRef RuntimeCargo::getUnoModule()
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir     if( ! dictUnoModule.is() )
1084cdf0e10cSrcweir     {
1085cdf0e10cSrcweir         dictUnoModule = importUnoModule();
1086cdf0e10cSrcweir     }
1087cdf0e10cSrcweir     return dictUnoModule;
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir }
1090