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().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 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 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 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 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 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 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 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 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 822 , 0 823 #endif 824 }; 825 826 PyRef getPyUnoClass() 827 { 828 return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) ); 829 } 830 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 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