xref: /trunk/main/pyuno/source/module/pyuno.cxx (revision 27dee00ef8b391d4d520b7edb65b4093b02f83ed)
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 
PyUNO_del(PyObject * self)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 
val2str(const void * pVal,typelib_TypeDescriptionReference * pTypeRef,sal_Int32 mode)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 
PyUNO_repr(PyObject * self)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 
PyUNO_invoke(PyObject * object,const char * name,PyObject * args)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().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                 ACCEPT_UNO_ANY);
361             paras = args;
362         }
363         else
364         {
365             // clean the tuple from uno.Any !
366             int size = PyTuple_Size( args );
367             { // for CC, keeping ref-count of tuple being 1
368             paras = PyRef(PyTuple_New( size ), SAL_NO_ACQUIRE);
369             }
370             for( int i = 0 ; i < size ;i ++ )
371             {
372                 PyObject * element = PyTuple_GetItem( args , i );
373                 if( PyObject_IsInstance( element , getAnyClass( runtime ).get() ) )
374                 {
375                     element = PyObject_GetAttrString(
376                         element, const_cast< char * >("value") );
377                 }
378                 else
379                 {
380                     Py_XINCREF( element );
381                 }
382                 PyTuple_SetItem( paras.get(), i , element );
383             }
384             callable = PyRef( PyObject_GetAttrString( object , (char*)name ), SAL_NO_ACQUIRE );
385             if( !callable.is() )
386                 return 0;
387         }
388         ret = PyRef( PyObject_CallObject( callable.get(), paras.get() ), SAL_NO_ACQUIRE );
389     }
390     catch (::com::sun::star::lang::IllegalArgumentException &e)
391     {
392         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
393     }
394     catch (::com::sun::star::script::CannotConvertException &e)
395     {
396         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
397     }
398     catch (::com::sun::star::uno::RuntimeException &e)
399     {
400         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
401     }
402     catch (::com::sun::star::uno::Exception &e)
403     {
404         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
405     }
406 
407     return ret.getAcquired();
408 }
409 
PyUNO_str(PyObject * self)410 PyObject *PyUNO_str( PyObject * self )
411 {
412     PyUNO *me = ( PyUNO * ) self;
413 
414     OStringBuffer buf;
415 
416 
417     if( me->members->wrappedObject.getValueType().getTypeClass()
418         == com::sun::star::uno::TypeClass_STRUCT ||
419         me->members->wrappedObject.getValueType().getTypeClass()
420         == com::sun::star::uno::TypeClass_EXCEPTION)
421     {
422         Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
423         if( rHolder.is() )
424         {
425             PyThreadDetach antiguard;
426             Any a = rHolder->getMaterial();
427             OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() );
428             buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
429         }
430     }
431     else
432     {
433         // a common UNO object
434         PyThreadDetach antiguard;
435         buf.append( "pyuno object " );
436 
437         OUString s = val2str( (void*)me->members->wrappedObject.getValue(),
438                               me->members->wrappedObject.getValueType().getTypeLibType() );
439         buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
440     }
441 
442     return PYSTR_FROMSTR( buf.getStr() );
443 }
444 
PyUNO_getattr(PyObject * self,PyObject * attr_name)445 PyObject* PyUNO_getattr (PyObject* self, PyObject* attr_name)
446 {
447     PyUNO* me;
448 
449     const char *name = PyUnicode_AsUTF8(attr_name);
450     try
451     {
452 
453         Runtime runtime;
454 
455         me = (PyUNO*) self;
456 
457         if (strcmp (name, "__dict__") == 0)
458         {
459             Py_INCREF (Py_None);
460             return Py_None;
461         }
462         if (strcmp (name, "__class__") == 0)
463         {
464             if( me->members->wrappedObject.getValueTypeClass() ==
465                 com::sun::star::uno::TypeClass_STRUCT ||
466                 me->members->wrappedObject.getValueTypeClass() ==
467                 com::sun::star::uno::TypeClass_EXCEPTION )
468             {
469                 return getClass(
470                     me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
471             }
472             Py_INCREF (Py_None);
473             return Py_None;
474         }
475 
476         OUString attrName( OUString::createFromAscii( name ) );
477         //We need to find out if it's a method...
478         if (me->members->xInvocation->hasMethod (attrName))
479         {
480             //Create a callable object to invoke this...
481             PyRef ret = PyUNO_callable_new (
482                 me->members->xInvocation,
483                 attrName);
484             Py_XINCREF( ret.get() );
485             return ret.get();
486 
487         }
488 
489         //or a property
490         if (me->members->xInvocation->hasProperty ( attrName))
491         {
492             //Return the value of the property
493             Any anyRet;
494             {
495                 PyThreadDetach antiguard;
496                 anyRet = me->members->xInvocation->getValue (attrName);
497             }
498             PyRef ret = runtime.any2PyObject(anyRet);
499             Py_XINCREF( ret.get() );
500             return ret.get();
501         }
502 
503         //or else...
504         PyErr_SetString (PyExc_AttributeError, name);
505     }
506     catch( com::sun::star::reflection::InvocationTargetException & e )
507     {
508         raisePyExceptionWithAny( makeAny(e.TargetException) );
509     }
510     catch( com::sun::star::beans::UnknownPropertyException & e )
511     {
512         raisePyExceptionWithAny( makeAny(e) );
513     }
514     catch( com::sun::star::lang::IllegalArgumentException &e )
515     {
516         raisePyExceptionWithAny( makeAny(e) );
517     }
518     catch( com::sun::star::script::CannotConvertException &e )
519     {
520         raisePyExceptionWithAny( makeAny(e) );
521     }
522     catch( RuntimeException &e )
523     {
524         raisePyExceptionWithAny( makeAny(e) );
525     }
526 
527     return NULL;
528 }
529 
PyUNO_setattr(PyObject * self,PyObject * attr_name,PyObject * value)530 int PyUNO_setattr (PyObject* self, PyObject* attr_name, PyObject* value)
531 {
532     PyUNO* me;
533 
534     const char *name = PyUnicode_AsUTF8(attr_name);
535     me = (PyUNO*) self;
536     try
537     {
538         Runtime runtime;
539         Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
540 
541         OUString attrName( OUString::createFromAscii( name ) );
542         {
543             PyThreadDetach antiguard;
544             if (me->members->xInvocation->hasProperty (attrName))
545             {
546                 me->members->xInvocation->setValue (attrName, val);
547                 return 0; //Keep with Python's boolean system
548             }
549         }
550     }
551     catch( com::sun::star::reflection::InvocationTargetException & e )
552     {
553         raisePyExceptionWithAny( makeAny(e.TargetException) );
554         return 1;
555     }
556     catch( com::sun::star::beans::UnknownPropertyException & e )
557     {
558         raisePyExceptionWithAny( makeAny(e) );
559         return 1;
560     }
561     catch( com::sun::star::script::CannotConvertException &e )
562     {
563         raisePyExceptionWithAny( makeAny(e) );
564         return 1;
565     }
566     catch( RuntimeException & e )
567     {
568         raisePyExceptionWithAny( makeAny( e ) );
569         return 1;
570     }
571     PyErr_SetString (PyExc_AttributeError, name);
572     return 1; //as above.
573 }
574 
PyUNO_dir(PyObject * self,PyObject * that)575 static PyObject *PyUNO_dir( PyObject *self, PyObject *that )
576 {
577     PyUNO* me;
578     PyObject* member_list;
579     Sequence<OUString> oo_member_list;
580 
581     me = (PyUNO*) self;
582     oo_member_list = me->members->xInvocation->getMemberNames ();
583     member_list = PyList_New (oo_member_list.getLength ());
584     for (int i = 0; i < oo_member_list.getLength (); i++)
585     {
586         // setitem steals a reference
587         PyList_SetItem (member_list, i, ustring2PyUnicode(oo_member_list[i]).getAcquired() );
588     }
589     return member_list;
590 }
591 
PyUNO_richcompare(PyObject * self,PyObject * that,int op)592 static PyObject *PyUNO_richcompare( PyObject *self, PyObject *that, int op )
593 {
594     switch (op)
595     {
596     case Py_EQ:
597     case Py_NE:
598         if( self == that )
599         {
600             if (op == Py_EQ)
601                 Py_RETURN_TRUE;
602             else
603                 Py_RETURN_FALSE;
604         }
605         try
606         {
607             Runtime runtime;
608             if( PyObject_IsInstance( that, getPyUnoClass().get() ) )
609             {
610                 PyUNO *me = reinterpret_cast< PyUNO*> ( self );
611                 PyUNO *other = reinterpret_cast< PyUNO *> (that );
612                 com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
613                 com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
614 
615                 if( tcMe == tcOther )
616                 {
617                     if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
618                         tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
619                     {
620                         Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
621                         Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
622                         if( xMe->getMaterial() == xOther->getMaterial() )
623                         {
624                             if (op == Py_EQ)
625                                 Py_RETURN_TRUE;
626                             else
627                                 Py_RETURN_FALSE;
628                         }
629                     }
630                     else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
631                     {
632                         if( me->members->wrappedObject == other->members->wrappedObject )
633                         {
634                             if (op == Py_EQ)
635                                 Py_RETURN_TRUE;
636                             else
637                                 Py_RETURN_FALSE;
638                         }
639                     }
640                 }
641             }
642             if (op == Py_EQ)
643                 Py_RETURN_FALSE;
644             else
645                 Py_RETURN_TRUE;
646         }
647         catch( com::sun::star::uno::RuntimeException & e)
648         {
649             raisePyExceptionWithAny( makeAny( e ) );
650         }
651         break;
652     default:
653         PyErr_SetString(Py_NotImplemented, "not implemented");
654         break;
655     }
656 
657     return NULL;
658 }
659 
660 
661 static struct PyMethodDef PyUNO_methods[] = {
662     { "__dir__", (PyCFunction)PyUNO_dir, METH_VARARGS, NULL},
663     { NULL, NULL }
664 };
665 
666 static PyTypeObject PyUNOType =
667 {
668     PyVarObject_HEAD_INIT(&PyType_Type, 0)
669     const_cast< char * >("pyuno"),
670     sizeof (PyUNO),
671     0,
672     (destructor) PyUNO_del,
673     (printfunc) 0,
674     (getattrfunc) 0,
675     (setattrfunc) 0,
676     0,
677     (reprfunc) PyUNO_repr,
678     0,
679     0,
680     0,
681     (hashfunc) 0,
682     (ternaryfunc) 0,
683     (reprfunc) PyUNO_str,
684     (getattrofunc)PyUNO_getattr, /* tp_getattro */
685     (setattrofunc)PyUNO_setattr, /* tp_setattro */
686     NULL,
687     0,
688     NULL,
689     (traverseproc)0,
690     (inquiry)0,
691     PyUNO_richcompare, /* tp_richcompare */
692     0,
693     (getiterfunc)0,
694     (iternextfunc)0,
695     PyUNO_methods, /* tp_methods */
696     NULL,
697     NULL,
698     NULL,
699     NULL,
700     (descrgetfunc)0,
701     (descrsetfunc)0,
702     0,
703     (initproc)0,
704     (allocfunc)0,
705     (newfunc)0,
706     (freefunc)0,
707     (inquiry)0,
708     NULL,
709     NULL,
710     NULL,
711     NULL,
712     NULL,
713     (destructor)0,
714     0
715 };
716 
getPyUnoClass()717 PyRef getPyUnoClass()
718 {
719     return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
720 }
721 
PyUNO_new(const Any & targetInterface,const Reference<XSingleServiceFactory> & ssf)722 PyObject* PyUNO_new (
723     const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
724 {
725     Reference<XInterface> tmp_interface;
726 
727     targetInterface >>= tmp_interface;
728     if (!tmp_interface.is ())
729     {
730         // empty reference !
731         Py_INCREF( Py_None );
732         return Py_None;
733     }
734 
735     return PyUNO_new_UNCHECKED (targetInterface, ssf);
736 }
737 
738 
PyUNO_new_UNCHECKED(const Any & targetInterface,const Reference<XSingleServiceFactory> & ssf)739 PyObject* PyUNO_new_UNCHECKED (
740     const Any &targetInterface,
741     const Reference<XSingleServiceFactory> &ssf )
742 {
743     PyUNO* self;
744     Sequence<Any> arguments (1);
745     Reference<XInterface> tmp_interface;
746 
747     self = PyObject_New (PyUNO, &PyUNOType);
748     if (self == NULL)
749         return NULL; //NULL == error
750     self->members = new PyUNOInternals();
751 
752     arguments[0] <<= targetInterface;
753     {
754         PyThreadDetach antiguard;
755         tmp_interface = ssf->createInstanceWithArguments (arguments);
756         Reference<XInvocation2> tmp_invocation (tmp_interface, UNO_QUERY);
757         self->members->xInvocation = tmp_invocation;
758         self->members->wrappedObject = targetInterface;
759     }
760     return (PyObject*) self;
761 }
762 
763 }
764