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