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