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