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