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