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 99 : void PyUNO_del (PyObject* self)
56 : {
57 99 : PyUNO* me = reinterpret_cast< PyUNO* > (self);
58 : {
59 99 : PyThreadDetach antiguard;
60 99 : delete me->members;
61 : }
62 99 : PyObject_Del (self);
63 99 : }
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( (sal_Unicode)'(' );
75 0 : buf.append( pTypeRef->pTypeName );
76 0 : buf.append( (sal_Unicode)')' );
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_UNION:
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 : OSL_ASSERT( pTypeDescr );
132 :
133 0 : typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
134 0 : sal_Int32 nDescr = pCompType->nMembers;
135 :
136 0 : if (pCompType->pBaseTypeDescription)
137 : {
138 0 : buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->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( (char *)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 = *(uno_Sequence **)pVal;
170 0 : typelib_TypeDescription * pElementTypeDescr = 0;
171 0 : TYPELIB_DANGER_GET( &pElementTypeDescr, ((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( ((uno_Any *)pVal)->pData,
199 : ((uno_Any *)pVal)->pType ,
200 0 : mode) );
201 0 : buf.append( " }" );
202 0 : break;
203 : case typelib_TypeClass_TYPE:
204 0 : buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
205 0 : break;
206 : case typelib_TypeClass_STRING:
207 0 : buf.append( (sal_Unicode)'\"' );
208 0 : buf.append( *(rtl_uString **)pVal );
209 0 : buf.append( (sal_Unicode)'\"' );
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 = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
217 0 : sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
218 0 : while (nPos--)
219 : {
220 0 : if (pValues[nPos] == *(int *)pVal)
221 0 : break;
222 : }
223 0 : if (nPos >= 0)
224 0 : buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[nPos] );
225 : else
226 0 : buf.append( (sal_Unicode)'?' );
227 :
228 0 : TYPELIB_DANGER_RELEASE( pTypeDescr );
229 0 : break;
230 : }
231 : case typelib_TypeClass_BOOLEAN:
232 0 : if (*(sal_Bool *)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( (sal_Unicode)'\'' );
239 0 : buf.append( *(sal_Unicode *)pVal );
240 0 : buf.append( (sal_Unicode)'\'' );
241 0 : break;
242 : case typelib_TypeClass_FLOAT:
243 0 : buf.append( *(float *)pVal );
244 0 : break;
245 : case typelib_TypeClass_DOUBLE:
246 0 : buf.append( *(double *)pVal );
247 0 : break;
248 : case typelib_TypeClass_BYTE:
249 0 : buf.append( "0x" );
250 0 : buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
251 0 : break;
252 : case typelib_TypeClass_SHORT:
253 0 : buf.append( "0x" );
254 0 : buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
255 0 : break;
256 : case typelib_TypeClass_UNSIGNED_SHORT:
257 0 : buf.append( "0x" );
258 0 : buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
259 0 : break;
260 : case typelib_TypeClass_LONG:
261 0 : buf.append( "0x" );
262 0 : buf.append( *(sal_Int32 *)pVal, 16 );
263 0 : break;
264 : case typelib_TypeClass_UNSIGNED_LONG:
265 0 : buf.append( "0x" );
266 0 : buf.append( (sal_Int64)*(sal_uInt32 *)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( *(sal_Int64 *)pVal, 16 );
282 : #endif
283 0 : break;
284 :
285 : case typelib_TypeClass_VOID:
286 : case typelib_TypeClass_ARRAY:
287 : case typelib_TypeClass_UNKNOWN:
288 : case typelib_TypeClass_SERVICE:
289 : case typelib_TypeClass_MODULE:
290 : default:
291 0 : buf.append( (sal_Unicode)'?' );
292 : }
293 :
294 0 : return buf.makeStringAndClear();
295 : }
296 :
297 :
298 1 : PyObject *PyUNO_repr( PyObject * self )
299 : {
300 1 : PyUNO *me = (PyUNO * ) self;
301 1 : PyObject * ret = 0;
302 :
303 1 : if( me->members->wrappedObject.getValueType().getTypeClass()
304 : == com::sun::star::uno::TypeClass_EXCEPTION )
305 : {
306 1 : Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
307 1 : if( rHolder.is() )
308 : {
309 1 : Any a = rHolder->getMaterial();
310 2 : Exception e;
311 1 : a >>= e;
312 2 : ret = ustring2PyUnicode(e.Message ).getAcquired();
313 1 : }
314 : }
315 : else
316 : {
317 0 : ret = PyUNO_str( self );
318 : }
319 1 : return ret;
320 : }
321 :
322 0 : PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args )
323 : {
324 0 : PyRef ret;
325 : try
326 : {
327 0 : Runtime runtime;
328 :
329 0 : PyRef paras,callable;
330 0 : if( PyObject_IsInstance( object, getPyUnoClass().get() ) )
331 : {
332 0 : PyUNO* me = (PyUNO*) object;
333 0 : OUString attrName = OUString::createFromAscii(name);
334 0 : if (! me->members->xInvocation->hasMethod (attrName))
335 : {
336 0 : OUStringBuffer buf;
337 0 : buf.append( "Attribute " );
338 0 : buf.append( attrName );
339 0 : buf.append( " unknown" );
340 0 : throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
341 : }
342 0 : callable = PyUNO_callable_new (
343 : me->members->xInvocation,
344 : attrName,
345 0 : runtime.getImpl()->cargo->xInvocation,
346 0 : runtime.getImpl()->cargo->xTypeConverter,
347 0 : ACCEPT_UNO_ANY);
348 0 : paras = args;
349 : }
350 : else
351 : {
352 : // clean the tuple from uno.Any !
353 0 : int size = PyTuple_Size( args );
354 : { // for CC, keeping ref-count of tuple being 1
355 0 : paras = PyRef(PyTuple_New( size ), SAL_NO_ACQUIRE);
356 : }
357 0 : for( int i = 0 ; i < size ;i ++ )
358 : {
359 0 : PyObject * element = PyTuple_GetItem( args , i );
360 0 : if( PyObject_IsInstance( element , getAnyClass( runtime ).get() ) )
361 : {
362 : element = PyObject_GetAttrString(
363 0 : element, "value" );
364 : }
365 : else
366 : {
367 0 : Py_XINCREF( element );
368 : }
369 0 : PyTuple_SetItem( paras.get(), i , element );
370 : }
371 0 : callable = PyRef( PyObject_GetAttrString( object , (char*)name ), SAL_NO_ACQUIRE );
372 0 : if( !callable.is() )
373 0 : return 0;
374 : }
375 0 : ret = PyRef( PyObject_CallObject( callable.get(), paras.get() ), SAL_NO_ACQUIRE );
376 : }
377 0 : catch (const ::com::sun::star::lang::IllegalArgumentException &e)
378 : {
379 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
380 : }
381 0 : catch (const ::com::sun::star::script::CannotConvertException &e)
382 : {
383 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
384 : }
385 0 : catch (const ::com::sun::star::uno::RuntimeException &e)
386 : {
387 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
388 : }
389 0 : catch (const ::com::sun::star::uno::Exception &e)
390 : {
391 0 : raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
392 : }
393 :
394 0 : return ret.getAcquired();
395 : }
396 :
397 0 : PyObject *PyUNO_str( PyObject * self )
398 : {
399 0 : PyUNO *me = ( PyUNO * ) self;
400 :
401 0 : OStringBuffer buf;
402 :
403 :
404 0 : if( me->members->wrappedObject.getValueType().getTypeClass()
405 0 : == com::sun::star::uno::TypeClass_STRUCT ||
406 0 : me->members->wrappedObject.getValueType().getTypeClass()
407 : == com::sun::star::uno::TypeClass_EXCEPTION)
408 : {
409 0 : Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
410 0 : if( rHolder.is() )
411 : {
412 0 : PyThreadDetach antiguard;
413 0 : Any a = rHolder->getMaterial();
414 0 : OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() );
415 0 : buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
416 0 : }
417 : }
418 : else
419 : {
420 : // a common UNO object
421 0 : PyThreadDetach antiguard;
422 0 : buf.append( "pyuno object " );
423 :
424 : OUString s = val2str( (void*)me->members->wrappedObject.getValue(),
425 0 : me->members->wrappedObject.getValueType().getTypeLibType() );
426 0 : buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
427 : }
428 :
429 0 : return PyStr_FromString( buf.getStr());
430 : }
431 :
432 362 : PyObject* PyUNO_getattr (PyObject* self, char* name)
433 : {
434 : PyUNO* me;
435 :
436 : try
437 : {
438 :
439 362 : Runtime runtime;
440 :
441 362 : me = (PyUNO*) self;
442 : //Handle Python dir () stuff first...
443 362 : if (strcmp (name, "__members__") == 0)
444 : {
445 : PyObject* member_list;
446 0 : Sequence<OUString> oo_member_list;
447 :
448 0 : oo_member_list = me->members->xInvocation->getMemberNames ();
449 0 : member_list = PyList_New (oo_member_list.getLength ());
450 0 : for (int i = 0; i < oo_member_list.getLength (); i++)
451 : {
452 : // setitem steals a reference
453 0 : PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
454 : }
455 0 : return member_list;
456 : }
457 :
458 362 : if (strcmp (name, "__dict__") == 0)
459 : {
460 0 : Py_INCREF (Py_None);
461 0 : return Py_None;
462 : }
463 362 : if (strcmp (name, "__methods__") == 0)
464 : {
465 0 : Py_INCREF (Py_None);
466 0 : return Py_None;
467 : }
468 362 : if (strcmp (name, "__class__") == 0)
469 : {
470 352 : if( me->members->wrappedObject.getValueTypeClass() ==
471 344 : com::sun::star::uno::TypeClass_STRUCT ||
472 168 : me->members->wrappedObject.getValueTypeClass() ==
473 : com::sun::star::uno::TypeClass_EXCEPTION )
474 : {
475 : return getClass(
476 64 : me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
477 : }
478 112 : Py_INCREF (Py_None);
479 112 : return Py_None;
480 : }
481 :
482 186 : OUString attrName( OUString::createFromAscii( name ) );
483 : //We need to find out if it's a method...
484 186 : if (me->members->xInvocation->hasMethod (attrName))
485 : {
486 : //Create a callable object to invoke this...
487 : PyRef ret = PyUNO_callable_new (
488 : me->members->xInvocation,
489 : attrName,
490 180 : runtime.getImpl()->cargo->xInvocation,
491 360 : runtime.getImpl()->cargo->xTypeConverter);
492 180 : Py_XINCREF( ret.get() );
493 180 : return ret.get();
494 :
495 : }
496 :
497 : //or a property
498 6 : if (me->members->xInvocation->hasProperty ( attrName))
499 : {
500 : //Return the value of the property
501 6 : Any anyRet;
502 : {
503 6 : PyThreadDetach antiguard;
504 6 : anyRet = me->members->xInvocation->getValue (attrName);
505 : }
506 12 : PyRef ret = runtime.any2PyObject(anyRet);
507 6 : Py_XINCREF( ret.get() );
508 12 : return ret.get();
509 : }
510 :
511 : //or else...
512 0 : PyErr_SetString (PyExc_AttributeError, name);
513 : }
514 0 : catch( const com::sun::star::reflection::InvocationTargetException & e )
515 : {
516 0 : raisePyExceptionWithAny( makeAny(e.TargetException) );
517 : }
518 0 : catch( const com::sun::star::beans::UnknownPropertyException & e )
519 : {
520 0 : 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 0 : return NULL;
536 : }
537 :
538 28 : int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
539 : {
540 : PyUNO* me;
541 :
542 28 : me = (PyUNO*) self;
543 : try
544 : {
545 28 : Runtime runtime;
546 56 : Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
547 :
548 56 : OUString attrName( OUString::createFromAscii( name ) );
549 : {
550 28 : PyThreadDetach antiguard;
551 28 : if (me->members->xInvocation->hasProperty (attrName))
552 : {
553 0 : me->members->xInvocation->setValue (attrName, val);
554 0 : return 0; //Keep with Python's boolean system
555 28 : }
556 28 : }
557 : }
558 0 : catch( const com::sun::star::reflection::InvocationTargetException & e )
559 : {
560 0 : raisePyExceptionWithAny( makeAny(e.TargetException) );
561 0 : 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 28 : PyErr_SetString (PyExc_AttributeError, name);
579 28 : 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 '!=' comparisions 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 : /* Python 2 has a tp_flags value for rich comparisons. Python 3 does not (on by default) */
646 : #ifdef Py_TPFLAGS_HAVE_RICHCOMPARE
647 : #define TP_FLAGS (Py_TPFLAGS_HAVE_RICHCOMPARE)
648 : #else
649 : #define TP_FLAGS 0
650 : #endif
651 :
652 : static PyTypeObject PyUNOType =
653 : {
654 : PyVarObject_HEAD_INIT( &PyType_Type, 0 )
655 : "pyuno",
656 : sizeof (PyUNO),
657 : 0,
658 : (destructor) PyUNO_del,
659 : (printfunc) 0,
660 : (getattrfunc) PyUNO_getattr,
661 : (setattrfunc) PyUNO_setattr,
662 : /* this type does not exist in Python 3: (cmpfunc) */ 0,
663 : (reprfunc) PyUNO_repr,
664 : 0,
665 : 0,
666 : 0,
667 : (hashfunc) 0,
668 : (ternaryfunc) 0,
669 : (reprfunc) PyUNO_str,
670 : (getattrofunc)0,
671 : (setattrofunc)0,
672 : NULL,
673 : TP_FLAGS,
674 : NULL,
675 : (traverseproc)0,
676 : (inquiry)0,
677 : (richcmpfunc) PyUNO_cmp,
678 : 0,
679 : (getiterfunc)0,
680 : (iternextfunc)0,
681 : NULL,
682 : NULL,
683 : NULL,
684 : NULL,
685 : NULL,
686 : (descrgetfunc)0,
687 : (descrsetfunc)0,
688 : 0,
689 : (initproc)0,
690 : (allocfunc)0,
691 : (newfunc)0,
692 : (freefunc)0,
693 : (inquiry)0,
694 : NULL,
695 : NULL,
696 : NULL,
697 : NULL,
698 : NULL,
699 : (destructor)0
700 : #if PY_VERSION_HEX >= 0x02060000
701 : , 0
702 : #endif
703 : };
704 :
705 29 : PyRef getPyUnoClass()
706 : {
707 29 : return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
708 : }
709 :
710 70 : PyObject* PyUNO_new (
711 : const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
712 : {
713 70 : Reference<XInterface> tmp_interface;
714 :
715 70 : targetInterface >>= tmp_interface;
716 :
717 70 : if (!tmp_interface.is ())
718 : {
719 : // empty reference !
720 0 : Py_INCREF( Py_None );
721 0 : return Py_None;
722 : }
723 70 : return PyUNO_new_UNCHECKED (targetInterface, ssf);
724 : }
725 :
726 :
727 115 : PyObject* PyUNO_new_UNCHECKED (
728 : const Any &targetInterface,
729 : const Reference<XSingleServiceFactory> &ssf )
730 : {
731 : PyUNO* self;
732 115 : Sequence<Any> arguments (1);
733 230 : Reference<XInterface> tmp_interface;
734 :
735 115 : self = PyObject_New (PyUNO, &PyUNOType);
736 115 : if (self == NULL)
737 0 : return NULL; // == error
738 115 : self->members = new PyUNOInternals();
739 :
740 115 : arguments[0] <<= targetInterface;
741 : {
742 115 : PyThreadDetach antiguard;
743 115 : tmp_interface = ssf->createInstanceWithArguments (arguments);
744 :
745 115 : if (!tmp_interface.is ())
746 : {
747 0 : Py_INCREF( Py_None );
748 0 : return Py_None;
749 : }
750 :
751 230 : Reference<XInvocation2> tmp_invocation (tmp_interface, UNO_QUERY);
752 115 : if (!tmp_invocation.is()) {
753 : throw RuntimeException (OUString::createFromAscii (
754 : "XInvocation2 not implemented, cannot interact with object"),
755 0 : Reference< XInterface > ());
756 : }
757 :
758 115 : self->members->xInvocation = tmp_invocation;
759 230 : self->members->wrappedObject = targetInterface;
760 : }
761 230 : return (PyObject*) self;
762 : }
763 :
764 : }
765 :
766 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|