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