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 #include "pyuno_impl.hxx"
24
25 #include <rtl/ustrbuf.hxx>
26 #include <rtl/strbuf.hxx>
27
28 #include <typelib/typedescription.hxx>
29
30 using rtl::OString;
31 using rtl::OUString;
32 using rtl::OUStringBuffer;
33 using rtl::OUStringToOString;
34 using rtl::OStringBuffer;
35
36 using com::sun::star::uno::TypeClass;
37 using com::sun::star::uno::Type;
38 using com::sun::star::uno::RuntimeException;
39 using com::sun::star::uno::Any;
40 using com::sun::star::uno::XInterface;
41 using com::sun::star::uno::Reference;
42 using com::sun::star::uno::TypeDescription;
43
44 #define USTR_ASCII(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
45 namespace pyuno
46 {
typeClassToString(TypeClass t)47 const char *typeClassToString( TypeClass t )
48 {
49 const char * ret = 0;
50 switch (t)
51 {
52 case com::sun::star::uno::TypeClass_VOID:
53 ret = "VOID"; break;
54 case com::sun::star::uno::TypeClass_CHAR:
55 ret = "CHAR"; break;
56 case com::sun::star::uno::TypeClass_BOOLEAN:
57 ret = "BOOLEAN"; break;
58 case com::sun::star::uno::TypeClass_BYTE:
59 ret = "BYTE"; break;
60 case com::sun::star::uno::TypeClass_SHORT:
61 ret = "SHORT"; break;
62 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
63 ret = "UNSIGNED_SHORT"; break;
64 case com::sun::star::uno::TypeClass_LONG:
65 ret = "LONG"; break;
66 case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
67 ret = "UNSIGNED_LONG"; break;
68 case com::sun::star::uno::TypeClass_HYPER:
69 ret = "HYPER"; break;
70 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
71 ret = "UNSIGNED_HYPER"; break;
72 case com::sun::star::uno::TypeClass_FLOAT:
73 ret = "FLOAT"; break;
74 case com::sun::star::uno::TypeClass_DOUBLE:
75 ret = "DOUBLE"; break;
76 case com::sun::star::uno::TypeClass_STRING:
77 ret = "STRING"; break;
78 case com::sun::star::uno::TypeClass_TYPE:
79 ret = "TYPE"; break;
80 case com::sun::star::uno::TypeClass_ANY:
81 ret = "ANY";break;
82 case com::sun::star::uno::TypeClass_ENUM:
83 ret = "ENUM";break;
84 case com::sun::star::uno::TypeClass_STRUCT:
85 ret = "STRUCT"; break;
86 case com::sun::star::uno::TypeClass_EXCEPTION:
87 ret = "EXCEPTION"; break;
88 case com::sun::star::uno::TypeClass_SEQUENCE:
89 ret = "SEQUENCE"; break;
90 case com::sun::star::uno::TypeClass_INTERFACE:
91 ret = "INTERFACE"; break;
92 case com::sun::star::uno::TypeClass_TYPEDEF:
93 ret = "TYPEDEF"; break;
94 case com::sun::star::uno::TypeClass_UNION:
95 ret = "UNION"; break;
96 case com::sun::star::uno::TypeClass_ARRAY:
97 ret = "ARRAY"; break;
98 case com::sun::star::uno::TypeClass_SERVICE:
99 ret = "SERVICE"; break;
100 case com::sun::star::uno::TypeClass_MODULE:
101 ret = "MODULE"; break;
102 case com::sun::star::uno::TypeClass_INTERFACE_METHOD:
103 ret = "INTERFACE_METHOD"; break;
104 case com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE:
105 ret = "INTERFACE_ATTRIBUTE"; break;
106 default:
107 ret = "UNKNOWN"; break;
108 }
109 return ret;
110 }
111
getClass(const Runtime & r,const char * name)112 static PyRef getClass( const Runtime & r , const char * name)
113 {
114 return PyRef( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*) name ) );
115 }
116
getTypeClass(const Runtime & r)117 PyRef getTypeClass( const Runtime & r )
118 {
119 return getClass( r , "Type" );
120 }
121
getEnumClass(const Runtime & r)122 PyRef getEnumClass( const Runtime & r )
123 {
124 return getClass( r , "Enum" );
125 }
126
getCharClass(const Runtime & r)127 PyRef getCharClass( const Runtime & r )
128 {
129 return getClass( r , "Char" );
130 }
131
getByteSequenceClass(const Runtime & r)132 PyRef getByteSequenceClass( const Runtime & r )
133 {
134 return getClass( r , "ByteSequence" );
135 }
136
getAnyClass(const Runtime & r)137 PyRef getAnyClass( const Runtime & r )
138 {
139 return getClass( r , "Any" );
140 }
141
142
PyChar2Unicode(PyObject * obj)143 sal_Unicode PyChar2Unicode( PyObject *obj ) throw ( RuntimeException )
144 {
145 PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE );
146 if( ! PyUnicode_Check( value.get() ) )
147 {
148 throw RuntimeException(
149 USTR_ASCII( "attribute value of uno.Char is not a unicode string" ),
150 Reference< XInterface > () );
151 }
152
153 if( PyUnicode_GetLength( value.get() ) < 1 )
154 {
155 throw RuntimeException(
156 USTR_ASCII( "uno.Char contains an empty unicode string" ),
157 Reference< XInterface > () );
158 }
159 sal_Unicode c = (sal_Unicode)PyUnicode_ReadChar( value.get(), 0 );
160 return c;
161 }
162
PyEnum2Enum(PyObject * obj)163 Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
164 {
165 Any ret;
166 PyRef typeName( PyObject_GetAttrString( obj,const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
167 PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE);
168 if( !PYSTR_CHECK( typeName.get() ) || ! PYSTR_CHECK( value.get() ) )
169 {
170 throw RuntimeException(
171 USTR_ASCII( "attributes typeName and/or value of uno.Enum are not strings" ),
172 Reference< XInterface > () );
173 }
174
175 OUString strTypeName( pyString2ustring( typeName.get() ) );
176 OUString strValue( pyString2ustring( value.get() ) );
177
178 TypeDescription desc( strTypeName );
179 if( desc.is() )
180 {
181 if(desc.get()->eTypeClass != typelib_TypeClass_ENUM )
182 {
183 OUStringBuffer buf;
184 buf.appendAscii( "pyuno.checkEnum: " ).append( strTypeName ).appendAscii( " is a " );
185 buf.appendAscii(
186 typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
187 buf.appendAscii( ", expected ENUM" );
188 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
189 }
190
191 desc.makeComplete();
192
193 typelib_EnumTypeDescription *pEnumDesc = (typelib_EnumTypeDescription*) desc.get();
194 int i = 0;
195 for( i = 0; i < pEnumDesc->nEnumValues ; i ++ )
196 {
197 if( (*((OUString *)&pEnumDesc->ppEnumNames[i])).compareTo( strValue ) == 0 )
198 {
199 break;
200 }
201 }
202 if( i == pEnumDesc->nEnumValues )
203 {
204 OUStringBuffer buf;
205 buf.appendAscii( "value " ).append( strValue ).appendAscii( " is unknown in enum " );
206 buf.append( strTypeName );
207 throw RuntimeException( buf.makeStringAndClear(), Reference<XInterface> () );
208 }
209 ret = Any( &pEnumDesc->pEnumValues[i], desc.get()->pWeakRef );
210 }
211 else
212 {
213 OUStringBuffer buf;
214 buf.appendAscii( "enum " ).append( strTypeName ).appendAscii( " is unknown" );
215 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
216 }
217 return ret;
218 }
219
220
PyType2Type(PyObject * o)221 Type PyType2Type( PyObject * o ) throw(RuntimeException )
222 {
223 PyRef pyName( PyObject_GetAttrString( o, const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
224 if( !PYSTR_CHECK( pyName.get() ) )
225 {
226 throw RuntimeException(
227 USTR_ASCII( "type object does not have typeName property" ),
228 Reference< XInterface > () );
229 }
230
231 PyRef pyTC( PyObject_GetAttrString( o, const_cast< char * >("typeClass") ), SAL_NO_ACQUIRE );
232 Any enumValue = PyEnum2Enum( pyTC.get() );
233
234 OUString name( pyString2ustring( pyName.get() ) );
235 TypeDescription desc( name );
236 if( ! desc.is() )
237 {
238 OUStringBuffer buf;
239 buf.appendAscii( "type " ).append(name).appendAscii( " is unknown" );
240 throw RuntimeException(
241 buf.makeStringAndClear(), Reference< XInterface > () );
242 }
243 if( desc.get()->eTypeClass != (typelib_TypeClass) *(sal_Int32*)enumValue.getValue() )
244 {
245 OUStringBuffer buf;
246 buf.appendAscii( "pyuno.checkType: " ).append(name).appendAscii( " is a " );
247 buf.appendAscii( typeClassToString( (TypeClass) desc.get()->eTypeClass) );
248 buf.appendAscii( ", but type got construct with typeclass " );
249 buf.appendAscii( typeClassToString( (TypeClass) *(sal_Int32*)enumValue.getValue() ) );
250 throw RuntimeException(
251 buf.makeStringAndClear(), Reference< XInterface > () );
252 }
253 return desc.get()->pWeakRef;
254 }
255
importToGlobal(PyObject * str,PyObject * dict,PyObject * target)256 PyObject *importToGlobal(PyObject *str, PyObject *dict, PyObject *target)
257 {
258 // maybe a constant ?
259 PyObject *ret = 0;
260 OUString name = pyString2ustring(str);
261 try
262 {
263 Runtime runtime;
264 TypeDescription desc(name );
265 desc.makeComplete();
266 if( desc.is() )
267 {
268 com::sun::star::uno::TypeClass tc =
269 (com::sun::star::uno::TypeClass)desc.get()->eTypeClass;
270
271 PyRef typesModule( PyDict_GetItemString( dict, "unotypes" ) );
272 if( ! typesModule.is() || ! PyModule_Check( typesModule.get() ))
273 {
274 typesModule = PyRef( PyModule_New( const_cast< char * >("unotypes") ), SAL_NO_ACQUIRE );
275 Py_INCREF( typesModule.get() );
276 PyDict_SetItemString( dict, "unotypes" , typesModule.get() );
277 }
278 const char *targetName = PyUnicode_AsUTF8( target );
279 const char *typeName = PyUnicode_AsUTF8( str );
280 PyModule_AddObject(
281 typesModule.get(),
282 targetName,
283 PyUNO_Type_new( typeName, tc, runtime ) );
284
285 if( com::sun::star::uno::TypeClass_EXCEPTION == tc ||
286 com::sun::star::uno::TypeClass_STRUCT == tc )
287 {
288 PyRef exc = getClass( name, runtime );
289 PyDict_SetItem( dict, target, exc.getAcquired() );
290 }
291 else if( com::sun::star::uno::TypeClass_ENUM == tc )
292 {
293 // introduce all enums into the dictionary !
294 typelib_EnumTypeDescription *pDesc =
295 (typelib_EnumTypeDescription *) desc.get();
296 for( int i = 0 ; i < pDesc->nEnumValues; i ++ )
297 {
298 OString enumElementName(
299 OUStringToOString( pDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US) );
300 const char *name = PyUnicode_AsUTF8(str);
301 PyDict_SetItemString(
302 dict, (char*)enumElementName.getStr(),
303 PyUNO_Enum_new(name, enumElementName.getStr(), runtime ) );
304 }
305 }
306 Py_INCREF( Py_None );
307 ret = Py_None;
308 }
309 else
310 {
311 Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(name);
312 if(a.hasValue())
313 {
314 PyRef constant = runtime.any2PyObject( a );
315 if( constant.is() )
316 {
317 Py_INCREF( constant.get() );
318 PyDict_SetItem( dict, target , constant.get());
319 ret = constant.get();
320 }
321 else
322 {
323 OUStringBuffer buf;
324 buf.appendAscii( "constant " ).append(pyString2ustring(str)).appendAscii( " unknown" );
325 PyErr_SetString(
326 PyExc_RuntimeError,
327 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr() );
328 }
329 }
330 else
331 {
332 OUStringBuffer buf;
333 buf.appendAscii( "pyuno.imp unknown type " );
334 buf.append( name );
335 PyErr_SetString(
336 PyExc_RuntimeError,
337 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
338 }
339 }
340 }
341 catch( com::sun::star::container::NoSuchElementException & )
342 {
343 OUStringBuffer buf;
344 buf.appendAscii( "pyuno.imp unknown type " );
345 buf.append( name );
346 PyErr_SetString(
347 PyExc_RuntimeError,
348 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
349 }
350 catch( com::sun::star::script::CannotConvertException & e )
351 {
352 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
353 }
354 catch( com::sun::star::lang::IllegalArgumentException & e )
355 {
356 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
357 }
358 catch( RuntimeException &e )
359 {
360 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ));
361 }
362 return ret;
363 }
364
callCtor(const Runtime & r,const char * clazz,const PyRef & args)365 static PyObject* callCtor( const Runtime &r , const char * clazz, const PyRef & args )
366 {
367 PyRef code( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*)clazz ) );
368 if( ! code.is() )
369 {
370 OStringBuffer buf;
371 buf.append( "couldn't access uno." );
372 buf.append( clazz );
373 PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
374 return NULL;
375 }
376 PyRef instance( PyObject_CallObject( code.get(), args.get() ), SAL_NO_ACQUIRE);
377 Py_XINCREF( instance.get() );
378 return instance.get();
379
380 }
381
382
PyUNO_Enum_new(const char * enumBase,const char * enumValue,const Runtime & r)383 PyObject *PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r )
384 {
385 PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
386 PyTuple_SetItem( args.get() , 0 , PYSTR_FROMSTR( enumBase ) );
387 PyTuple_SetItem( args.get() , 1 , PYSTR_FROMSTR( enumValue ) );
388
389 return callCtor( r, "Enum" , args );
390 }
391
392
PyUNO_Type_new(const char * typeName,TypeClass t,const Runtime & r)393 PyObject* PyUNO_Type_new (const char *typeName , TypeClass t , const Runtime &r )
394 {
395 // retrieve type object
396 PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
397
398 PyTuple_SetItem( args.get() , 0 , PYSTR_FROMSTR( typeName ) );
399 PyObject *typeClass = PyUNO_Enum_new( "com.sun.star.uno.TypeClass" , typeClassToString(t), r );
400 if( ! typeClass )
401 return NULL;
402 PyTuple_SetItem( args.get() , 1 , typeClass);
403
404 return callCtor( r, "Type" , args );
405 }
406
PyUNO_char_new(sal_Unicode val,const Runtime & r)407 PyObject* PyUNO_char_new ( sal_Unicode val , const Runtime &r )
408 {
409 // retrieve type object
410 PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
411
412 Py_UCS2 u[1];
413 u[0] = val;
414 PyTuple_SetItem( args.get(), 0, PyUnicode_FromKindAndData( PyUnicode_2BYTE_KIND, u, 1 ) );
415
416 return callCtor( r, "Char" , args );
417 }
418
PyUNO_ByteSequence_new(const com::sun::star::uno::Sequence<sal_Int8> & byteSequence,const Runtime & r)419 PyObject *PyUNO_ByteSequence_new(
420 const com::sun::star::uno::Sequence< sal_Int8 > &byteSequence, const Runtime &r )
421 {
422 PyRef str(
423 PyBytes_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()),
424 SAL_NO_ACQUIRE );
425 PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
426 PyTuple_SetItem( args.get() , 0 , str.getAcquired() );
427 return callCtor( r, "ByteSequence" , args );
428
429 }
430 }
431