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