1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "pyuno_impl.hxx"
25 
26 #include <osl/module.hxx>
27 #include <osl/thread.h>
28 #include <osl/file.hxx>
29 
30 #include <typelib/typedescription.hxx>
31 
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::OUStringToOString;
49 using rtl::OUStringBuffer;
50 using rtl::OStringBuffer;
51 
52 using com::sun::star::uno::Sequence;
53 using com::sun::star::uno::Reference;
54 using com::sun::star::uno::XInterface;
55 using com::sun::star::uno::Any;
56 using com::sun::star::uno::makeAny;
57 using com::sun::star::uno::UNO_QUERY;
58 using com::sun::star::uno::RuntimeException;
59 using com::sun::star::uno::TypeDescription;
60 using com::sun::star::uno::XComponentContext;
61 using com::sun::star::container::NoSuchElementException;
62 using com::sun::star::reflection::XIdlReflection;
63 using com::sun::star::reflection::XIdlClass;
64 using com::sun::star::script::XInvocation2;
65 
66 using namespace pyuno;
67 
68 namespace {
69 
70 /**
71    @ index of the next to be used member in the initializer list !
72  */
fillStructWithInitializer(const Reference<XInvocation2> & inv,typelib_CompoundTypeDescription * pCompType,PyObject * initializer,const Runtime & runtime)73 sal_Int32 fillStructWithInitializer(
74     const Reference< XInvocation2 > &inv,
75     typelib_CompoundTypeDescription *pCompType,
76     PyObject *initializer,
77     const Runtime &runtime) throw ( RuntimeException )
78 {
79     sal_Int32 nIndex = 0;
80     if( pCompType->pBaseTypeDescription )
81         nIndex = fillStructWithInitializer(
82             inv, pCompType->pBaseTypeDescription, initializer, runtime );
83 
84     sal_Int32 nTupleSize =  PyTuple_Size(initializer);
85     int i;
86     for( i = 0 ; i < pCompType->nMembers ; i ++ )
87     {
88         if( i + nIndex >= nTupleSize )
89         {
90             OUStringBuffer buf;
91             buf.appendAscii( "pyuno._createUnoStructHelper: too few elements in the initializer tuple,");
92             buf.appendAscii( "expected at least " ).append( nIndex + pCompType->nMembers );
93             buf.appendAscii( ", got " ).append( nTupleSize );
94             throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
95         }
96         PyObject *element = PyTuple_GetItem( initializer, i + nIndex );
97         Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
98         inv->setValue( pCompType->ppMemberNames[i], a );
99     }
100     return i+nIndex;
101 }
102 
getLibDir()103 OUString getLibDir()
104 {
105     static OUString *pLibDir;
106     if( !pLibDir )
107     {
108         osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
109         if( ! pLibDir )
110         {
111             static OUString libDir;
112 
113             // workarounds the $(ORIGIN) until it is available
114             if( Module::getUrlFromAddress(
115                     reinterpret_cast< oslGenericFunction >(getLibDir), libDir ) )
116             {
117                 libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
118                 OUString name ( RTL_CONSTASCII_USTRINGPARAM( "PYUNOLIBDIR" ) );
119                 rtl_bootstrap_set( name.pData, libDir.pData );
120             }
121             pLibDir = &libDir;
122         }
123     }
124     return *pLibDir;
125 }
126 
raisePySystemException(const char * exceptionType,const OUString & message)127 void raisePySystemException( const char * exceptionType, const OUString & message )
128 {
129     OStringBuffer buf;
130     buf.append( "Error during bootstrapping uno (");
131     buf.append( exceptionType );
132     buf.append( "):" );
133     buf.append( OUStringToOString( message, osl_getThreadTextEncoding() ) );
134     PyErr_SetString( PyExc_SystemError, buf.makeStringAndClear().getStr() );
135 }
136 
137 extern "C" {
138 
getComponentContext(PyObject *,PyObject *)139 static PyObject* getComponentContext (PyObject*, PyObject*)
140 {
141     PyRef ret;
142     try
143     {
144         Reference<XComponentContext> ctx;
145 
146         // getLibDir() must be called in order to set bootstrap variables correctly !
147         OUString path( getLibDir());
148         if( Runtime::isInitialized() )
149         {
150             Runtime runtime;
151             ctx = runtime.getImpl()->cargo->xContext;
152         }
153         else
154         {
155             OUString iniFile;
156             if( !path.getLength() )
157             {
158                 PyErr_SetString(
159                     PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini "
160                     "file for bootstrapping python uno bridge\n" );
161                 return NULL;
162             }
163 
164             OUStringBuffer iniFileName;
165             iniFileName.append( path );
166             iniFileName.appendAscii( "/" );
167             iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) );
168             iniFile = iniFileName.makeStringAndClear();
169             osl::DirectoryItem item;
170             if( osl::DirectoryItem::get( iniFile, item ) == item.E_None )
171             {
172                 // in case pyuno.ini exists, use this file for bootstrapping
173                 PyThreadDetach antiguard;
174                 ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile);
175             }
176             else
177             {
178                 // defaulting to the standard bootstrapping
179                 PyThreadDetach antiguard;
180                 ctx = cppu::defaultBootstrap_InitialComponentContext ();
181             }
182 
183         }
184 
185         if( ! Runtime::isInitialized() )
186         {
187             Runtime::initialize( ctx );
188         }
189         Runtime runtime;
190         ret = runtime.any2PyObject( makeAny( ctx ) );
191     }
192     catch (com::sun::star::registry::InvalidRegistryException &e)
193     {
194         // can't use raisePyExceptionWithAny() here, because the function
195         // does any conversions, which will not work with a
196         // wrongly bootstrapped pyuno!
197         raisePySystemException( "InvalidRegistryException", e.Message );
198     }
199     catch( com::sun::star::lang::IllegalArgumentException & e)
200     {
201         raisePySystemException( "IllegalArgumentException", e.Message );
202     }
203     catch( com::sun::star::script::CannotConvertException & e)
204     {
205         raisePySystemException( "CannotConvertException", e.Message );
206     }
207     catch (com::sun::star::uno::RuntimeException & e)
208     {
209         raisePySystemException( "RuntimeException", e.Message );
210     }
211     catch (com::sun::star::uno::Exception & e)
212     {
213         raisePySystemException( "uno::Exception", e.Message );
214     }
215     return ret.getAcquired();
216 }
217 
extractOneStringArg(PyObject * args,char const * funcName)218 PyObject * extractOneStringArg( PyObject *args, char const *funcName )
219 {
220     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
221     {
222         OStringBuffer buf;
223         buf.append( funcName ).append( ": expecting one string argument" );
224         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
225         return NULL;
226     }
227     PyObject *obj = PyTuple_GetItem( args, 0 );
228 #if PY_MAJOR_VERSION >= 3
229     if( ! PyUnicode_Check(obj) )
230 #else
231     if( !PyBytes_Check( obj ) && ! PyUnicode_Check(obj))
232 #endif
233     {
234         OStringBuffer buf;
235         buf.append( funcName ).append( ": expecting one string argument" );
236         PyErr_SetString( PyExc_TypeError, buf.getStr());
237         return NULL;
238     }
239     return obj;
240 }
241 
createUnoStructHelper(PyObject *,PyObject * args)242 static PyObject *createUnoStructHelper(PyObject *, PyObject* args )
243 {
244     Any IdlStruct;
245     PyRef ret;
246 
247     try
248     {
249         Runtime runtime;
250         if( PyTuple_Size( args ) == 2 )
251         {
252             PyObject *structName = PyTuple_GetItem( args,0 );
253             PyObject *initializer = PyTuple_GetItem( args ,1 );
254 
255             if( PYSTR_CHECK( structName ) )
256             {
257                 if( PyTuple_Check( initializer ) )
258                 {
259                     OUString typeName( pyString2ustring( structName ) );
260                     RuntimeCargo *c = runtime.getImpl()->cargo;
261                     Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
262                     if (idl_class.is ())
263                     {
264                         idl_class->createObject (IdlStruct);
265                         PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation );
266                         PyRef returnCandidate( (PyObject*)me, SAL_NO_ACQUIRE );
267                         if( PyTuple_Size( initializer ) > 0 )
268                         {
269                             TypeDescription desc( typeName );
270                             OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 !
271 
272                             typelib_CompoundTypeDescription *pCompType =
273                                 ( typelib_CompoundTypeDescription * ) desc.get();
274                             sal_Int32 n = fillStructWithInitializer(
275                                 me->members->xInvocation, pCompType, initializer, runtime );
276                             if( n != PyTuple_Size(initializer) )
277                             {
278                                 OUStringBuffer buf;
279                                 buf.appendAscii( "pyuno._createUnoStructHelper: wrong number of ");
280                                 buf.appendAscii( "elements in the initializer list, expected " );
281                                 buf.append( n );
282                                 buf.appendAscii( ", got " );
283                                 buf.append( (sal_Int32) PyTuple_Size(initializer) );
284                                 throw RuntimeException(
285                                     buf.makeStringAndClear(), Reference< XInterface > ());
286                             }
287                         }
288                         ret = returnCandidate;
289                     }
290                     else
291                     {
292                         OStringBuffer buf;
293                         buf.append( "UNO struct " );
294                         buf.append( OUStringToOString( typeName, RTL_TEXTENCODING_ASCII_US ) );
295                         buf.append( " is unknown" );
296                         PyErr_SetString (PyExc_RuntimeError, buf.getStr());
297                     }
298                 }
299                 else
300                 {
301                     PyErr_SetString(
302                         PyExc_RuntimeError,
303                         "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
304                 }
305             }
306             else
307             {
308                 PyErr_SetString (PyExc_AttributeError, "createUnoStruct: first argument wasn't a string");
309             }
310         }
311         else
312         {
313             PyErr_SetString (PyExc_AttributeError, "1 Arguments: Structure Name");
314         }
315     }
316     catch( com::sun::star::uno::RuntimeException & e )
317     {
318         raisePyExceptionWithAny( makeAny( e ) );
319     }
320     catch( com::sun::star::script::CannotConvertException & e )
321     {
322         raisePyExceptionWithAny( makeAny( e ) );
323     }
324     catch( com::sun::star::uno::Exception & e )
325     {
326         raisePyExceptionWithAny( makeAny( e ) );
327     }
328     return ret.getAcquired();
329 }
330 
getTypeByName(PyObject *,PyObject * args)331 static PyObject *getTypeByName( PyObject *, PyObject *args )
332 {
333     PyObject * ret = NULL;
334 
335     try
336     {
337         char *name;
338 
339         if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
340         {
341             OUString typeName ( OUString::createFromAscii( name ) );
342             TypeDescription typeDesc( typeName );
343             if( typeDesc.is() )
344             {
345                 Runtime runtime;
346                 ret = PyUNO_Type_new(
347                     name, (com::sun::star::uno::TypeClass)typeDesc.get()->eTypeClass, runtime );
348             }
349             else
350             {
351                 OStringBuffer buf;
352                 buf.append( "Type " ).append(name).append( " is unknown" );
353                 PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
354             }
355         }
356     }
357     catch ( RuntimeException & e )
358     {
359         raisePyExceptionWithAny( makeAny( e ) );
360     }
361     return ret;
362 }
363 
getConstantByName(PyObject *,PyObject * args)364 static PyObject *getConstantByName( PyObject *, PyObject *args )
365 {
366     PyObject *ret = 0;
367     try
368     {
369         char *name;
370 
371         if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
372         {
373             OUString typeName ( OUString::createFromAscii( name ) );
374             Runtime runtime;
375             Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName);
376             if( a.getValueType().getTypeClass() ==
377                 com::sun::star::uno::TypeClass_INTERFACE )
378             {
379                 // a idl constant cannot be an instance of an uno-object, thus
380                 // this cannot be a constant
381                 OUStringBuffer buf;
382                 buf.appendAscii( "pyuno.getConstantByName: " ).append( typeName );
383                 buf.appendAscii( "is not a constant" );
384                 throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > () );
385             }
386             PyRef constant = runtime.any2PyObject( a );
387             ret = constant.getAcquired();
388         }
389     }
390     catch( NoSuchElementException & e )
391     {
392         // to the python programmer, this is a runtime exception,
393         // do not support tweakings with the type system
394         RuntimeException runExc( e.Message, Reference< XInterface > () );
395         raisePyExceptionWithAny( makeAny( runExc ) );
396     }
397     catch( com::sun::star::script::CannotConvertException & e)
398     {
399         raisePyExceptionWithAny( makeAny( e ) );
400     }
401     catch( com::sun::star::lang::IllegalArgumentException & e)
402     {
403         raisePyExceptionWithAny( makeAny( e ) );
404     }
405     catch( RuntimeException & e )
406     {
407         raisePyExceptionWithAny( makeAny(e) );
408     }
409     return ret;
410 }
411 
checkType(PyObject *,PyObject * args)412 static PyObject *checkType( PyObject *, PyObject *args )
413 {
414     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
415     {
416         OStringBuffer buf;
417         buf.append( "pyuno.checkType : expecting one uno.Type argument" );
418         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
419         return NULL;
420     }
421     PyObject *obj = PyTuple_GetItem( args, 0 );
422 
423     try
424     {
425         PyType2Type( obj );
426     }
427     catch( RuntimeException & e)
428     {
429         raisePyExceptionWithAny( makeAny( e ) );
430         return NULL;
431     }
432     Py_INCREF( Py_None );
433     return Py_None;
434 }
435 
checkEnum(PyObject *,PyObject * args)436 static PyObject *checkEnum( PyObject *, PyObject *args )
437 {
438     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
439     {
440         OStringBuffer buf;
441         buf.append( "pyuno.checkType : expecting one uno.Type argument" );
442         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
443         return NULL;
444     }
445     PyObject *obj = PyTuple_GetItem( args, 0 );
446 
447     try
448     {
449         PyEnum2Enum( obj );
450     }
451     catch( RuntimeException & e)
452     {
453         raisePyExceptionWithAny( makeAny( e) );
454         return NULL;
455     }
456     Py_INCREF( Py_None );
457     return Py_None;
458 }
459 
getClass(PyObject *,PyObject * args)460 static PyObject *getClass( PyObject *, PyObject *args )
461 {
462     PyObject *obj = extractOneStringArg( args, "pyuno.getClass");
463     if( ! obj )
464         return NULL;
465 
466     try
467     {
468         Runtime runtime;
469         PyRef ret = getClass( pyString2ustring(obj), runtime );
470         Py_XINCREF( ret.get() );
471         return ret.get();
472     }
473     catch( RuntimeException & e)
474     {
475         // NOOPT !!!
476         // gcc 3.2.3 crashes here in the regcomp test scenario
477         // only since migration to python 2.3.4 ???? strange thing
478         // optimization switched off for this module !
479         raisePyExceptionWithAny( makeAny(e) );
480     }
481     return NULL;
482 }
483 
isInterface(PyObject *,PyObject * args)484 static PyObject *isInterface( PyObject *, PyObject *args )
485 {
486 
487     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
488     {
489         PyObject *obj = PyTuple_GetItem( args, 0 );
490         Runtime r;
491 #if PY_MAJOR_VERSION >= 3
492         return PyLong_FromLong( isInterfaceClass( r, obj ) );
493 #else
494         return PyInt_FromLong( isInterfaceClass( r, obj ) );
495 
496 #endif
497     }
498 #if PY_MAJOR_VERSION >= 3
499     return PyLong_FromLong( 0 );
500 #else
501     return PyInt_FromLong( 0 );
502 #endif
503 }
504 
generateUuid(PyObject *,PyObject *)505 static PyObject * generateUuid( PyObject *, PyObject * )
506 {
507     Sequence< sal_Int8 > seq( 16 );
508     rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False );
509     PyRef ret;
510     try
511     {
512         Runtime runtime;
513         ret = runtime.any2PyObject( makeAny( seq ) );
514     }
515     catch( RuntimeException & e )
516     {
517         raisePyExceptionWithAny( makeAny(e) );
518     }
519     return ret.getAcquired();
520 }
521 
systemPathToFileUrl(PyObject *,PyObject * args)522 static PyObject *systemPathToFileUrl( PyObject *, PyObject * args )
523 {
524     PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" );
525     if( ! obj )
526         return NULL;
527 
528     OUString sysPath = pyString2ustring( obj );
529     OUString url;
530     osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url );
531 
532     if( e != osl::FileBase::E_None )
533     {
534         OUStringBuffer buf;
535         buf.appendAscii( "Couldn't convert " );
536         buf.append( sysPath );
537         buf.appendAscii( " to a file url for reason (" );
538         buf.append( (sal_Int32) e );
539         buf.appendAscii( ")" );
540         raisePyExceptionWithAny(
541             makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
542         return NULL;
543     }
544     return ustring2PyUnicode( url ).getAcquired();
545 }
546 
fileUrlToSystemPath(PyObject *,PyObject * args)547 static PyObject * fileUrlToSystemPath( PyObject *, PyObject * args )
548 {
549     PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" );
550     if( ! obj )
551         return NULL;
552 
553     OUString url = pyString2ustring( obj );
554     OUString sysPath;
555     osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath );
556 
557     if( e != osl::FileBase::E_None )
558     {
559         OUStringBuffer buf;
560         buf.appendAscii( "Couldn't convert file url " );
561         buf.append( sysPath );
562         buf.appendAscii( " to a system path for reason (" );
563         buf.append( (sal_Int32) e );
564         buf.appendAscii( ")" );
565         raisePyExceptionWithAny(
566             makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
567         return NULL;
568     }
569     return ustring2PyUnicode( sysPath ).getAcquired();
570 }
571 
absolutize(PyObject *,PyObject * args)572 static PyObject * absolutize( PyObject *, PyObject * args )
573 {
574     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 )
575     {
576         OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) );
577         OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) );
578         OUString ret;
579         oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) );
580         if( e != osl_File_E_None )
581         {
582             OUStringBuffer buf;
583             buf.appendAscii( "Couldn't absolutize " );
584             buf.append( ouRel );
585             buf.appendAscii( " using root " );
586             buf.append( ouPath );
587             buf.appendAscii( " for reason (" );
588             buf.append( (sal_Int32) e );
589             buf.appendAscii( ")" );
590 
591             PyErr_SetString(
592                 PyExc_OSError,
593                 OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding()));
594             return 0;
595         }
596         return ustring2PyUnicode( ret ).getAcquired();
597     }
598     return 0;
599 }
600 
invoke(PyObject *,PyObject * args)601 static PyObject * invoke ( PyObject *, PyObject * args )
602 {
603     PyObject *ret = 0;
604     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 3 )
605     {
606         PyObject *object = PyTuple_GetItem( args, 0 );
607 
608         if( PYSTR_CHECK( PyTuple_GetItem( args, 1 ) ) )
609         {
610 #if PY_VERSION_HEX >= 0x03030000
611             const char *name = PyUnicode_AsUTF8( PyTuple_GetItem( args, 1 ) );
612 #elif PY_MAJOR_VERSION >= 3
613             PyRef pUtf8(PyUnicode_AsUTF8String( PyTuple_GetItem( args, 1 ) ), SAL_NO_ACQUIRE);
614             const char *name = PyBytes_AsString( pUtf8.get() );
615 #else
616             const char *name = PyBytes_AsString( PyTuple_GetItem( args, 1 ) );
617 #endif
618             if( PyTuple_Check( PyTuple_GetItem( args , 2 )))
619             {
620                 ret = PyUNO_invoke( object, name , PyTuple_GetItem( args, 2 ) );
621             }
622             else
623             {
624                 OStringBuffer buf;
625                 buf.append( "uno.invoke expects a tuple as 3rd argument, got " );
626 #if PY_MAJOR_VERSION >= 3
627                 buf.append( OUStringToOString( pyString2ustring( PyTuple_GetItem( args, 2 ) ), RTL_TEXTENCODING_ASCII_US) );
628 #else
629                 buf.append( PyBytes_AsString( PyObject_Str( PyTuple_GetItem( args, 2) ) ) );
630 #endif
631                 PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
632             }
633         }
634         else
635         {
636             OStringBuffer buf;
637             buf.append( "uno.invoke expected a string as 2nd argument, got " );
638 #if PY_MAJOR_VERSION >= 3
639             buf.append( OUStringToOString( pyString2ustring( PyTuple_GetItem( args, 1 ) ), RTL_TEXTENCODING_ASCII_US ) );
640 #else
641             buf.append( PyBytes_AsString( PyObject_Str( PyTuple_GetItem( args, 1) ) ) );
642 #endif
643             PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
644         }
645     }
646     else
647     {
648         OStringBuffer buf;
649         buf.append( "uno.invoke expects object, name, (arg1, arg2, ... )\n" );
650         PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
651     }
652     return ret;
653 }
654 
getCurrentContext(PyObject *,PyObject *)655 static PyObject *getCurrentContext( PyObject *, PyObject * )
656 {
657     PyRef ret;
658     try
659     {
660         Runtime runtime;
661         ret = runtime.any2PyObject(
662             makeAny( com::sun::star::uno::getCurrentContext() ) );
663     }
664     catch( com::sun::star::uno::Exception & e )
665     {
666         raisePyExceptionWithAny( makeAny( e ) );
667     }
668     return ret.getAcquired();
669 }
670 
setCurrentContext(PyObject *,PyObject * args)671 static PyObject *setCurrentContext( PyObject *, PyObject * args )
672 {
673     PyRef ret;
674     try
675     {
676         if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
677         {
678 
679             Runtime runtime;
680             Any a = runtime.pyObject2Any( PyTuple_GetItem( args, 0 ) );
681 
682             Reference< com::sun::star::uno::XCurrentContext > context;
683 
684             if( (a.hasValue() && (a >>= context)) || ! a.hasValue() )
685             {
686                 ret = com::sun::star::uno::setCurrentContext( context ) ? Py_True : Py_False;
687             }
688             else
689             {
690                 OStringBuffer buf;
691                 buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
692 #if PY_MAJOR_VERSION >= 3
693                 buf.append( OUStringToOString( pyString2ustring( PyTuple_GetItem( args, 0 ) ), RTL_TEXTENCODING_ASCII_US ) );
694 #else
695                 buf.append( PyBytes_AsString( PyObject_Str( PyTuple_GetItem( args, 0) ) ) );
696 #endif
697                 PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
698             }
699         }
700         else
701         {
702             OStringBuffer buf;
703             buf.append( "uno.setCurrentContext expects exactly one argument (the current Context)\n" );
704             PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
705         }
706     }
707     catch( com::sun::star::uno::Exception & e )
708     {
709         raisePyExceptionWithAny( makeAny( e ) );
710     }
711     return ret.getAcquired();
712 }
713 
714 }
715 
716 struct PyMethodDef PyUNOModule_methods [] =
717 {
718     {const_cast< char * >("getComponentContext"), getComponentContext, METH_NOARGS, NULL},
719     {const_cast< char * >("_createUnoStructHelper"), createUnoStructHelper, METH_VARARGS, NULL},
720     {const_cast< char * >("getTypeByName"), getTypeByName, METH_VARARGS, NULL},
721     {const_cast< char * >("getConstantByName"), getConstantByName, METH_VARARGS, NULL},
722     {const_cast< char * >("getClass"), getClass, METH_VARARGS, NULL},
723     {const_cast< char * >("checkEnum"), checkEnum, METH_VARARGS, NULL},
724     {const_cast< char * >("checkType"), checkType, METH_VARARGS, NULL},
725     {const_cast< char * >("generateUuid"), generateUuid, METH_NOARGS, NULL},
726     {const_cast< char * >("systemPathToFileUrl"), systemPathToFileUrl, METH_VARARGS, NULL},
727     {const_cast< char * >("fileUrlToSystemPath"), fileUrlToSystemPath, METH_VARARGS, NULL},
728     {const_cast< char * >("absolutize"), absolutize, METH_VARARGS, NULL},
729     {const_cast< char * >("isInterface"), isInterface, METH_VARARGS, NULL},
730     {const_cast< char * >("invoke"), invoke, METH_VARARGS, NULL},
731     {const_cast< char * >("setCurrentContext"), setCurrentContext, METH_VARARGS, NULL},
732     {const_cast< char * >("getCurrentContext"), getCurrentContext, METH_NOARGS, NULL},
733     {NULL, NULL, 0, NULL}
734 };
735 
736 #if PY_MAJOR_VERSION >= 3
737 static struct PyModuleDef PyUNOModule =
738 {
739     PyModuleDef_HEAD_INIT,
740     const_cast< char * >("pyuno"),
741     NULL,
742     -1,
743     PyUNOModule_methods
744 };
745 #endif
746 }
747 
748 #if PY_MAJOR_VERSION >= 3
PyInit_pyuno()749 PY_DLLEXPORT PyMODINIT_FUNC PyInit_pyuno()
750 {
751     PyObject *m;
752 
753     PyEval_InitThreads();
754 
755     m = PyModule_Create(&PyUNOModule);
756     if (m == NULL)
757         return NULL;
758 
759     if (PyType_Ready((PyTypeObject *)getPyUnoClass().get()))
760         return NULL;
761     return m;
762 }
763 #else
initpyuno()764 extern "C" PY_DLLEXPORT void initpyuno()
765 {
766     // noop when called already, otherwise needed to allow multiple threads
767     // This has to be reworked for Python 3.
768     PyEval_InitThreads();
769     Py_InitModule (const_cast< char * >("pyuno"), PyUNOModule_methods);
770 }
771 #endif
772