Branch data Line data Source code
1 : : /* -*- Mode: C++; 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 <rtl/strbuf.hxx>
23 : : #include <rtl/ustrbuf.hxx>
24 : :
25 : : #include <osl/thread.h>
26 : :
27 : : #include <com/sun/star/lang/XServiceInfo.hpp>
28 : : #include <com/sun/star/lang/XTypeProvider.hpp>
29 : : #include <com/sun/star/beans/XPropertySet.hpp>
30 : : #include <com/sun/star/beans/XMaterialHolder.hpp>
31 : :
32 : : using rtl::OStringBuffer;
33 : : using rtl::OUStringBuffer;
34 : : using rtl::OUStringToOString;
35 : : using rtl::OUString;
36 : : using com::sun::star::uno::Sequence;
37 : : using com::sun::star::uno::Reference;
38 : : using com::sun::star::uno::XInterface;
39 : : using com::sun::star::uno::Any;
40 : : using com::sun::star::uno::makeAny;
41 : : using com::sun::star::uno::UNO_QUERY;
42 : : using com::sun::star::uno::Type;
43 : : using com::sun::star::uno::TypeClass;
44 : : using com::sun::star::uno::RuntimeException;
45 : : using com::sun::star::uno::Exception;
46 : : using com::sun::star::uno::XComponentContext;
47 : : using com::sun::star::lang::XSingleServiceFactory;
48 : : using com::sun::star::lang::XServiceInfo;
49 : : using com::sun::star::lang::XTypeProvider;
50 : : using com::sun::star::script::XTypeConverter;
51 : : using com::sun::star::script::XInvocation2;
52 : : using com::sun::star::beans::XMaterialHolder;
53 : :
54 : : namespace pyuno
55 : : {
56 : :
57 : : PyObject *PyUNO_str( PyObject * self );
58 : :
59 : 17132 : void PyUNO_del (PyObject* self)
60 : : {
61 : 17132 : PyUNO* me = reinterpret_cast< PyUNO* > (self);
62 : : {
63 [ + - ]: 17132 : PyThreadDetach antiguard;
64 [ + - ][ + - ]: 17132 : delete me->members;
[ + - ]
65 : : }
66 : 17132 : PyObject_Del (self);
67 : 17132 : }
68 : :
69 : :
70 : :
71 : 0 : OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef , sal_Int32 mode ) SAL_THROW(())
72 : : {
73 : : OSL_ASSERT( pVal );
74 [ # # ]: 0 : if (pTypeRef->eTypeClass == typelib_TypeClass_VOID)
75 [ # # ]: 0 : return OUString( RTL_CONSTASCII_USTRINGPARAM("void") );
76 : :
77 : 0 : OUStringBuffer buf( 64 );
78 [ # # ]: 0 : buf.append( (sal_Unicode)'(' );
79 [ # # ]: 0 : buf.append( pTypeRef->pTypeName );
80 [ # # ]: 0 : buf.append( (sal_Unicode)')' );
81 : :
82 [ # # # # : 0 : switch (pTypeRef->eTypeClass)
# # # # #
# # # # #
# # # #
# ]
83 : : {
84 : : case typelib_TypeClass_INTERFACE:
85 : : {
86 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
87 [ # # ]: 0 : buf.append( reinterpret_cast< sal_IntPtr >(*(void **)pVal), 16 );
88 [ # # ]: 0 : if( VAL2STR_MODE_DEEP == mode )
89 : : {
90 [ # # ]: 0 : buf.appendAscii( "{" ); Reference< XInterface > r = *( Reference< XInterface > * ) pVal;
91 [ # # ]: 0 : Reference< XServiceInfo > serviceInfo( r, UNO_QUERY);
92 [ # # ]: 0 : Reference< XTypeProvider > typeProvider(r,UNO_QUERY);
93 [ # # ]: 0 : if( serviceInfo.is() )
94 : : {
95 [ # # ]: 0 : buf.appendAscii("implementationName=" );
96 [ # # ][ # # ]: 0 : buf.append(serviceInfo->getImplementationName() );
[ # # ]
97 [ # # ]: 0 : buf.appendAscii(", supportedServices={" );
98 [ # # ][ # # ]: 0 : Sequence< OUString > seq = serviceInfo->getSupportedServiceNames();
99 [ # # ]: 0 : for( int i = 0 ; i < seq.getLength() ; i ++ )
100 : : {
101 [ # # ][ # # ]: 0 : buf.append( seq[i] );
102 [ # # ]: 0 : if( i +1 != seq.getLength() )
103 [ # # ]: 0 : buf.appendAscii( "," );
104 : : }
105 [ # # ][ # # ]: 0 : buf.appendAscii("}");
106 : : }
107 : :
108 [ # # ]: 0 : if( typeProvider.is() )
109 : : {
110 [ # # ]: 0 : buf.appendAscii(", supportedInterfaces={" );
111 [ # # ][ # # ]: 0 : Sequence< Type > seq (typeProvider->getTypes());
112 [ # # ]: 0 : for( int i = 0 ; i < seq.getLength() ; i ++ )
113 : : {
114 [ # # ][ # # ]: 0 : buf.append(seq[i].getTypeName());
115 [ # # ]: 0 : if( i +1 != seq.getLength() )
116 [ # # ]: 0 : buf.appendAscii( "," );
117 : : }
118 [ # # ][ # # ]: 0 : buf.appendAscii("}");
119 : : }
120 [ # # ]: 0 : buf.appendAscii( "}" );
121 : : }
122 : :
123 : 0 : break;
124 : : }
125 : : case typelib_TypeClass_UNION:
126 : : {
127 : 0 : break;
128 : : }
129 : : case typelib_TypeClass_STRUCT:
130 : : case typelib_TypeClass_EXCEPTION:
131 : : {
132 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
133 : 0 : typelib_TypeDescription * pTypeDescr = 0;
134 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
[ # # ][ # # ]
[ # # ]
135 : : OSL_ASSERT( pTypeDescr );
136 : :
137 : 0 : typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
138 : 0 : sal_Int32 nDescr = pCompType->nMembers;
139 : :
140 [ # # ]: 0 : if (pCompType->pBaseTypeDescription)
141 : : {
142 [ # # ][ # # ]: 0 : buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef,mode ) );
143 [ # # ]: 0 : if (nDescr)
144 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
145 : : }
146 : :
147 : 0 : typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
148 : 0 : sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
149 : 0 : rtl_uString ** ppMemberNames = pCompType->ppMemberNames;
150 : :
151 [ # # ]: 0 : for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
152 : : {
153 [ # # ]: 0 : buf.append( ppMemberNames[nPos] );
154 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
155 : 0 : typelib_TypeDescription * pMemberType = 0;
156 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
[ # # ][ # # ]
[ # # ]
157 [ # # ][ # # ]: 0 : buf.append( val2str( (char *)pVal + pMemberOffsets[nPos], pMemberType->pWeakRef, mode ) );
158 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pMemberType );
159 [ # # ]: 0 : if (nPos < (nDescr -1))
160 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
161 : : }
162 : :
163 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pTypeDescr );
164 : :
165 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
166 : : break;
167 : : }
168 : : case typelib_TypeClass_SEQUENCE:
169 : : {
170 : 0 : typelib_TypeDescription * pTypeDescr = 0;
171 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
[ # # ][ # # ]
[ # # ]
172 : :
173 : 0 : uno_Sequence * pSequence = *(uno_Sequence **)pVal;
174 : 0 : typelib_TypeDescription * pElementTypeDescr = 0;
175 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
[ # # ][ # # ]
[ # # ]
176 : :
177 : 0 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
178 : 0 : sal_Int32 nElements = pSequence->nElements;
179 : :
180 [ # # ]: 0 : if (nElements)
181 : : {
182 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
183 : 0 : char * pElements = pSequence->elements;
184 [ # # ]: 0 : for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
185 : : {
186 [ # # ][ # # ]: 0 : buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef, mode ) );
187 [ # # ]: 0 : if (nPos < (nElements -1))
188 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
189 : : }
190 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
191 : : }
192 : : else
193 : : {
194 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
195 : : }
196 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
197 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pTypeDescr );
198 : : break;
199 : : }
200 : : case typelib_TypeClass_ANY:
201 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
202 : : buf.append( val2str( ((uno_Any *)pVal)->pData,
203 : : ((uno_Any *)pVal)->pType ,
204 [ # # ][ # # ]: 0 : mode) );
205 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
206 : 0 : break;
207 : : case typelib_TypeClass_TYPE:
208 [ # # ]: 0 : buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
209 : 0 : break;
210 : : case typelib_TypeClass_STRING:
211 [ # # ]: 0 : buf.append( (sal_Unicode)'\"' );
212 [ # # ]: 0 : buf.append( *(rtl_uString **)pVal );
213 [ # # ]: 0 : buf.append( (sal_Unicode)'\"' );
214 : 0 : break;
215 : : case typelib_TypeClass_ENUM:
216 : : {
217 : 0 : typelib_TypeDescription * pTypeDescr = 0;
218 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
[ # # ][ # # ]
[ # # ]
219 : :
220 : 0 : sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
221 : 0 : sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
222 [ # # ]: 0 : while (nPos--)
223 : : {
224 [ # # ]: 0 : if (pValues[nPos] == *(int *)pVal)
225 : 0 : break;
226 : : }
227 [ # # ]: 0 : if (nPos >= 0)
228 [ # # ]: 0 : buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[nPos] );
229 : : else
230 [ # # ]: 0 : buf.append( (sal_Unicode)'?' );
231 : :
232 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pTypeDescr );
233 : : break;
234 : : }
235 : : case typelib_TypeClass_BOOLEAN:
236 [ # # ]: 0 : if (*(sal_Bool *)pVal)
237 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
238 : : else
239 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
240 : 0 : break;
241 : : case typelib_TypeClass_CHAR:
242 [ # # ]: 0 : buf.append( (sal_Unicode)'\'' );
243 [ # # ]: 0 : buf.append( *(sal_Unicode *)pVal );
244 [ # # ]: 0 : buf.append( (sal_Unicode)'\'' );
245 : 0 : break;
246 : : case typelib_TypeClass_FLOAT:
247 [ # # ]: 0 : buf.append( *(float *)pVal );
248 : 0 : break;
249 : : case typelib_TypeClass_DOUBLE:
250 [ # # ]: 0 : buf.append( *(double *)pVal );
251 : 0 : break;
252 : : case typelib_TypeClass_BYTE:
253 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
254 [ # # ]: 0 : buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
255 : 0 : break;
256 : : case typelib_TypeClass_SHORT:
257 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
258 [ # # ]: 0 : buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
259 : 0 : break;
260 : : case typelib_TypeClass_UNSIGNED_SHORT:
261 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
262 [ # # ]: 0 : buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
263 : 0 : break;
264 : : case typelib_TypeClass_LONG:
265 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
266 [ # # ]: 0 : buf.append( *(sal_Int32 *)pVal, 16 );
267 : 0 : break;
268 : : case typelib_TypeClass_UNSIGNED_LONG:
269 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
270 [ # # ]: 0 : buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 );
271 : 0 : break;
272 : : case typelib_TypeClass_HYPER:
273 : : case typelib_TypeClass_UNSIGNED_HYPER:
274 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
275 : : #if defined(GCC) && defined(SPARC)
276 : : {
277 : : sal_Int64 aVal;
278 : : *(sal_Int32 *)&aVal = *(sal_Int32 *)pVal;
279 : : *((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1);
280 : : buf.append( aVal, 16 );
281 : : }
282 : : #else
283 [ # # ]: 0 : buf.append( *(sal_Int64 *)pVal, 16 );
284 : : #endif
285 : 0 : break;
286 : :
287 : : case typelib_TypeClass_VOID:
288 : : case typelib_TypeClass_ARRAY:
289 : : case typelib_TypeClass_UNKNOWN:
290 : : case typelib_TypeClass_SERVICE:
291 : : case typelib_TypeClass_MODULE:
292 : : default:
293 [ # # ]: 0 : buf.append( (sal_Unicode)'?' );
294 : : }
295 : :
296 [ # # ]: 0 : return buf.makeStringAndClear();
297 : : }
298 : :
299 : :
300 : 0 : PyObject *PyUNO_repr( PyObject * self )
301 : : {
302 : 0 : PyUNO *me = (PyUNO * ) self;
303 : 0 : PyObject * ret = 0;
304 : :
305 [ # # ]: 0 : if( me->members->wrappedObject.getValueType().getTypeClass()
306 : : == com::sun::star::uno::TypeClass_EXCEPTION )
307 : : {
308 [ # # ]: 0 : Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
309 [ # # ]: 0 : if( rHolder.is() )
310 : : {
311 [ # # ][ # # ]: 0 : Any a = rHolder->getMaterial();
312 [ # # ]: 0 : Exception e;
313 [ # # ]: 0 : a >>= e;
314 [ # # ][ # # ]: 0 : ret = ustring2PyUnicode(e.Message ).getAcquired();
[ # # ]
315 : 0 : }
316 : : }
317 : : else
318 : : {
319 : 0 : ret = PyUNO_str( self );
320 : : }
321 : 0 : return ret;
322 : : }
323 : :
324 : 0 : PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args )
325 : : {
326 : 0 : PyRef ret;
327 : : try
328 : : {
329 [ # # ]: 0 : Runtime runtime;
330 : :
331 : 0 : PyRef paras,callable;
332 [ # # ][ # # ]: 0 : if( PyObject_IsInstance( object, getPyUnoClass().get() ) )
[ # # ][ # # ]
333 : : {
334 : 0 : PyUNO* me = (PyUNO*) object;
335 : 0 : OUString attrName = OUString::createFromAscii(name);
336 [ # # ][ # # ]: 0 : if (! me->members->xInvocation->hasMethod (attrName))
[ # # ]
337 : : {
338 : 0 : OUStringBuffer buf;
339 [ # # ]: 0 : buf.appendAscii( "Attribute " );
340 [ # # ]: 0 : buf.append( attrName );
341 [ # # ]: 0 : buf.appendAscii( " unknown" );
342 [ # # ][ # # ]: 0 : throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
343 : : }
344 : : callable = PyUNO_callable_new (
345 : : me->members->xInvocation,
346 : : attrName,
347 : 0 : runtime.getImpl()->cargo->xInvocation,
348 : 0 : runtime.getImpl()->cargo->xTypeConverter,
349 [ # # ][ # # ]: 0 : ACCEPT_UNO_ANY);
[ # # ]
350 [ # # ][ # # ]: 0 : paras = args;
351 : : }
352 : : else
353 : : {
354 : : // clean the tuple from uno.Any !
355 [ # # ]: 0 : int size = PyTuple_Size( args );
356 : : { // for CC, keeping ref-count of tuple being 1
357 [ # # ][ # # ]: 0 : paras = PyRef(PyTuple_New( size ), SAL_NO_ACQUIRE);
[ # # ]
358 : : }
359 [ # # ]: 0 : for( int i = 0 ; i < size ;i ++ )
360 : : {
361 [ # # ]: 0 : PyObject * element = PyTuple_GetItem( args , i );
362 [ # # ][ # # ]: 0 : if( PyObject_IsInstance( element , getAnyClass( runtime ).get() ) )
[ # # ][ # # ]
363 : : {
364 : : element = PyObject_GetAttrString(
365 [ # # ]: 0 : element, "value" );
366 : : }
367 : : else
368 : : {
369 [ # # ]: 0 : Py_XINCREF( element );
370 : : }
371 [ # # ]: 0 : PyTuple_SetItem( paras.get(), i , element );
372 : : }
373 [ # # ][ # # ]: 0 : callable = PyRef( PyObject_GetAttrString( object , (char*)name ), SAL_NO_ACQUIRE );
[ # # ]
374 [ # # ]: 0 : if( !callable.is() )
375 : 0 : return 0;
376 : : }
377 [ # # ][ # # ]: 0 : ret = PyRef( PyObject_CallObject( callable.get(), paras.get() ), SAL_NO_ACQUIRE );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
378 : : }
379 [ # # ]: 0 : catch (const ::com::sun::star::lang::IllegalArgumentException &e)
380 : : {
381 [ # # # # ]: 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
382 : : }
383 [ # # ]: 0 : catch (const ::com::sun::star::script::CannotConvertException &e)
384 : : {
385 [ # # # # ]: 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
386 : : }
387 [ # # ]: 0 : catch (const ::com::sun::star::uno::RuntimeException &e)
388 : : {
389 [ # # # # ]: 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
390 : : }
391 [ # # # # : 0 : catch (const ::com::sun::star::uno::Exception &e)
# # # ]
392 : : {
393 [ # # # # ]: 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
394 : : }
395 : :
396 [ # # ]: 0 : return ret.getAcquired();
397 : : }
398 : :
399 : 0 : PyObject *PyUNO_str( PyObject * self )
400 : : {
401 : 0 : PyUNO *me = ( PyUNO * ) self;
402 : :
403 : 0 : OStringBuffer buf;
404 : :
405 : :
406 [ # # ]: 0 : if( me->members->wrappedObject.getValueType().getTypeClass()
[ # # # # ]
407 : : == com::sun::star::uno::TypeClass_STRUCT ||
408 : 0 : me->members->wrappedObject.getValueType().getTypeClass()
409 : : == com::sun::star::uno::TypeClass_EXCEPTION)
410 : : {
411 [ # # ]: 0 : Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
412 [ # # ]: 0 : if( rHolder.is() )
413 : : {
414 [ # # ]: 0 : PyThreadDetach antiguard;
415 [ # # ][ # # ]: 0 : Any a = rHolder->getMaterial();
416 [ # # ]: 0 : OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() );
417 [ # # ][ # # ]: 0 : buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
[ # # ]
418 : 0 : }
419 : : }
420 : : else
421 : : {
422 : : // a common UNO object
423 [ # # ]: 0 : PyThreadDetach antiguard;
424 [ # # ]: 0 : buf.append( "pyuno object " );
425 : :
426 : : OUString s = val2str( (void*)me->members->wrappedObject.getValue(),
427 [ # # ]: 0 : me->members->wrappedObject.getValueType().getTypeLibType() );
428 [ # # ][ # # ]: 0 : buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
[ # # ]
429 : : }
430 : :
431 [ # # ]: 0 : return PyString_FromString( buf.getStr());
432 : : }
433 : :
434 : 66282 : PyObject* PyUNO_getattr (PyObject* self, char* name)
435 : : {
436 : : PyUNO* me;
437 : :
438 : : try
439 : : {
440 : :
441 [ + - ]: 66282 : Runtime runtime;
442 : :
443 : 66282 : me = (PyUNO*) self;
444 : : //Handle Python dir () stuff first...
445 [ - + ]: 66282 : if (strcmp (name, "__members__") == 0)
446 : : {
447 : : PyObject* member_list;
448 [ # # ]: 0 : Sequence<OUString> oo_member_list;
449 : :
450 [ # # ][ # # ]: 0 : oo_member_list = me->members->xInvocation->getMemberNames ();
[ # # ][ # # ]
451 [ # # ]: 0 : member_list = PyList_New (oo_member_list.getLength ());
452 [ # # ]: 0 : for (int i = 0; i < oo_member_list.getLength (); i++)
453 : : {
454 : : // setitem steals a reference
455 [ # # ][ # # ]: 0 : PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
[ # # ][ # # ]
456 : : }
457 [ # # ]: 0 : return member_list;
458 : : }
459 : :
460 [ - + ]: 66282 : if (strcmp (name, "__dict__") == 0)
461 : : {
462 : 0 : Py_INCREF (Py_None);
463 : 0 : return Py_None;
464 : : }
465 [ - + ]: 66282 : if (strcmp (name, "__methods__") == 0)
466 : : {
467 : 0 : Py_INCREF (Py_None);
468 : 0 : return Py_None;
469 : : }
470 [ + + ]: 66282 : if (strcmp (name, "__class__") == 0)
471 : : {
472 [ + + + + ]: 21574 : if( me->members->wrappedObject.getValueTypeClass() ==
[ + + ]
473 : : com::sun::star::uno::TypeClass_STRUCT ||
474 : 6124 : me->members->wrappedObject.getValueTypeClass() ==
475 : : com::sun::star::uno::TypeClass_EXCEPTION )
476 : : {
477 : : return getClass(
478 [ + - ][ + - ]: 14930 : me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
479 : : }
480 : 520 : Py_INCREF (Py_None);
481 : 520 : return Py_None;
482 : : }
483 : :
484 : 50832 : OUString attrName( OUString::createFromAscii( name ) );
485 : : //We need to find out if it's a method...
486 [ + - ][ + + ]: 50832 : if (me->members->xInvocation->hasMethod (attrName))
[ + - ]
487 : : {
488 : : //Create a callable object to invoke this...
489 : : PyRef ret = PyUNO_callable_new (
490 : : me->members->xInvocation,
491 : : attrName,
492 : 3474 : runtime.getImpl()->cargo->xInvocation,
493 [ + - ]: 6948 : runtime.getImpl()->cargo->xTypeConverter);
494 [ + - ]: 3474 : Py_XINCREF( ret.get() );
495 [ + - ]: 3474 : return ret.get();
496 : :
497 : : }
498 : :
499 : : //or a property
500 [ + - ][ + - ]: 47358 : if (me->members->xInvocation->hasProperty ( attrName))
[ + - ]
501 : : {
502 : : //Return the value of the property
503 : 47358 : Any anyRet;
504 : : {
505 [ + - ]: 47358 : PyThreadDetach antiguard;
506 [ + - ][ + - ]: 47358 : anyRet = me->members->xInvocation->getValue (attrName);
[ + - ]
507 : : }
508 [ + - ]: 47358 : PyRef ret = runtime.any2PyObject(anyRet);
509 [ + - ]: 47358 : Py_XINCREF( ret.get() );
510 [ + - ]: 47358 : return ret.get();
511 : : }
512 : :
513 : : //or else...
514 [ # # ][ + - ]: 66282 : PyErr_SetString (PyExc_AttributeError, name);
[ + - ][ - + ]
515 : : }
516 : 0 : catch( const com::sun::star::reflection::InvocationTargetException & e )
517 : : {
518 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e.TargetException) );
519 : : }
520 : 0 : catch( const com::sun::star::beans::UnknownPropertyException & e )
521 : : {
522 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
523 : : }
524 : 0 : catch( const com::sun::star::lang::IllegalArgumentException &e )
525 : : {
526 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
527 : : }
528 : 0 : catch( const com::sun::star::script::CannotConvertException &e )
529 : : {
530 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
531 : : }
532 [ # # # # : 0 : catch( const RuntimeException &e )
# # ]
533 : : {
534 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
535 : : }
536 : :
537 : 66282 : return NULL;
538 : : }
539 : :
540 : 51731 : int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
541 : : {
542 : : PyUNO* me;
543 : :
544 : 51731 : me = (PyUNO*) self;
545 : : try
546 : : {
547 [ + - ]: 51731 : Runtime runtime;
548 [ + - ][ + - ]: 51731 : Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
549 : :
550 : 51731 : OUString attrName( OUString::createFromAscii( name ) );
551 : : {
552 [ + - ]: 51731 : PyThreadDetach antiguard;
553 [ + - ][ + - ]: 51731 : if (me->members->xInvocation->hasProperty (attrName))
[ + + ]
554 : : {
555 [ + - ][ + - ]: 48929 : me->members->xInvocation->setValue (attrName, val);
556 : 51731 : return 0; //Keep with Python's boolean system
557 [ + - ][ + + ]: 51731 : }
558 [ + + ][ + + ]: 51731 : }
[ + - ][ + + ]
559 : : }
560 : 0 : catch( const com::sun::star::reflection::InvocationTargetException & e )
561 : : {
562 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e.TargetException) );
563 : 0 : return 1;
564 : : }
565 : 0 : catch( const com::sun::star::beans::UnknownPropertyException & e )
566 : : {
567 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
568 : 0 : return 1;
569 : : }
570 : 0 : catch( const com::sun::star::script::CannotConvertException &e )
571 : : {
572 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny(e) );
573 : 0 : return 1;
574 : : }
575 [ # # # # : 0 : catch( const RuntimeException & e )
# ]
576 : : {
577 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
578 : 0 : return 1;
579 : : }
580 : 2802 : PyErr_SetString (PyExc_AttributeError, name);
581 : 51731 : return 1; //as above.
582 : : }
583 : :
584 : : // ensure object identity and struct equality
585 : 510 : static PyObject* PyUNO_cmp( PyObject *self, PyObject *that, int op )
586 : : {
587 : : PyObject *result;
588 : :
589 [ - + ][ # # ]: 510 : if(op != Py_EQ && op != Py_NE)
590 : : {
591 : 0 : PyErr_SetString(PyExc_TypeError, "only '==' and '!=' comparisions are defined");
592 : 0 : return 0;
593 : : }
594 [ - + ]: 510 : if( self == that )
595 : : {
596 [ # # ]: 0 : result = (op == Py_EQ ? Py_True : Py_False);
597 : 0 : Py_INCREF(result);
598 : 0 : return result;
599 : : }
600 : : try
601 : : {
602 [ + - ]: 510 : Runtime runtime;
603 [ + - ][ + - ]: 510 : if( PyObject_IsInstance( that, getPyUnoClass().get() ) )
[ + - ][ + - ]
604 : : {
605 : :
606 : 510 : PyUNO *me = reinterpret_cast< PyUNO*> ( self );
607 : 510 : PyUNO *other = reinterpret_cast< PyUNO *> (that );
608 : 510 : com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
609 : 510 : com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
610 : :
611 [ + - ]: 510 : if( tcMe == tcOther )
612 : : {
613 [ - + ][ # # ]: 510 : if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
614 : : tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
615 : : {
616 [ + - ]: 510 : Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
617 [ + - ]: 510 : Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
618 [ + - ][ + - ]: 510 : if( xMe->getMaterial() == xOther->getMaterial() )
[ + - ][ + - ]
[ + + ]
619 : : {
620 [ + - ]: 34 : result = (op == Py_EQ ? Py_True : Py_False);
621 : 34 : Py_INCREF(result);
622 : 510 : return result;
623 [ + + ][ + + ]: 510 : }
624 : : }
625 [ # # ]: 0 : else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
626 : : {
627 [ # # ]: 0 : if( me->members->wrappedObject == other->members->wrappedObject )
628 : : {
629 [ # # ]: 0 : result = (op == Py_EQ ? Py_True : Py_False);
630 : 0 : Py_INCREF(result);
631 : 476 : return result;
632 : : }
633 : : }
634 : : }
635 [ + - ][ + + ]: 510 : }
636 : : }
637 [ # # ]: 0 : catch( const com::sun::star::uno::RuntimeException & e)
638 : : {
639 [ # # # # ]: 0 : raisePyExceptionWithAny( makeAny( e ) );
640 : : }
641 : :
642 [ + - ]: 476 : result = (op == Py_EQ ? Py_False : Py_True);
643 : 476 : Py_INCREF(result);
644 : 510 : return result;
645 : : }
646 : :
647 : : /* Python 2 has a tp_flags value for rich comparisons. Python 3 does not (on by default) */
648 : : #ifdef Py_TPFLAGS_HAVE_RICHCOMPARE
649 : : #define TP_FLAGS (Py_TPFLAGS_HAVE_RICHCOMPARE)
650 : : #else
651 : : #define TP_FLAGS 0
652 : : #endif
653 : :
654 : : static PyTypeObject PyUNOType =
655 : : {
656 : : PyVarObject_HEAD_INIT( &PyType_Type, 0 )
657 : : "pyuno",
658 : : sizeof (PyUNO),
659 : : 0,
660 : : (destructor) PyUNO_del,
661 : : (printfunc) 0,
662 : : (getattrfunc) PyUNO_getattr,
663 : : (setattrfunc) PyUNO_setattr,
664 : : /* this type does not exist in Python 3: (cmpfunc) */ 0,
665 : : (reprfunc) PyUNO_repr,
666 : : 0,
667 : : 0,
668 : : 0,
669 : : (hashfunc) 0,
670 : : (ternaryfunc) 0,
671 : : (reprfunc) PyUNO_str,
672 : : (getattrofunc)0,
673 : : (setattrofunc)0,
674 : : NULL,
675 : : TP_FLAGS,
676 : : NULL,
677 : : (traverseproc)0,
678 : : (inquiry)0,
679 : : (richcmpfunc) PyUNO_cmp,
680 : : 0,
681 : : (getiterfunc)0,
682 : : (iternextfunc)0,
683 : : NULL,
684 : : NULL,
685 : : NULL,
686 : : NULL,
687 : : NULL,
688 : : (descrgetfunc)0,
689 : : (descrsetfunc)0,
690 : : 0,
691 : : (initproc)0,
692 : : (allocfunc)0,
693 : : (newfunc)0,
694 : : (freefunc)0,
695 : : (inquiry)0,
696 : : NULL,
697 : : NULL,
698 : : NULL,
699 : : NULL,
700 : : NULL,
701 : : (destructor)0
702 : : #if PY_VERSION_HEX >= 0x02060000
703 : : , 0
704 : : #endif
705 : : };
706 : :
707 : 5625 : PyRef getPyUnoClass()
708 : : {
709 : 5625 : return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
710 : : }
711 : :
712 : 2215 : PyObject* PyUNO_new (
713 : : const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
714 : : {
715 : 2215 : Reference<XInterface> tmp_interface;
716 : :
717 [ + - ]: 2215 : targetInterface >>= tmp_interface;
718 : :
719 [ + + ]: 2215 : if (!tmp_interface.is ())
720 : : {
721 : : // empty reference !
722 : 51 : Py_INCREF( Py_None );
723 : 51 : return Py_None;
724 : : }
725 [ + - ]: 2215 : return PyUNO_new_UNCHECKED (targetInterface, ssf);
726 : : }
727 : :
728 : :
729 : 17344 : PyObject* PyUNO_new_UNCHECKED (
730 : : const Any &targetInterface,
731 : : const Reference<XSingleServiceFactory> &ssf )
732 : : {
733 : : PyUNO* self;
734 [ + - ]: 17344 : Sequence<Any> arguments (1);
735 : 17344 : Reference<XInterface> tmp_interface;
736 : :
737 [ + - ]: 17344 : self = PyObject_New (PyUNO, &PyUNOType);
738 [ - + ]: 17344 : if (self == NULL)
739 : 0 : return NULL; // == error
740 [ + - ][ + - ]: 17344 : self->members = new PyUNOInternals();
741 : :
742 [ + - ][ + - ]: 17344 : arguments[0] <<= targetInterface;
743 : : {
744 [ + - ]: 17344 : PyThreadDetach antiguard;
745 [ + - ][ + - ]: 17344 : tmp_interface = ssf->createInstanceWithArguments (arguments);
[ + - ]
746 : :
747 [ - + ]: 17344 : if (!tmp_interface.is ())
748 : : {
749 : 0 : Py_INCREF( Py_None );
750 : 0 : return Py_None;
751 : : }
752 : :
753 [ + - ]: 17344 : Reference<XInvocation2> tmp_invocation (tmp_interface, UNO_QUERY);
754 [ - + ]: 17344 : if (!tmp_invocation.is()) {
755 : : throw RuntimeException (rtl::OUString::createFromAscii (
756 : : "XInvocation2 not implemented, cannot interact with object"),
757 [ # # ]: 0 : Reference< XInterface > ());
758 : : }
759 : :
760 [ + - ]: 17344 : self->members->xInvocation = tmp_invocation;
761 [ + - ][ + - ]: 17344 : self->members->wrappedObject = targetInterface;
762 : : }
763 [ + - ]: 17344 : return (PyObject*) self;
764 : : }
765 : :
766 : : }
767 : :
768 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|