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