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 <boost/unordered_map.hpp>
23 : : #include <utility>
24 : :
25 : : #include <osl/module.hxx>
26 : : #include <osl/thread.h>
27 : : #include <osl/file.hxx>
28 : :
29 : : #include <typelib/typedescription.hxx>
30 : :
31 : : #include <rtl/ustring.hxx>
32 : : #include <rtl/strbuf.hxx>
33 : : #include <rtl/ustrbuf.hxx>
34 : : #include <rtl/uuid.h>
35 : : #include <rtl/bootstrap.hxx>
36 : :
37 : : #include <uno/current_context.hxx>
38 : : #include <cppuhelper/bootstrap.hxx>
39 : :
40 : : #include <com/sun/star/reflection/XIdlReflection.hpp>
41 : : #include <com/sun/star/reflection/XIdlClass.hpp>
42 : : #include <com/sun/star/registry/InvalidRegistryException.hpp>
43 : :
44 : : using osl::Module;
45 : :
46 : : using rtl::OString;
47 : : using rtl::OUString;
48 : : using rtl::OUStringHash;
49 : : using rtl::OUStringToOString;
50 : : using rtl::OUStringBuffer;
51 : : using rtl::OStringBuffer;
52 : :
53 : : using com::sun::star::uno::Sequence;
54 : : using com::sun::star::uno::Reference;
55 : : using com::sun::star::uno::XInterface;
56 : : using com::sun::star::uno::Any;
57 : : using com::sun::star::uno::makeAny;
58 : : using com::sun::star::uno::UNO_QUERY;
59 : : using com::sun::star::uno::RuntimeException;
60 : : using com::sun::star::uno::TypeDescription;
61 : : using com::sun::star::uno::XComponentContext;
62 : : using com::sun::star::container::NoSuchElementException;
63 : : using com::sun::star::reflection::XIdlReflection;
64 : : using com::sun::star::reflection::XIdlClass;
65 : : using com::sun::star::script::XInvocation2;
66 : :
67 : : using namespace pyuno;
68 : :
69 : : namespace {
70 : :
71 : : /**
72 : : @ index of the next to be used member in the initializer list !
73 : : */
74 : : // LEM TODO: export member names as keyword arguments in initialiser?
75 : : // Python supports very flexible variadic functions. By marking
76 : : // variables with one asterisk (e.g. *var) the given variable is
77 : : // defined to be a tuple of all the extra arguments. By marking
78 : : // variables with two asterisks (e.g. **var) the given variable is a
79 : : // dictionary of all extra keyword arguments; the keys are strings,
80 : : // which are the names that were used to identify the arguments. If
81 : : // they exist, these arguments must be the last one in the list.
82 : :
83 : : class fillStructState
84 : : {
85 : : // Keyword arguments used
86 : : PyObject *used;
87 : : // Which structure members are initialised
88 : : boost::unordered_map <const OUString, bool, OUStringHash> initialised;
89 : : // How many positional arguments are consumed
90 : : // This is always the so-many first ones
91 : : sal_Int32 nPosConsumed;
92 : : // The total number of members set, either by a keyword argument or a positional argument
93 : : unsigned int nMembersSet;
94 : :
95 : : public:
96 : 7715 : fillStructState()
97 : 7715 : : used (PyDict_New())
98 : : , initialised ()
99 : : , nPosConsumed (0)
100 [ + - ]: 7715 : , nMembersSet (0)
101 : : {
102 [ - + ]: 7715 : if ( ! used )
103 [ # # ][ # # ]: 0 : throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("pyuno._createUnoStructHelper failed to create new dictionary")), Reference< XInterface > ());
104 : 7715 : }
105 : 7715 : ~fillStructState()
106 : 7715 : {
107 [ - + ][ # # ]: 7715 : Py_DECREF(used);
108 : 7715 : }
109 : 0 : void setUsed(PyObject *key)
110 : : {
111 : 0 : PyDict_SetItem(used, key, Py_True);
112 : 0 : }
113 : : bool isUsed(PyObject *key) const
114 : : {
115 : : return Py_True == PyDict_GetItem(used, key);
116 : : }
117 : 6240 : void setInitialised(OUString key, sal_Int32 pos = -1)
118 : : {
119 [ - + ]: 6240 : if (initialised[key])
120 : : {
121 : 0 : OUStringBuffer buf;
122 [ # # ]: 0 : buf.appendAscii( "pyuno._createUnoStructHelper: member '");
123 [ # # ]: 0 : buf.append(key);
124 [ # # ]: 0 : buf.appendAscii( "'");
125 [ # # ]: 0 : if ( pos >= 0 )
126 : : {
127 [ # # ]: 0 : buf.appendAscii( " at position ");
128 [ # # ]: 0 : buf.append(pos);
129 : : }
130 [ # # ]: 0 : buf.appendAscii( " initialised multiple times.");
131 [ # # ][ # # ]: 0 : throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
132 : : }
133 : 6240 : initialised[key] = true;
134 : 6240 : ++nMembersSet;
135 [ + - ]: 6240 : if ( pos >= 0 )
136 : 6240 : ++nPosConsumed;
137 : 6240 : }
138 : 6240 : bool isInitialised(OUString key)
139 : : {
140 : 6240 : return initialised[key];
141 : : }
142 : 7715 : PyObject *getUsed() const
143 : : {
144 : 7715 : return used;
145 : : }
146 : 16035 : sal_Int32 getCntConsumed() const
147 : : {
148 : 16035 : return nPosConsumed;
149 : : }
150 : : int getCntMembersSet() const
151 : : {
152 : : return nMembersSet;
153 : : }
154 : : };
155 : :
156 : 2080 : static void fillStruct(
157 : : const Reference< XInvocation2 > &inv,
158 : : typelib_CompoundTypeDescription *pCompType,
159 : : PyObject *initializer,
160 : : PyObject *kwinitializer,
161 : : fillStructState &state,
162 : : const Runtime &runtime) throw ( RuntimeException )
163 : : {
164 [ - + ]: 2080 : if( pCompType->pBaseTypeDescription )
165 : 0 : fillStruct( inv, pCompType->pBaseTypeDescription, initializer, kwinitializer, state, runtime );
166 : :
167 : 2080 : const sal_Int32 nMembers = pCompType->nMembers;
168 : : {
169 [ + + ]: 8320 : for( int i = 0 ; i < nMembers ; i ++ )
170 : : {
171 : 6240 : const OUString OUMemberName (pCompType->ppMemberNames[i]);
172 [ + - ][ + - ]: 6240 : PyObject *pyMemberName = PyString_FromString(::rtl::OUStringToOString( OUMemberName, RTL_TEXTENCODING_UTF8 ).getStr());
173 [ - + ][ + - ]: 6240 : if ( PyObject *element = PyDict_GetItem(kwinitializer, pyMemberName ) )
174 : : {
175 [ # # ]: 0 : state.setInitialised(OUMemberName);
176 [ # # ]: 0 : state.setUsed(pyMemberName);
177 [ # # ][ # # ]: 0 : Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
178 [ # # ][ # # ]: 0 : inv->setValue( OUMemberName, a );
179 : : }
180 : 6240 : }
181 : : }
182 : : {
183 : 2080 : const int remainingPosInitialisers = PyTuple_Size(initializer) - state.getCntConsumed();
184 [ + + ][ + - ]: 8320 : for( int i = 0 ; i < remainingPosInitialisers && i < nMembers ; i ++ )
[ + + ]
185 : : {
186 : 6240 : const int tupleIndex = state.getCntConsumed();
187 : 6240 : const OUString pMemberName (pCompType->ppMemberNames[i]);
188 [ + - ]: 6240 : state.setInitialised(pMemberName, tupleIndex);
189 [ + - ]: 6240 : PyObject *element = PyTuple_GetItem( initializer, tupleIndex );
190 [ + - ][ + - ]: 6240 : Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
191 [ + - ][ + - ]: 6240 : inv->setValue( pMemberName, a );
192 : 6240 : }
193 : : }
194 [ + + ]: 8320 : for ( int i = 0; i < nMembers ; ++i)
195 : : {
196 : 6240 : const OUString memberName (pCompType->ppMemberNames[i]);
197 [ - + ][ + - ]: 6240 : if ( ! state.isInitialised( memberName ) )
198 : : {
199 : 0 : OUStringBuffer buf;
200 [ # # ]: 0 : buf.appendAscii( "pyuno._createUnoStructHelper: member '");
201 [ # # ]: 0 : buf.append(memberName);
202 [ # # ]: 0 : buf.appendAscii( "' of struct type '");
203 [ # # ]: 0 : buf.append(pCompType->aBase.pTypeName);
204 [ # # ]: 0 : buf.appendAscii( "' not given a value.");
205 [ # # ][ # # ]: 0 : throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
206 : : }
207 : 6240 : }
208 : 2080 : }
209 : :
210 : 112 : OUString getLibDir()
211 : : {
212 : : static OUString *pLibDir;
213 [ + - ]: 112 : if( !pLibDir )
214 : : {
215 [ + - ][ + - ]: 112 : osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
216 [ + - ]: 112 : if( ! pLibDir )
217 : : {
218 [ + - ][ + - ]: 112 : static OUString libDir;
219 : :
220 : : // workarounds the $(ORIGIN) until it is available
221 [ + - ]: 112 : if( Module::getUrlFromAddress(
222 [ + - ]: 112 : reinterpret_cast< oslGenericFunction >(getLibDir), libDir ) )
223 : : {
224 : 112 : libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
225 [ + - ]: 112 : OUString name ( RTL_CONSTASCII_USTRINGPARAM( "PYUNOLIBDIR" ) );
226 : 112 : rtl_bootstrap_set( name.pData, libDir.pData );
227 : : }
228 : 112 : pLibDir = &libDir;
229 [ + - ]: 112 : }
230 : : }
231 : 112 : return *pLibDir;
232 : : }
233 : :
234 : 0 : void raisePySystemException( const char * exceptionType, const OUString & message )
235 : : {
236 : 0 : OStringBuffer buf;
237 [ # # ]: 0 : buf.append( "Error during bootstrapping uno (");
238 [ # # ]: 0 : buf.append( exceptionType );
239 [ # # ]: 0 : buf.append( "):" );
240 [ # # ][ # # ]: 0 : buf.append( OUStringToOString( message, osl_getThreadTextEncoding() ) );
[ # # ]
241 [ # # ]: 0 : PyErr_SetString( PyExc_SystemError, buf.makeStringAndClear().getStr() );
242 : 0 : }
243 : :
244 : : extern "C" {
245 : :
246 : 112 : static PyObject* getComponentContext(
247 : : SAL_UNUSED_PARAMETER PyObject*, SAL_UNUSED_PARAMETER PyObject*)
248 : : {
249 : 112 : PyRef ret;
250 : : try
251 : : {
252 : 112 : Reference<XComponentContext> ctx;
253 : :
254 : : // getLibDir() must be called in order to set bootstrap variables correctly !
255 [ + - ]: 112 : OUString path( getLibDir());
256 [ + - ][ + - ]: 112 : if( Runtime::isInitialized() )
257 : : {
258 [ + - ]: 112 : Runtime runtime;
259 [ + - ][ + - ]: 112 : ctx = runtime.getImpl()->cargo->xContext;
260 : : }
261 : : else
262 : : {
263 : 0 : OUString iniFile;
264 [ # # ]: 0 : if( path.isEmpty() )
265 : : {
266 : : PyErr_SetString(
267 : : PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini "
268 [ # # ]: 0 : "file for bootstrapping python uno bridge\n" );
269 : 0 : return NULL;
270 : : }
271 : :
272 : 0 : OUStringBuffer iniFileName;
273 [ # # ]: 0 : iniFileName.append( path );
274 [ # # ]: 0 : iniFileName.appendAscii( "/" );
275 [ # # ]: 0 : iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) );
276 [ # # ]: 0 : iniFile = iniFileName.makeStringAndClear();
277 : 0 : osl::DirectoryItem item;
278 [ # # ][ # # ]: 0 : if( osl::DirectoryItem::get( iniFile, item ) == item.E_None )
279 : : {
280 : : // in case pyuno.ini exists, use this file for bootstrapping
281 [ # # ]: 0 : PyThreadDetach antiguard;
282 [ # # ][ # # ]: 0 : ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile);
[ # # ]
283 : : }
284 : : else
285 : : {
286 : : // defaulting to the standard bootstrapping
287 [ # # ]: 0 : PyThreadDetach antiguard;
288 [ # # ][ # # ]: 0 : ctx = cppu::defaultBootstrap_InitialComponentContext ();
[ # # ]
289 [ # # ][ # # ]: 0 : }
290 : :
291 : : }
292 : :
293 [ + - ][ - + ]: 112 : if( ! Runtime::isInitialized() )
294 : : {
295 [ # # ]: 0 : Runtime::initialize( ctx );
296 : : }
297 [ + - ]: 112 : Runtime runtime;
298 [ + - ][ + - ]: 112 : ret = runtime.any2PyObject( makeAny( ctx ) );
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ]
299 : : }
300 [ # # ]: 0 : catch (const com::sun::star::registry::InvalidRegistryException &e)
301 : : {
302 : : // can't use raisePyExceptionWithAny() here, because the function
303 : : // does any conversions, which will not work with a
304 : : // wrongly bootstrapped pyuno!
305 [ # # ]: 0 : raisePySystemException( "InvalidRegistryException", e.Message );
306 : : }
307 [ # # ]: 0 : catch(const com::sun::star::lang::IllegalArgumentException & e)
308 : : {
309 [ # # ]: 0 : raisePySystemException( "IllegalArgumentException", e.Message );
310 : : }
311 [ # # ]: 0 : catch(const com::sun::star::script::CannotConvertException & e)
312 : : {
313 [ # # ]: 0 : raisePySystemException( "CannotConvertException", e.Message );
314 : : }
315 [ # # ]: 0 : catch (const com::sun::star::uno::RuntimeException & e)
316 : : {
317 [ # # ]: 0 : raisePySystemException( "RuntimeException", e.Message );
318 : : }
319 [ # # # # : 0 : catch (const com::sun::star::uno::Exception & e)
# # # # ]
320 : : {
321 [ # # ]: 0 : raisePySystemException( "uno::Exception", e.Message );
322 : : }
323 [ + - ]: 112 : return ret.getAcquired();
324 : : }
325 : :
326 : 11702 : PyObject * extractOneStringArg( PyObject *args, char const *funcName )
327 : : {
328 [ + - ][ - + ]: 11702 : if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
[ - + ]
329 : : {
330 : 0 : OStringBuffer buf;
331 [ # # ][ # # ]: 0 : buf.append( funcName ).append( ": expecting one string argument" );
332 [ # # ]: 0 : PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
333 : 0 : return NULL;
334 : : }
335 : 11702 : PyObject *obj = PyTuple_GetItem( args, 0 );
336 [ - + ][ + + ]: 11702 : if(!PyString_Check(obj) && !PyUnicode_Check(obj))
337 : : {
338 : 0 : OStringBuffer buf;
339 [ # # ][ # # ]: 0 : buf.append( funcName ).append( ": expecting one string argument" );
340 [ # # ]: 0 : PyErr_SetString( PyExc_TypeError, buf.getStr());
341 : 0 : return NULL;
342 : : }
343 : 11702 : return obj;
344 : : }
345 : :
346 : 7715 : static PyObject *createUnoStructHelper(
347 : : SAL_UNUSED_PARAMETER PyObject *, PyObject* args, PyObject* keywordArgs)
348 : : {
349 : 7715 : Any IdlStruct;
350 : 7715 : PyRef ret;
351 : : try
352 : : {
353 [ + - ]: 7715 : Runtime runtime;
354 [ + - ][ + - ]: 7715 : if( PyTuple_Size( args ) == 2 )
355 : : {
356 [ + - ]: 7715 : PyObject *structName = PyTuple_GetItem(args, 0);
357 [ + - ]: 7715 : PyObject *initializer = PyTuple_GetItem(args, 1);
358 : :
359 : : // Perhaps in Python 3, only PyUnicode_Check returns true and
360 : : // in Python 2, only PyString_Check returns true.
361 [ - + ][ # # ]: 7715 : if(PyString_Check(structName) || PyUnicode_Check(structName))
362 : : {
363 [ + - ][ + - ]: 7715 : if( PyTuple_Check( initializer ) && PyDict_Check ( keywordArgs ) )
364 : : {
365 [ + - ]: 7715 : OUString typeName( OUString::createFromAscii(PyString_AsString(structName)));
366 : 7715 : RuntimeCargo *c = runtime.getImpl()->cargo;
367 [ + - ][ + - ]: 7715 : Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
[ + - ]
368 [ + - ]: 7715 : if (idl_class.is ())
369 : : {
370 [ + - ][ + - ]: 7715 : idl_class->createObject (IdlStruct);
371 [ + - ]: 7715 : PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation );
372 : 7715 : PyRef returnCandidate( (PyObject*)me, SAL_NO_ACQUIRE );
373 : 7715 : TypeDescription desc( typeName );
374 : : OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 !
375 : :
376 : : typelib_CompoundTypeDescription *pCompType =
377 : 7715 : ( typelib_CompoundTypeDescription * ) desc.get();
378 [ + - ]: 7715 : fillStructState state;
379 [ + - ][ + + ]: 7715 : if ( PyTuple_Size( initializer ) > 0 || PyDict_Size( keywordArgs ) > 0 )
[ + - ][ - + ]
[ + + ]
380 [ + - ]: 2080 : fillStruct( me->members->xInvocation, pCompType, initializer, keywordArgs, state, runtime );
381 [ + - ][ - + ]: 7715 : if( state.getCntConsumed() != PyTuple_Size(initializer) )
382 : : {
383 : 0 : OUStringBuffer buf;
384 [ # # ]: 0 : buf.appendAscii( "pyuno._createUnoStructHelper: too many ");
385 [ # # ]: 0 : buf.appendAscii( "elements in the initializer list, expected " );
386 [ # # ]: 0 : buf.append( state.getCntConsumed() );
387 [ # # ]: 0 : buf.appendAscii( ", got " );
388 [ # # ][ # # ]: 0 : buf.append( (sal_Int32) PyTuple_Size(initializer) );
389 [ # # ][ # # ]: 0 : throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > ());
390 : : }
391 [ + - ][ + - ]: 7715 : ret = PyRef( PyTuple_Pack(2, returnCandidate.get(), state.getUsed()), SAL_NO_ACQUIRE);
[ + - ][ + - ]
[ + - ]
392 : : }
393 : : else
394 : : {
395 : 0 : OStringBuffer buf;
396 [ # # ]: 0 : buf.append( "UNO struct " );
397 [ # # ][ # # ]: 0 : buf.append( PyString_AsString(structName) );
398 [ # # ]: 0 : buf.append( " is unkown" );
399 [ # # ]: 0 : PyErr_SetString (PyExc_RuntimeError, buf.getStr());
400 : 7715 : }
401 : : }
402 : : else
403 : : {
404 : : PyErr_SetString(
405 : : PyExc_RuntimeError,
406 [ # # ]: 0 : "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
407 : 7715 : }
408 : : }
409 : : else
410 : : {
411 [ # # ]: 7715 : PyErr_SetString (PyExc_AttributeError, "createUnoStruct: first argument wasn't a string");
412 : : }
413 : : }
414 : : else
415 : : {
416 [ # # ]: 0 : PyErr_SetString (PyExc_AttributeError, "pyuno._createUnoStructHelper: expects exactly two non-keyword arguments:\n\tStructure Name\n\tinitialiser tuple; may be the empty tuple");
417 [ + - ]: 7715 : }
418 : : }
419 [ # # ]: 0 : catch( const com::sun::star::uno::RuntimeException & e )
420 : : {
421 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
422 : : }
423 [ # # ]: 0 : catch( const com::sun::star::script::CannotConvertException & e )
424 : : {
425 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
426 : : }
427 [ # # # # : 0 : catch( const com::sun::star::uno::Exception & e )
# # ]
428 : : {
429 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
430 : : }
431 [ + - ]: 7715 : return ret.getAcquired();
432 : : }
433 : :
434 : 786 : static PyObject *getTypeByName(
435 : : SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
436 : : {
437 : 786 : PyObject * ret = NULL;
438 : :
439 : : try
440 : : {
441 : : char *name;
442 : :
443 [ + - ][ + - ]: 786 : if (PyArg_ParseTuple (args, "s", &name))
444 : : {
445 : 786 : OUString typeName ( OUString::createFromAscii( name ) );
446 : 786 : TypeDescription typeDesc( typeName );
447 [ + - ]: 786 : if( typeDesc.is() )
448 : : {
449 [ + - ]: 786 : Runtime runtime;
450 : : ret = PyUNO_Type_new(
451 [ + - ][ + - ]: 786 : name, (com::sun::star::uno::TypeClass)typeDesc.get()->eTypeClass, runtime );
452 : : }
453 : : else
454 : : {
455 : 0 : OStringBuffer buf;
456 [ # # ][ # # ]: 0 : buf.append( "Type " ).append(name).append( " is unknown" );
[ # # ]
457 [ # # ]: 0 : PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
458 : 786 : }
459 : : }
460 : : }
461 [ # # ]: 0 : catch ( const RuntimeException & e )
462 : : {
463 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
464 : : }
465 : 786 : return ret;
466 : : }
467 : :
468 : 1233 : static PyObject *getConstantByName(
469 : : SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
470 : : {
471 : 1233 : PyObject *ret = 0;
472 : : try
473 : : {
474 : : char *name;
475 : :
476 [ + - ][ + - ]: 1233 : if (PyArg_ParseTuple (args, "s", &name))
477 : : {
478 : 1233 : OUString typeName ( OUString::createFromAscii( name ) );
479 [ + - ]: 1233 : Runtime runtime;
480 [ + - ][ + - ]: 1233 : Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName);
481 [ - + ]: 1233 : if( a.getValueType().getTypeClass() ==
482 : : com::sun::star::uno::TypeClass_INTERFACE )
483 : : {
484 : : // a idl constant cannot be an instance of an uno-object, thus
485 : : // this cannot be a constant
486 : 0 : OUStringBuffer buf;
487 [ # # ][ # # ]: 0 : buf.appendAscii( "pyuno.getConstantByName: " ).append( typeName );
488 [ # # ]: 0 : buf.appendAscii( "is not a constant" );
489 [ # # ][ # # ]: 0 : throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > () );
490 : : }
491 [ + - ]: 1233 : PyRef constant = runtime.any2PyObject( a );
492 [ + - ][ + - ]: 1233 : ret = constant.getAcquired();
493 : : }
494 : : }
495 : 0 : catch( const NoSuchElementException & e )
496 : : {
497 : : // to the python programmer, this is a runtime exception,
498 : : // do not support tweakings with the type system
499 [ # # ]: 0 : RuntimeException runExc( e.Message, Reference< XInterface > () );
500 [ # # # # : 0 : raisePyExceptionWithAny( makeAny( runExc ) );
# # ]
501 : : }
502 : 0 : catch(const com::sun::star::script::CannotConvertException & e)
503 : : {
504 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
505 : : }
506 : 0 : catch(const com::sun::star::lang::IllegalArgumentException & e)
507 : : {
508 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
509 : : }
510 [ # # # # : 0 : catch( const RuntimeException & e )
# ]
511 : : {
512 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
513 : : }
514 : 1233 : return ret;
515 : : }
516 : :
517 : 786 : static PyObject *checkType( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
518 : : {
519 [ + - ][ - + ]: 786 : if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
[ - + ]
520 : : {
521 : 0 : OStringBuffer buf;
522 [ # # ]: 0 : buf.append( "pyuno.checkType : expecting one uno.Type argument" );
523 [ # # ]: 0 : PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
524 : 0 : return NULL;
525 : : }
526 : 786 : PyObject *obj = PyTuple_GetItem( args, 0 );
527 : :
528 : : try
529 : : {
530 [ + - ]: 786 : PyType2Type( obj );
531 : : }
532 [ # # ]: 0 : catch(const RuntimeException & e)
533 : : {
534 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
535 : 0 : return NULL;
536 : : }
537 : 786 : Py_INCREF( Py_None );
538 : 786 : return Py_None;
539 : : }
540 : :
541 : 2355 : static PyObject *checkEnum( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
542 : : {
543 [ + - ][ - + ]: 2355 : if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
[ - + ]
544 : : {
545 : 0 : OStringBuffer buf;
546 [ # # ]: 0 : buf.append( "pyuno.checkType : expecting one uno.Type argument" );
547 [ # # ]: 0 : PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
548 : 0 : return NULL;
549 : : }
550 : 2355 : PyObject *obj = PyTuple_GetItem( args, 0 );
551 : :
552 : : try
553 : : {
554 [ + + ]: 2355 : PyEnum2Enum( obj );
555 : : }
556 [ - + ]: 2466 : catch(const RuntimeException & e)
557 : : {
558 [ - + ][ - + ]: 1233 : raisePyExceptionWithAny( makeAny( e) );
559 : 1233 : return NULL;
560 : : }
561 : 1122 : Py_INCREF( Py_None );
562 : 2355 : return Py_None;
563 : : }
564 : :
565 : 11363 : static PyObject *getClass( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
566 : : {
567 : 11363 : PyObject *obj = extractOneStringArg( args, "pyuno.getClass");
568 [ - + ]: 11363 : if( ! obj )
569 : 0 : return NULL;
570 : :
571 : : try
572 : : {
573 [ + - ]: 11363 : Runtime runtime;
574 : : PyRef ret = getClass(
575 [ + - ][ + - ]: 11363 : OUString( PyString_AsString( obj), strlen(PyString_AsString(obj)),RTL_TEXTENCODING_ASCII_US),
576 [ + - ][ + + ]: 11363 : runtime );
577 [ + - ]: 9794 : Py_XINCREF( ret.get() );
578 [ + - ][ + - ]: 12932 : return ret.get();
579 : : }
580 [ - + ]: 3138 : catch(const RuntimeException & e)
581 : : {
582 : : // NOOPT !!!
583 : : // gcc 3.2.3 crashes here in the regcomp test scenario
584 : : // only since migration to python 2.3.4 ???? strange thing
585 : : // optimization switched off for this module !
586 [ - + ][ - + ]: 1569 : raisePyExceptionWithAny( makeAny(e) );
587 : : }
588 : 1569 : return NULL;
589 : : }
590 : :
591 : 998 : static PyObject *isInterface( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
592 : : {
593 : :
594 [ + - ][ + - ]: 998 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
[ + - ]
595 : : {
596 [ + - ]: 998 : PyObject *obj = PyTuple_GetItem( args, 0 );
597 [ + - ]: 998 : Runtime r;
598 [ + - ][ + - ]: 998 : return PyLong_FromLong( isInterfaceClass( r, obj ) );
[ + - ]
599 : : }
600 : 998 : return PyLong_FromLong( 0 );
601 : : }
602 : :
603 : 212 : static PyObject * generateUuid(
604 : : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * )
605 : : {
606 [ + - ]: 212 : Sequence< sal_Int8 > seq( 16 );
607 [ + - ][ + - ]: 212 : rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False );
608 : 212 : PyRef ret;
609 : : try
610 : : {
611 [ + - ]: 212 : Runtime runtime;
612 [ + - ][ + - ]: 212 : ret = runtime.any2PyObject( makeAny( seq ) );
[ + - ][ + - ]
[ + - ]
613 : : }
614 [ # # # # ]: 0 : catch( const RuntimeException & e )
615 : : {
616 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
617 : : }
618 [ + - ][ + - ]: 212 : return ret.getAcquired();
619 : : }
620 : :
621 : 0 : static PyObject *systemPathToFileUrl(
622 : : SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
623 : : {
624 [ # # ]: 0 : PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" );
625 [ # # ]: 0 : if( ! obj )
626 : 0 : return NULL;
627 : :
628 [ # # ]: 0 : OUString sysPath = pyString2ustring( obj );
629 : 0 : OUString url;
630 [ # # ]: 0 : osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url );
631 : :
632 [ # # ]: 0 : if( e != osl::FileBase::E_None )
633 : : {
634 : 0 : OUStringBuffer buf;
635 [ # # ]: 0 : buf.appendAscii( "Couldn't convert " );
636 [ # # ]: 0 : buf.append( sysPath );
637 [ # # ]: 0 : buf.appendAscii( " to a file url for reason (" );
638 [ # # ]: 0 : buf.append( (sal_Int32) e );
639 [ # # ]: 0 : buf.appendAscii( ")" );
640 : : raisePyExceptionWithAny(
641 [ # # ][ # # ]: 0 : makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
[ # # ][ # # ]
[ # # ]
642 : 0 : return NULL;
643 : : }
644 [ # # ][ # # ]: 0 : return ustring2PyUnicode( url ).getAcquired();
645 : : }
646 : :
647 : 339 : static PyObject * fileUrlToSystemPath(
648 : : SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
649 : : {
650 [ + - ]: 339 : PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" );
651 [ - + ]: 339 : if( ! obj )
652 : 0 : return NULL;
653 : :
654 [ + - ]: 339 : OUString url = pyString2ustring( obj );
655 : 339 : OUString sysPath;
656 [ + - ]: 339 : osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath );
657 : :
658 [ - + ]: 339 : if( e != osl::FileBase::E_None )
659 : : {
660 : 0 : OUStringBuffer buf;
661 [ # # ]: 0 : buf.appendAscii( "Couldn't convert file url " );
662 [ # # ]: 0 : buf.append( sysPath );
663 [ # # ]: 0 : buf.appendAscii( " to a system path for reason (" );
664 [ # # ]: 0 : buf.append( (sal_Int32) e );
665 [ # # ]: 0 : buf.appendAscii( ")" );
666 : : raisePyExceptionWithAny(
667 [ # # ][ # # ]: 0 : makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
[ # # ][ # # ]
[ # # ]
668 : 0 : return NULL;
669 : : }
670 [ + - ][ + - ]: 339 : return ustring2PyUnicode( sysPath ).getAcquired();
671 : : }
672 : :
673 : 175 : static PyObject * absolutize( SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
674 : : {
675 [ + - ][ + - ]: 175 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 )
[ + - ]
676 : : {
677 [ + - ][ + - ]: 175 : OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) );
678 [ + - ][ + - ]: 175 : OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) );
679 : 175 : OUString ret;
680 [ + - ]: 175 : oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) );
681 [ - + ]: 175 : if( e != osl_File_E_None )
682 : : {
683 : 0 : OUStringBuffer buf;
684 [ # # ]: 0 : buf.appendAscii( "Couldn't absolutize " );
685 [ # # ]: 0 : buf.append( ouRel );
686 [ # # ]: 0 : buf.appendAscii( " using root " );
687 [ # # ]: 0 : buf.append( ouPath );
688 [ # # ]: 0 : buf.appendAscii( " for reason (" );
689 [ # # ]: 0 : buf.append( (sal_Int32) e );
690 [ # # ]: 0 : buf.appendAscii( ")" );
691 : :
692 : : PyErr_SetString(
693 : : PyExc_OSError,
694 [ # # ][ # # ]: 0 : OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding()).getStr());
[ # # ][ # # ]
695 : 0 : return 0;
696 : : }
697 [ + - ][ + - ]: 175 : return ustring2PyUnicode( ret ).getAcquired();
698 : : }
699 : 175 : return 0;
700 : : }
701 : :
702 : 0 : static PyObject * invoke(SAL_UNUSED_PARAMETER PyObject *, PyObject *args)
703 : : {
704 : 0 : PyObject *ret = 0;
705 [ # # ][ # # ]: 0 : if(PyTuple_Check(args) && PyTuple_Size(args) == 3)
[ # # ]
706 : : {
707 : 0 : PyObject *object = PyTuple_GetItem(args, 0);
708 : 0 : PyObject *item1 = PyTuple_GetItem(args, 1);
709 [ # # ][ # # ]: 0 : if(PyString_Check(item1) || PyUnicode_Check(item1))
710 : : {
711 : 0 : const char *name = PyString_AsString(item1);
712 : 0 : PyObject *item2 = PyTuple_GetItem(args, 2);
713 [ # # ]: 0 : if(PyTuple_Check(item2))
714 : : {
715 : 0 : ret = PyUNO_invoke(object, name, item2);
716 : : }
717 : : else
718 : : {
719 : 0 : OStringBuffer buf;
720 [ # # ]: 0 : buf.append("uno.invoke expects a tuple as 3rd argument, got ");
721 [ # # ][ # # ]: 0 : buf.append(PyString_AsString(PyObject_Str(item2)));
[ # # ]
722 : : PyErr_SetString(
723 [ # # ]: 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr());
724 : 0 : }
725 : : }
726 : : else
727 : : {
728 : 0 : OStringBuffer buf;
729 [ # # ]: 0 : buf.append("uno.invoke expected a string as 2nd argument, got ");
730 [ # # ][ # # ]: 0 : buf.append(PyString_AsString(PyObject_Str(item1)));
[ # # ]
731 : : PyErr_SetString(
732 [ # # ]: 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr());
733 : : }
734 : : }
735 : : else
736 : : {
737 : 0 : OStringBuffer buf;
738 [ # # ]: 0 : buf.append("uno.invoke expects object, name, (arg1, arg2, ... )\n");
739 [ # # ]: 0 : PyErr_SetString(PyExc_RuntimeError, buf.makeStringAndClear().getStr());
740 : : }
741 : 0 : return ret;
742 : : }
743 : :
744 : 0 : static PyObject *getCurrentContext(
745 : : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * )
746 : : {
747 : 0 : PyRef ret;
748 : : try
749 : : {
750 [ # # ]: 0 : Runtime runtime;
751 : : ret = runtime.any2PyObject(
752 [ # # ][ # # ]: 0 : makeAny( com::sun::star::uno::getCurrentContext() ) );
[ # # ][ # # ]
[ # # ][ # # ]
753 : : }
754 [ # # # # ]: 0 : catch( const com::sun::star::uno::Exception & e )
755 : : {
756 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
757 : : }
758 [ # # ]: 0 : return ret.getAcquired();
759 : : }
760 : :
761 : 0 : static PyObject *setCurrentContext(
762 : : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * args )
763 : : {
764 : 0 : PyRef ret;
765 : : try
766 : : {
767 [ # # ][ # # ]: 0 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
[ # # ][ # # ]
768 : : {
769 : :
770 [ # # ]: 0 : Runtime runtime;
771 [ # # ][ # # ]: 0 : Any a = runtime.pyObject2Any( PyTuple_GetItem( args, 0 ) );
[ # # ]
772 : :
773 : 0 : Reference< com::sun::star::uno::XCurrentContext > context;
774 : :
775 [ # # ][ # # ]: 0 : if( (a.hasValue() && (a >>= context)) || ! a.hasValue() )
[ # # ][ # # ]
[ # # ]
776 : : {
777 [ # # ][ # # ]: 0 : ret = com::sun::star::uno::setCurrentContext( context ) ? Py_True : Py_False;
[ # # ][ # # ]
778 : : }
779 : : else
780 : : {
781 : 0 : OStringBuffer buf;
782 [ # # ]: 0 : buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
783 [ # # ][ # # ]: 0 : buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 0) ) ) );
[ # # ][ # # ]
784 : : PyErr_SetString(
785 [ # # ]: 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr() );
786 [ # # ]: 0 : }
787 : : }
788 : : else
789 : : {
790 : 0 : OStringBuffer buf;
791 [ # # ]: 0 : buf.append( "uno.setCurrentContext expects exactly one argument (the current Context)\n" );
792 : : PyErr_SetString(
793 [ # # ]: 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr() );
794 : : }
795 : : }
796 [ # # # # ]: 0 : catch( const com::sun::star::uno::Exception & e )
797 : : {
798 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
799 : : }
800 [ # # ]: 0 : return ret.getAcquired();
801 : : }
802 : :
803 : : }
804 : :
805 : : struct PyMethodDef PyUNOModule_methods [] =
806 : : {
807 : : {"getComponentContext", getComponentContext, METH_VARARGS, NULL},
808 : : {"_createUnoStructHelper", reinterpret_cast<PyCFunction>(createUnoStructHelper), METH_VARARGS | METH_KEYWORDS, NULL},
809 : : {"getTypeByName", getTypeByName, METH_VARARGS, NULL},
810 : : {"getConstantByName", getConstantByName, METH_VARARGS, NULL},
811 : : {"getClass", getClass, METH_VARARGS, NULL},
812 : : {"checkEnum", checkEnum, METH_VARARGS, NULL},
813 : : {"checkType", checkType, METH_VARARGS, NULL},
814 : : {"generateUuid", generateUuid, METH_VARARGS, NULL},
815 : : {"systemPathToFileUrl", systemPathToFileUrl, METH_VARARGS, NULL},
816 : : {"fileUrlToSystemPath", fileUrlToSystemPath, METH_VARARGS, NULL},
817 : : {"absolutize", absolutize, METH_VARARGS | METH_KEYWORDS, NULL},
818 : : {"isInterface", isInterface, METH_VARARGS, NULL},
819 : : {"invoke", invoke, METH_VARARGS | METH_KEYWORDS, NULL},
820 : : {"setCurrentContext", setCurrentContext, METH_VARARGS, NULL},
821 : : {"getCurrentContext", getCurrentContext, METH_VARARGS, NULL},
822 : : {NULL, NULL, 0, NULL}
823 : : };
824 : :
825 : : }
826 : :
827 : : extern "C"
828 : : #if PY_MAJOR_VERSION >= 3
829 : : PyObject* PyInit_pyuno()
830 : : {
831 : : // noop when called already, otherwise needed to allow multiple threads
832 : : PyEval_InitThreads();
833 : : static struct PyModuleDef moduledef =
834 : : {
835 : : PyModuleDef_HEAD_INIT,
836 : : "pyuno", // module name
837 : : 0, // module documentation
838 : : -1, // module keeps state in global variables,
839 : : PyUNOModule_methods, // modules methods
840 : : 0, // m_reload (must be 0)
841 : : 0, // m_traverse
842 : : 0, // m_clear
843 : : 0, // m_free
844 : : };
845 : : return PyModule_Create(&moduledef);
846 : : }
847 : : #else
848 : 112 : void initpyuno()
849 : : {
850 : 112 : PyEval_InitThreads();
851 : 112 : Py_InitModule ("pyuno", PyUNOModule_methods);
852 : 112 : }
853 : : #endif /* PY_MAJOR_VERSION >= 3 */
854 : :
855 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|