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 0 : fillStructState()
97 0 : : used (PyDict_New())
98 : , initialised ()
99 : , nPosConsumed (0)
100 0 : , nMembersSet (0)
101 : {
102 0 : if ( ! used )
103 0 : throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("pyuno._createUnoStructHelper failed to create new dictionary")), Reference< XInterface > ());
104 0 : }
105 0 : ~fillStructState()
106 0 : {
107 0 : Py_DECREF(used);
108 0 : }
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 0 : void setInitialised(OUString key, sal_Int32 pos = -1)
118 : {
119 0 : 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 0 : initialised[key] = true;
134 0 : ++nMembersSet;
135 0 : if ( pos >= 0 )
136 0 : ++nPosConsumed;
137 0 : }
138 0 : bool isInitialised(OUString key)
139 : {
140 0 : return initialised[key];
141 : }
142 0 : PyObject *getUsed() const
143 : {
144 0 : return used;
145 : }
146 0 : sal_Int32 getCntConsumed() const
147 : {
148 0 : return nPosConsumed;
149 : }
150 : int getCntMembersSet() const
151 : {
152 : return nMembersSet;
153 : }
154 : };
155 :
156 0 : 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 0 : if( pCompType->pBaseTypeDescription )
165 0 : fillStruct( inv, pCompType->pBaseTypeDescription, initializer, kwinitializer, state, runtime );
166 :
167 0 : const sal_Int32 nMembers = pCompType->nMembers;
168 : {
169 0 : for( int i = 0 ; i < nMembers ; i ++ )
170 : {
171 0 : const OUString OUMemberName (pCompType->ppMemberNames[i]);
172 : PyObject *pyMemberName =
173 : PyStr_FromString(::rtl::OUStringToOString(OUMemberName,
174 0 : RTL_TEXTENCODING_UTF8).getStr());
175 0 : if ( PyObject *element = PyDict_GetItem(kwinitializer, pyMemberName ) )
176 : {
177 0 : state.setInitialised(OUMemberName);
178 0 : state.setUsed(pyMemberName);
179 0 : Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
180 0 : inv->setValue( OUMemberName, a );
181 : }
182 0 : }
183 : }
184 : {
185 0 : const int remainingPosInitialisers = PyTuple_Size(initializer) - state.getCntConsumed();
186 0 : for( int i = 0 ; i < remainingPosInitialisers && i < nMembers ; i ++ )
187 : {
188 0 : const int tupleIndex = state.getCntConsumed();
189 0 : const OUString pMemberName (pCompType->ppMemberNames[i]);
190 0 : state.setInitialised(pMemberName, tupleIndex);
191 0 : PyObject *element = PyTuple_GetItem( initializer, tupleIndex );
192 0 : Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
193 0 : inv->setValue( pMemberName, a );
194 0 : }
195 : }
196 0 : for ( int i = 0; i < nMembers ; ++i)
197 : {
198 0 : const OUString memberName (pCompType->ppMemberNames[i]);
199 0 : if ( ! state.isInitialised( memberName ) )
200 : {
201 0 : OUStringBuffer buf;
202 0 : buf.appendAscii( "pyuno._createUnoStructHelper: member '");
203 0 : buf.append(memberName);
204 0 : buf.appendAscii( "' of struct type '");
205 0 : buf.append(pCompType->aBase.pTypeName);
206 0 : buf.appendAscii( "' not given a value.");
207 0 : throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
208 : }
209 0 : }
210 0 : }
211 :
212 0 : OUString getLibDir()
213 : {
214 : static OUString *pLibDir;
215 0 : if( !pLibDir )
216 : {
217 0 : osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
218 0 : if( ! pLibDir )
219 : {
220 0 : static OUString libDir;
221 :
222 : // workarounds the $(ORIGIN) until it is available
223 0 : if( Module::getUrlFromAddress(
224 0 : reinterpret_cast< oslGenericFunction >(getLibDir), libDir ) )
225 : {
226 0 : libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
227 0 : OUString name ( RTL_CONSTASCII_USTRINGPARAM( "PYUNOLIBDIR" ) );
228 0 : rtl_bootstrap_set( name.pData, libDir.pData );
229 : }
230 0 : pLibDir = &libDir;
231 0 : }
232 : }
233 0 : return *pLibDir;
234 : }
235 :
236 0 : void raisePySystemException( const char * exceptionType, const OUString & message )
237 : {
238 0 : OStringBuffer buf;
239 0 : buf.append( "Error during bootstrapping uno (");
240 0 : buf.append( exceptionType );
241 0 : buf.append( "):" );
242 0 : buf.append( OUStringToOString( message, osl_getThreadTextEncoding() ) );
243 0 : PyErr_SetString( PyExc_SystemError, buf.makeStringAndClear().getStr() );
244 0 : }
245 :
246 : extern "C" {
247 :
248 0 : static PyObject* getComponentContext(
249 : SAL_UNUSED_PARAMETER PyObject*, SAL_UNUSED_PARAMETER PyObject*)
250 : {
251 0 : PyRef ret;
252 : try
253 : {
254 0 : Reference<XComponentContext> ctx;
255 :
256 : // getLibDir() must be called in order to set bootstrap variables correctly !
257 0 : OUString path( getLibDir());
258 0 : if( Runtime::isInitialized() )
259 : {
260 0 : Runtime runtime;
261 0 : ctx = runtime.getImpl()->cargo->xContext;
262 : }
263 : else
264 : {
265 0 : OUString iniFile;
266 0 : if( path.isEmpty() )
267 : {
268 : PyErr_SetString(
269 : PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini "
270 0 : "file for bootstrapping python uno bridge\n" );
271 0 : return NULL;
272 : }
273 :
274 0 : OUStringBuffer iniFileName;
275 0 : iniFileName.append( path );
276 0 : iniFileName.appendAscii( "/" );
277 0 : iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) );
278 0 : iniFile = iniFileName.makeStringAndClear();
279 0 : osl::DirectoryItem item;
280 0 : if( osl::DirectoryItem::get( iniFile, item ) == item.E_None )
281 : {
282 : // in case pyuno.ini exists, use this file for bootstrapping
283 0 : PyThreadDetach antiguard;
284 0 : ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile);
285 : }
286 : else
287 : {
288 : // defaulting to the standard bootstrapping
289 0 : PyThreadDetach antiguard;
290 0 : ctx = cppu::defaultBootstrap_InitialComponentContext ();
291 0 : }
292 :
293 : }
294 :
295 0 : if( ! Runtime::isInitialized() )
296 : {
297 0 : Runtime::initialize( ctx );
298 : }
299 0 : Runtime runtime;
300 0 : ret = runtime.any2PyObject( makeAny( ctx ) );
301 : }
302 0 : catch (const com::sun::star::registry::InvalidRegistryException &e)
303 : {
304 : // can't use raisePyExceptionWithAny() here, because the function
305 : // does any conversions, which will not work with a
306 : // wrongly bootstrapped pyuno!
307 0 : raisePySystemException( "InvalidRegistryException", e.Message );
308 : }
309 0 : catch(const com::sun::star::lang::IllegalArgumentException & e)
310 : {
311 0 : raisePySystemException( "IllegalArgumentException", e.Message );
312 : }
313 0 : catch(const com::sun::star::script::CannotConvertException & e)
314 : {
315 0 : raisePySystemException( "CannotConvertException", e.Message );
316 : }
317 0 : catch (const com::sun::star::uno::RuntimeException & e)
318 : {
319 0 : raisePySystemException( "RuntimeException", e.Message );
320 : }
321 0 : catch (const com::sun::star::uno::Exception & e)
322 : {
323 0 : raisePySystemException( "uno::Exception", e.Message );
324 : }
325 0 : return ret.getAcquired();
326 : }
327 :
328 0 : PyObject * extractOneStringArg( PyObject *args, char const *funcName )
329 : {
330 0 : if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
331 : {
332 0 : OStringBuffer buf;
333 0 : buf.append( funcName ).append( ": expecting one string argument" );
334 0 : PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
335 0 : return NULL;
336 : }
337 0 : PyObject *obj = PyTuple_GetItem( args, 0 );
338 0 : if (!PyStr_Check(obj) && !PyUnicode_Check(obj))
339 : {
340 0 : OStringBuffer buf;
341 0 : buf.append( funcName ).append( ": expecting one string argument" );
342 0 : PyErr_SetString( PyExc_TypeError, buf.getStr());
343 0 : return NULL;
344 : }
345 0 : return obj;
346 : }
347 :
348 0 : static PyObject *createUnoStructHelper(
349 : SAL_UNUSED_PARAMETER PyObject *, PyObject* args, PyObject* keywordArgs)
350 : {
351 0 : Any IdlStruct;
352 0 : PyRef ret;
353 : try
354 : {
355 0 : Runtime runtime;
356 0 : if( PyTuple_Size( args ) == 2 )
357 : {
358 0 : PyObject *structName = PyTuple_GetItem(args, 0);
359 0 : PyObject *initializer = PyTuple_GetItem(args, 1);
360 :
361 0 : if (PyStr_Check(structName))
362 : {
363 0 : if( PyTuple_Check( initializer ) && PyDict_Check ( keywordArgs ) )
364 : {
365 0 : OUString typeName( OUString::createFromAscii(PyStr_AsString(structName)));
366 0 : RuntimeCargo *c = runtime.getImpl()->cargo;
367 0 : Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
368 0 : if (idl_class.is ())
369 : {
370 0 : idl_class->createObject (IdlStruct);
371 0 : PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation );
372 0 : PyRef returnCandidate( (PyObject*)me, SAL_NO_ACQUIRE );
373 0 : TypeDescription desc( typeName );
374 : OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 !
375 :
376 : typelib_CompoundTypeDescription *pCompType =
377 0 : ( typelib_CompoundTypeDescription * ) desc.get();
378 0 : fillStructState state;
379 0 : if ( PyTuple_Size( initializer ) > 0 || PyDict_Size( keywordArgs ) > 0 )
380 0 : fillStruct( me->members->xInvocation, pCompType, initializer, keywordArgs, state, runtime );
381 0 : 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 0 : 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( PyStr_AsString(structName) );
398 0 : buf.append( " is unkown" );
399 0 : PyErr_SetString (PyExc_RuntimeError, buf.getStr());
400 0 : }
401 : }
402 : else
403 : {
404 : PyErr_SetString(
405 : PyExc_RuntimeError,
406 0 : "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
407 : }
408 : }
409 : else
410 : {
411 0 : 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 0 : }
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 0 : return ret.getAcquired();
432 : }
433 :
434 0 : static PyObject *getTypeByName(
435 : SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
436 : {
437 0 : PyObject * ret = NULL;
438 :
439 : try
440 : {
441 : char *name;
442 :
443 0 : if (PyArg_ParseTuple (args, "s", &name))
444 : {
445 0 : OUString typeName ( OUString::createFromAscii( name ) );
446 0 : TypeDescription typeDesc( typeName );
447 0 : if( typeDesc.is() )
448 : {
449 0 : Runtime runtime;
450 : ret = PyUNO_Type_new(
451 0 : 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 0 : }
459 : }
460 : }
461 0 : catch ( const RuntimeException & e )
462 : {
463 0 : raisePyExceptionWithAny( makeAny( e ) );
464 : }
465 0 : return ret;
466 : }
467 :
468 0 : static PyObject *getConstantByName(
469 : SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
470 : {
471 0 : PyObject *ret = 0;
472 : try
473 : {
474 : char *name;
475 :
476 0 : if (PyArg_ParseTuple (args, "s", &name))
477 : {
478 0 : OUString typeName ( OUString::createFromAscii( name ) );
479 0 : Runtime runtime;
480 0 : Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName);
481 0 : 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 0 : PyRef constant = runtime.any2PyObject( a );
492 0 : 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 0 : return ret;
515 : }
516 :
517 0 : static PyObject *checkType( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
518 : {
519 0 : 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 0 : PyObject *obj = PyTuple_GetItem( args, 0 );
527 :
528 : try
529 : {
530 0 : PyType2Type( obj );
531 : }
532 0 : catch(const RuntimeException & e)
533 : {
534 0 : raisePyExceptionWithAny( makeAny( e ) );
535 0 : return NULL;
536 : }
537 0 : Py_INCREF( Py_None );
538 0 : return Py_None;
539 : }
540 :
541 0 : static PyObject *checkEnum( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
542 : {
543 0 : 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 0 : PyObject *obj = PyTuple_GetItem( args, 0 );
551 :
552 : try
553 : {
554 0 : PyEnum2Enum( obj );
555 : }
556 0 : catch(const RuntimeException & e)
557 : {
558 0 : raisePyExceptionWithAny( makeAny( e) );
559 0 : return NULL;
560 : }
561 0 : Py_INCREF( Py_None );
562 0 : return Py_None;
563 : }
564 :
565 0 : static PyObject *getClass( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
566 : {
567 0 : PyObject *obj = extractOneStringArg( args, "pyuno.getClass");
568 0 : if( ! obj )
569 0 : return NULL;
570 :
571 : try
572 : {
573 0 : Runtime runtime;
574 0 : PyRef ret = getClass(pyString2ustring(obj), runtime);
575 0 : Py_XINCREF( ret.get() );
576 0 : return ret.get();
577 : }
578 0 : catch(const RuntimeException & e)
579 : {
580 : // NOOPT !!!
581 : // gcc 3.2.3 crashes here in the regcomp test scenario
582 : // only since migration to python 2.3.4 ???? strange thing
583 : // optimization switched off for this module !
584 0 : raisePyExceptionWithAny( makeAny(e) );
585 : }
586 0 : return NULL;
587 : }
588 :
589 0 : static PyObject *isInterface( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
590 : {
591 :
592 0 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
593 : {
594 0 : PyObject *obj = PyTuple_GetItem( args, 0 );
595 0 : Runtime r;
596 0 : return PyLong_FromLong( isInterfaceClass( r, obj ) );
597 : }
598 0 : return PyLong_FromLong( 0 );
599 : }
600 :
601 0 : static PyObject * generateUuid(
602 : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * )
603 : {
604 0 : Sequence< sal_Int8 > seq( 16 );
605 0 : rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False );
606 0 : PyRef ret;
607 : try
608 : {
609 0 : Runtime runtime;
610 0 : ret = runtime.any2PyObject( makeAny( seq ) );
611 : }
612 0 : catch( const RuntimeException & e )
613 : {
614 0 : raisePyExceptionWithAny( makeAny(e) );
615 : }
616 0 : return ret.getAcquired();
617 : }
618 :
619 0 : static PyObject *systemPathToFileUrl(
620 : SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
621 : {
622 0 : PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" );
623 0 : if( ! obj )
624 0 : return NULL;
625 :
626 0 : OUString sysPath = pyString2ustring( obj );
627 0 : OUString url;
628 0 : osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url );
629 :
630 0 : if( e != osl::FileBase::E_None )
631 : {
632 0 : OUStringBuffer buf;
633 0 : buf.appendAscii( "Couldn't convert " );
634 0 : buf.append( sysPath );
635 0 : buf.appendAscii( " to a file url for reason (" );
636 0 : buf.append( (sal_Int32) e );
637 0 : buf.appendAscii( ")" );
638 : raisePyExceptionWithAny(
639 0 : makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
640 0 : return NULL;
641 : }
642 0 : return ustring2PyUnicode( url ).getAcquired();
643 : }
644 :
645 0 : static PyObject * fileUrlToSystemPath(
646 : SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
647 : {
648 0 : PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" );
649 0 : if( ! obj )
650 0 : return NULL;
651 :
652 0 : OUString url = pyString2ustring( obj );
653 0 : OUString sysPath;
654 0 : osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath );
655 :
656 0 : if( e != osl::FileBase::E_None )
657 : {
658 0 : OUStringBuffer buf;
659 0 : buf.appendAscii( "Couldn't convert file url " );
660 0 : buf.append( sysPath );
661 0 : buf.appendAscii( " to a system path for reason (" );
662 0 : buf.append( (sal_Int32) e );
663 0 : buf.appendAscii( ")" );
664 : raisePyExceptionWithAny(
665 0 : makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
666 0 : return NULL;
667 : }
668 0 : return ustring2PyUnicode( sysPath ).getAcquired();
669 : }
670 :
671 0 : static PyObject * absolutize( SAL_UNUSED_PARAMETER PyObject *, PyObject * args )
672 : {
673 0 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 )
674 : {
675 0 : OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) );
676 0 : OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) );
677 0 : OUString ret;
678 0 : oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) );
679 0 : if( e != osl_File_E_None )
680 : {
681 0 : OUStringBuffer buf;
682 0 : buf.appendAscii( "Couldn't absolutize " );
683 0 : buf.append( ouRel );
684 0 : buf.appendAscii( " using root " );
685 0 : buf.append( ouPath );
686 0 : buf.appendAscii( " for reason (" );
687 0 : buf.append( (sal_Int32) e );
688 0 : buf.appendAscii( ")" );
689 :
690 : PyErr_SetString(
691 : PyExc_OSError,
692 0 : OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding()).getStr());
693 0 : return 0;
694 : }
695 0 : return ustring2PyUnicode( ret ).getAcquired();
696 : }
697 0 : return 0;
698 : }
699 :
700 0 : static PyObject * invoke(SAL_UNUSED_PARAMETER PyObject *, PyObject *args)
701 : {
702 0 : PyObject *ret = 0;
703 0 : if(PyTuple_Check(args) && PyTuple_Size(args) == 3)
704 : {
705 0 : PyObject *object = PyTuple_GetItem(args, 0);
706 0 : PyObject *item1 = PyTuple_GetItem(args, 1);
707 0 : if (PyStr_Check(item1))
708 : {
709 0 : const char *name = PyStr_AsString(item1);
710 0 : PyObject *item2 = PyTuple_GetItem(args, 2);
711 0 : if(PyTuple_Check(item2))
712 : {
713 0 : ret = PyUNO_invoke(object, name, item2);
714 : }
715 : else
716 : {
717 0 : OStringBuffer buf;
718 0 : buf.append("uno.invoke expects a tuple as 3rd argument, got ");
719 0 : buf.append(PyStr_AsString(PyObject_Str(item2)));
720 : PyErr_SetString(
721 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr());
722 : }
723 : }
724 : else
725 : {
726 0 : OStringBuffer buf;
727 0 : buf.append("uno.invoke expected a string as 2nd argument, got ");
728 0 : buf.append(PyStr_AsString(PyObject_Str(item1)));
729 : PyErr_SetString(
730 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr());
731 : }
732 : }
733 : else
734 : {
735 0 : OStringBuffer buf;
736 0 : buf.append("uno.invoke expects object, name, (arg1, arg2, ... )\n");
737 0 : PyErr_SetString(PyExc_RuntimeError, buf.makeStringAndClear().getStr());
738 : }
739 0 : return ret;
740 : }
741 :
742 0 : static PyObject *getCurrentContext(
743 : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * )
744 : {
745 0 : PyRef ret;
746 : try
747 : {
748 0 : Runtime runtime;
749 : ret = runtime.any2PyObject(
750 0 : makeAny( com::sun::star::uno::getCurrentContext() ) );
751 : }
752 0 : catch( const com::sun::star::uno::Exception & e )
753 : {
754 0 : raisePyExceptionWithAny( makeAny( e ) );
755 : }
756 0 : return ret.getAcquired();
757 : }
758 :
759 0 : static PyObject *setCurrentContext(
760 : SAL_UNUSED_PARAMETER PyObject *, SAL_UNUSED_PARAMETER PyObject * args )
761 : {
762 0 : PyRef ret;
763 : try
764 : {
765 0 : if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
766 : {
767 :
768 0 : Runtime runtime;
769 0 : Any a = runtime.pyObject2Any( PyTuple_GetItem( args, 0 ) );
770 :
771 0 : Reference< com::sun::star::uno::XCurrentContext > context;
772 :
773 0 : if( (a.hasValue() && (a >>= context)) || ! a.hasValue() )
774 : {
775 0 : ret = com::sun::star::uno::setCurrentContext( context ) ? Py_True : Py_False;
776 : }
777 : else
778 : {
779 0 : OStringBuffer buf;
780 0 : buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
781 : buf.append(
782 0 : PyStr_AsString(PyObject_Str(PyTuple_GetItem(args, 0))));
783 : PyErr_SetString(
784 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr() );
785 0 : }
786 : }
787 : else
788 : {
789 0 : OStringBuffer buf;
790 0 : buf.append( "uno.setCurrentContext expects exactly one argument (the current Context)\n" );
791 : PyErr_SetString(
792 0 : PyExc_RuntimeError, buf.makeStringAndClear().getStr() );
793 : }
794 : }
795 0 : catch( const com::sun::star::uno::Exception & e )
796 : {
797 0 : raisePyExceptionWithAny( makeAny( e ) );
798 : }
799 0 : return ret.getAcquired();
800 : }
801 :
802 : }
803 :
804 : struct PyMethodDef PyUNOModule_methods [] =
805 : {
806 : {"getComponentContext", getComponentContext, METH_VARARGS, NULL},
807 : {"_createUnoStructHelper", reinterpret_cast<PyCFunction>(createUnoStructHelper), METH_VARARGS | METH_KEYWORDS, NULL},
808 : {"getTypeByName", getTypeByName, METH_VARARGS, NULL},
809 : {"getConstantByName", getConstantByName, METH_VARARGS, NULL},
810 : {"getClass", getClass, METH_VARARGS, NULL},
811 : {"checkEnum", checkEnum, METH_VARARGS, NULL},
812 : {"checkType", checkType, METH_VARARGS, NULL},
813 : {"generateUuid", generateUuid, METH_VARARGS, NULL},
814 : {"systemPathToFileUrl", systemPathToFileUrl, METH_VARARGS, NULL},
815 : {"fileUrlToSystemPath", fileUrlToSystemPath, METH_VARARGS, NULL},
816 : {"absolutize", absolutize, METH_VARARGS | METH_KEYWORDS, NULL},
817 : {"isInterface", isInterface, METH_VARARGS, NULL},
818 : {"invoke", invoke, METH_VARARGS | METH_KEYWORDS, NULL},
819 : {"setCurrentContext", setCurrentContext, METH_VARARGS, NULL},
820 : {"getCurrentContext", getCurrentContext, METH_VARARGS, NULL},
821 : {NULL, NULL, 0, NULL}
822 : };
823 :
824 : }
825 :
826 : extern "C"
827 : #if PY_MAJOR_VERSION >= 3
828 0 : PyObject* PyInit_pyuno()
829 : {
830 : // noop when called already, otherwise needed to allow multiple threads
831 0 : PyEval_InitThreads();
832 : static struct PyModuleDef moduledef =
833 : {
834 : PyModuleDef_HEAD_INIT,
835 : "pyuno", // module name
836 : 0, // module documentation
837 : -1, // module keeps state in global variables,
838 : PyUNOModule_methods, // modules methods
839 : 0, // m_reload (must be 0)
840 : 0, // m_traverse
841 : 0, // m_clear
842 : 0, // m_free
843 : };
844 0 : return PyModule_Create(&moduledef);
845 : }
846 : #else
847 : void initpyuno()
848 : {
849 : PyEval_InitThreads();
850 : Py_InitModule ("pyuno", PyUNOModule_methods);
851 : }
852 : #endif /* PY_MAJOR_VERSION >= 3 */
853 :
854 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|