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
445 #if PY_MAJOR_VERSION >= 3
PyUNO_getattr(PyObject * self,PyObject * attr_name)446 PyObject* PyUNO_getattr (PyObject* self, PyObject* attr_name)
447 #else
448 PyObject* PyUNO_getattr (PyObject* self, char* name)
449 #endif
450 {
451 PyUNO* me;
452
453 #if PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x03060000
454 char *name = PyUnicode_AsUTF8(attr_name);
455 #elif PY_MAJOR_VERSION >= 3
456 PyRef pUtf8(PyUnicode_AsUTF8String(attr_name), SAL_NO_ACQUIRE);
457 char *name = PyBytes_AsString(pUtf8.get());
458 #endif
459 try
460 {
461
462 Runtime runtime;
463
464 me = (PyUNO*) self;
465 #if PY_MAJOR_VERSION < 3
466 //Handle Python dir () stuff first...
467 if (strcmp (name, "__members__") == 0)
468 {
469 PyObject* member_list;
470 Sequence<OUString> oo_member_list;
471
472 oo_member_list = me->members->xInvocation->getMemberNames ();
473 member_list = PyList_New (oo_member_list.getLength ());
474 for (int i = 0; i < oo_member_list.getLength (); i++)
475 {
476 // setitem steals a reference
477 PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
478 }
479 return member_list;
480 }
481 #endif
482
483 if (strcmp (name, "__dict__") == 0)
484 {
485 Py_INCREF (Py_None);
486 return Py_None;
487 }
488 #if PY_MAJOR_VERSION < 3
489 if (strcmp (name, "__methods__") == 0)
490 {
491 Py_INCREF (Py_None);
492 return Py_None;
493 }
494 #endif
495 if (strcmp (name, "__class__") == 0)
496 {
497 if( me->members->wrappedObject.getValueTypeClass() ==
498 com::sun::star::uno::TypeClass_STRUCT ||
499 me->members->wrappedObject.getValueTypeClass() ==
500 com::sun::star::uno::TypeClass_EXCEPTION )
501 {
502 return getClass(
503 me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
504 }
505 Py_INCREF (Py_None);
506 return Py_None;
507 }
508
509 OUString attrName( OUString::createFromAscii( name ) );
510 //We need to find out if it's a method...
511 if (me->members->xInvocation->hasMethod (attrName))
512 {
513 //Create a callable object to invoke this...
514 PyRef ret = PyUNO_callable_new (
515 me->members->xInvocation,
516 attrName);
517 Py_XINCREF( ret.get() );
518 return ret.get();
519
520 }
521
522 //or a property
523 if (me->members->xInvocation->hasProperty ( attrName))
524 {
525 //Return the value of the property
526 Any anyRet;
527 {
528 PyThreadDetach antiguard;
529 anyRet = me->members->xInvocation->getValue (attrName);
530 }
531 PyRef ret = runtime.any2PyObject(anyRet);
532 Py_XINCREF( ret.get() );
533 return ret.get();
534 }
535
536 //or else...
537 PyErr_SetString (PyExc_AttributeError, name);
538 }
539 catch( com::sun::star::reflection::InvocationTargetException & e )
540 {
541 raisePyExceptionWithAny( makeAny(e.TargetException) );
542 }
543 catch( com::sun::star::beans::UnknownPropertyException & e )
544 {
545 raisePyExceptionWithAny( makeAny(e) );
546 }
547 catch( com::sun::star::lang::IllegalArgumentException &e )
548 {
549 raisePyExceptionWithAny( makeAny(e) );
550 }
551 catch( com::sun::star::script::CannotConvertException &e )
552 {
553 raisePyExceptionWithAny( makeAny(e) );
554 }
555 catch( RuntimeException &e )
556 {
557 raisePyExceptionWithAny( makeAny(e) );
558 }
559
560 return NULL;
561 }
562
563 #if PY_MAJOR_VERSION >= 3
PyUNO_setattr(PyObject * self,PyObject * attr_name,PyObject * value)564 int PyUNO_setattr (PyObject* self, PyObject* attr_name, PyObject* value)
565 #else
566 int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
567 #endif
568 {
569 PyUNO* me;
570
571 #if PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x03060000
572 char *name = PyUnicode_AsUTF8(attr_name);
573 #elif PY_MAJOR_VERSION >= 3
574 PyRef pUtf8(PyUnicode_AsUTF8String(attr_name), SAL_NO_ACQUIRE);
575 char *name = PyBytes_AsString(pUtf8.get());
576 #endif
577 me = (PyUNO*) self;
578 try
579 {
580 Runtime runtime;
581 Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
582
583 OUString attrName( OUString::createFromAscii( name ) );
584 {
585 PyThreadDetach antiguard;
586 if (me->members->xInvocation->hasProperty (attrName))
587 {
588 me->members->xInvocation->setValue (attrName, val);
589 return 0; //Keep with Python's boolean system
590 }
591 }
592 }
593 catch( com::sun::star::reflection::InvocationTargetException & e )
594 {
595 raisePyExceptionWithAny( makeAny(e.TargetException) );
596 return 1;
597 }
598 catch( com::sun::star::beans::UnknownPropertyException & e )
599 {
600 raisePyExceptionWithAny( makeAny(e) );
601 return 1;
602 }
603 catch( com::sun::star::script::CannotConvertException &e )
604 {
605 raisePyExceptionWithAny( makeAny(e) );
606 return 1;
607 }
608 catch( RuntimeException & e )
609 {
610 raisePyExceptionWithAny( makeAny( e ) );
611 return 1;
612 }
613 PyErr_SetString (PyExc_AttributeError, name);
614 return 1; //as above.
615 }
616
617 #if PY_MAJOR_VERSION >= 3
PyUNO_dir(PyObject * self,PyObject * that)618 static PyObject *PyUNO_dir( PyObject *self, PyObject *that )
619 {
620 PyUNO* me;
621 PyObject* member_list;
622 Sequence<OUString> oo_member_list;
623
624 me = (PyUNO*) self;
625 oo_member_list = me->members->xInvocation->getMemberNames ();
626 member_list = PyList_New (oo_member_list.getLength ());
627 for (int i = 0; i < oo_member_list.getLength (); i++)
628 {
629 // setitem steals a reference
630 PyList_SetItem (member_list, i, ustring2PyUnicode(oo_member_list[i]).getAcquired() );
631 }
632 return member_list;
633 }
634
PyUNO_richcompare(PyObject * self,PyObject * that,int op)635 static PyObject *PyUNO_richcompare( PyObject *self, PyObject *that, int op )
636 {
637 switch (op)
638 {
639 case Py_EQ:
640 case Py_NE:
641 if( self == that )
642 {
643 if (op == Py_EQ)
644 Py_RETURN_TRUE;
645 else
646 Py_RETURN_FALSE;
647 }
648 try
649 {
650 Runtime runtime;
651 if( PyObject_IsInstance( that, getPyUnoClass().get() ) )
652 {
653 PyUNO *me = reinterpret_cast< PyUNO*> ( self );
654 PyUNO *other = reinterpret_cast< PyUNO *> (that );
655 com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
656 com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
657
658 if( tcMe == tcOther )
659 {
660 if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
661 tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
662 {
663 Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
664 Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
665 if( xMe->getMaterial() == xOther->getMaterial() )
666 {
667 if (op == Py_EQ)
668 Py_RETURN_TRUE;
669 else
670 Py_RETURN_FALSE;
671 }
672 }
673 else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
674 {
675 if( me->members->wrappedObject == other->members->wrappedObject )
676 {
677 if (op == Py_EQ)
678 Py_RETURN_TRUE;
679 else
680 Py_RETURN_FALSE;
681 }
682 }
683 }
684 }
685 if (op == Py_EQ)
686 Py_RETURN_FALSE;
687 else
688 Py_RETURN_TRUE;
689 }
690 catch( com::sun::star::uno::RuntimeException & e)
691 {
692 raisePyExceptionWithAny( makeAny( e ) );
693 }
694 break;
695 default:
696 PyErr_SetString(Py_NotImplemented, "not implemented");
697 break;
698 }
699
700 return NULL;
701 }
702
703
704 static struct PyMethodDef PyUNO_methods[] = {
705 { "__dir__", (PyCFunction)PyUNO_dir, METH_VARARGS, NULL},
706 { NULL, NULL }
707 };
708
709 #else
710 // ensure object identity and struct equality
PyUNO_cmp(PyObject * self,PyObject * that)711 static int PyUNO_cmp( PyObject *self, PyObject *that )
712 {
713 if( self == that )
714 return 0;
715 int retDefault = self > that ? 1 : -1;
716 try
717 {
718 Runtime runtime;
719 if( PyObject_IsInstance( that, getPyUnoClass().get() ) )
720 {
721
722 PyUNO *me = reinterpret_cast< PyUNO*> ( self );
723 PyUNO *other = reinterpret_cast< PyUNO *> (that );
724 com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
725 com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
726
727 if( tcMe == tcOther )
728 {
729 if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
730 tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
731 {
732 Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
733 Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
734 if( xMe->getMaterial() == xOther->getMaterial() )
735 return 0;
736 }
737 else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
738 {
739 if( me->members->wrappedObject == other->members->wrappedObject )
740 // if( me->members->xInvocation == other->members->xInvocation )
741 return 0;
742 }
743 }
744 }
745 }
746 catch( com::sun::star::uno::RuntimeException & e)
747 {
748 raisePyExceptionWithAny( makeAny( e ) );
749 }
750 return retDefault;
751 }
752 #endif
753
754 static PyTypeObject PyUNOType =
755 {
756 PyVarObject_HEAD_INIT(&PyType_Type, 0)
757 const_cast< char * >("pyuno"),
758 sizeof (PyUNO),
759 0,
760 (destructor) PyUNO_del,
761 (printfunc) 0,
762 #if PY_MAJOR_VERSION >= 3
763 (getattrfunc) 0,
764 (setattrfunc) 0,
765 0,
766 #else
767 (getattrfunc) PyUNO_getattr, /* tp_getattr */
768 (setattrfunc) PyUNO_setattr, /* tp_setattr */
769 (cmpfunc) PyUNO_cmp,
770 #endif
771 (reprfunc) PyUNO_repr,
772 0,
773 0,
774 0,
775 (hashfunc) 0,
776 (ternaryfunc) 0,
777 (reprfunc) PyUNO_str,
778 #if PY_MAJOR_VERSION >= 3
779 (getattrofunc)PyUNO_getattr, /* tp_getattro */
780 (setattrofunc)PyUNO_setattr, /* tp_setattro */
781 #else
782 (getattrofunc)0,
783 (setattrofunc)0,
784 #endif
785 NULL,
786 0,
787 NULL,
788 (traverseproc)0,
789 (inquiry)0,
790 #if PY_MAJOR_VERSION >= 3
791 PyUNO_richcompare, /* tp_richcompare */
792 #else
793 (richcmpfunc)0,
794 #endif
795 0,
796 (getiterfunc)0,
797 (iternextfunc)0,
798 #if PY_MAJOR_VERSION >= 3
799 PyUNO_methods, /* tp_methods */
800 #else
801 NULL,
802 #endif
803 NULL,
804 NULL,
805 NULL,
806 NULL,
807 (descrgetfunc)0,
808 (descrsetfunc)0,
809 0,
810 (initproc)0,
811 (allocfunc)0,
812 (newfunc)0,
813 (freefunc)0,
814 (inquiry)0,
815 NULL,
816 NULL,
817 NULL,
818 NULL,
819 NULL,
820 (destructor)0
821 #if PY_VERSION_HEX >= 0x02060000 && PY_VERSION_HEX < 0x03060000
822 , 0
823 #endif
824 };
825
getPyUnoClass()826 PyRef getPyUnoClass()
827 {
828 return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
829 }
830
PyUNO_new(const Any & targetInterface,const Reference<XSingleServiceFactory> & ssf)831 PyObject* PyUNO_new (
832 const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
833 {
834 Reference<XInterface> tmp_interface;
835
836 targetInterface >>= tmp_interface;
837 if (!tmp_interface.is ())
838 {
839 // empty reference !
840 Py_INCREF( Py_None );
841 return Py_None;
842 }
843
844 return PyUNO_new_UNCHECKED (targetInterface, ssf);
845 }
846
847
PyUNO_new_UNCHECKED(const Any & targetInterface,const Reference<XSingleServiceFactory> & ssf)848 PyObject* PyUNO_new_UNCHECKED (
849 const Any &targetInterface,
850 const Reference<XSingleServiceFactory> &ssf )
851 {
852 PyUNO* self;
853 Sequence<Any> arguments (1);
854 Reference<XInterface> tmp_interface;
855
856 self = PyObject_New (PyUNO, &PyUNOType);
857 if (self == NULL)
858 return NULL; //NULL == error
859 self->members = new PyUNOInternals();
860
861 arguments[0] <<= targetInterface;
862 {
863 PyThreadDetach antiguard;
864 tmp_interface = ssf->createInstanceWithArguments (arguments);
865 Reference<XInvocation2> tmp_invocation (tmp_interface, UNO_QUERY);
866 self->members->xInvocation = tmp_invocation;
867 self->members->wrappedObject = targetInterface;
868 }
869 return (PyObject*) self;
870 }
871
872 }
873