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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_stoc.hxx" 26 27 #include <sal/config.h> 28 #ifdef SAL_UNX 29 #include <sal/alloca.h> 30 #endif 31 #if !(defined(MACOSX) || defined(FREEBSD)) 32 #include <malloc.h> 33 #endif 34 #include <rtl/alloc.h> 35 #include <typelib/typedescription.hxx> 36 #include <uno/data.h> 37 38 #include "base.hxx" 39 40 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" 41 #include "com/sun/star/uno/RuntimeException.hpp" 42 #include "cppuhelper/exc_hlp.hxx" 43 44 namespace stoc_corefl 45 { 46 47 //================================================================================================== 48 class IdlAttributeFieldImpl 49 : public IdlMemberImpl 50 , public XIdlField 51 , public XIdlField2 52 { 53 public: 54 typelib_InterfaceAttributeTypeDescription * getAttributeTypeDescr() 55 { return (typelib_InterfaceAttributeTypeDescription *)getTypeDescr(); } 56 57 IdlAttributeFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, 58 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) 59 : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) 60 {} 61 62 // XInterface 63 virtual Any SAL_CALL queryInterface( const Type & rType ); 64 virtual void SAL_CALL acquire() throw(); 65 virtual void SAL_CALL release() throw(); 66 67 // XTypeProvider 68 virtual Sequence< Type > SAL_CALL getTypes(); 69 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId(); 70 71 // XIdlMember 72 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass(); 73 virtual OUString SAL_CALL getName(); 74 // XIdlField 75 virtual Reference< XIdlClass > SAL_CALL getType(); 76 virtual FieldAccessMode SAL_CALL getAccessMode(); 77 virtual Any SAL_CALL get( const Any & rObj ); 78 virtual void SAL_CALL set( const Any & rObj, const Any & rValue ); 79 // XIdlField2: getType, getAccessMode and get are equal to XIdlField 80 virtual void SAL_CALL set( Any & rObj, const Any & rValue ); 81 82 private: 83 void checkException( 84 uno_Any * exception, Reference< XInterface > const & context); 85 }; 86 87 // XInterface 88 //__________________________________________________________________________________________________ 89 Any IdlAttributeFieldImpl::queryInterface( const Type & rType ) 90 { 91 Any aRet( ::cppu::queryInterface( rType, 92 static_cast< XIdlField * >( this ), 93 static_cast< XIdlField2 * >( this ) ) ); 94 return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); 95 } 96 //__________________________________________________________________________________________________ 97 void IdlAttributeFieldImpl::acquire() throw() 98 { 99 IdlMemberImpl::acquire(); 100 } 101 //__________________________________________________________________________________________________ 102 void IdlAttributeFieldImpl::release() throw() 103 { 104 IdlMemberImpl::release(); 105 } 106 107 // XTypeProvider 108 //__________________________________________________________________________________________________ 109 Sequence< Type > IdlAttributeFieldImpl::getTypes() 110 { 111 static OTypeCollection * s_pTypes = 0; 112 if (! s_pTypes) 113 { 114 MutexGuard aGuard( getMutexAccess() ); 115 if (! s_pTypes) 116 { 117 static OTypeCollection s_aTypes( 118 ::getCppuType( (const Reference< XIdlField2 > *)0 ), 119 ::getCppuType( (const Reference< XIdlField > *)0 ), 120 IdlMemberImpl::getTypes() ); 121 s_pTypes = &s_aTypes; 122 } 123 } 124 return s_pTypes->getTypes(); 125 } 126 //__________________________________________________________________________________________________ 127 Sequence< sal_Int8 > IdlAttributeFieldImpl::getImplementationId() 128 { 129 static OImplementationId * s_pId = 0; 130 if (! s_pId) 131 { 132 MutexGuard aGuard( getMutexAccess() ); 133 if (! s_pId) 134 { 135 static OImplementationId s_aId; 136 s_pId = &s_aId; 137 } 138 } 139 return s_pId->getImplementationId(); 140 } 141 142 // XIdlMember 143 //__________________________________________________________________________________________________ 144 Reference< XIdlClass > IdlAttributeFieldImpl::getDeclaringClass() 145 { 146 if (! _xDeclClass.is()) 147 { 148 MutexGuard aGuard( getMutexAccess() ); 149 if (! _xDeclClass.is()) 150 { 151 rtl::OUString aName(getAttributeTypeDescr()->aBase.aBase.pTypeName); 152 sal_Int32 i = aName.indexOf(':'); 153 OSL_ASSERT(i >= 0); 154 _xDeclClass = getReflection()->forName(aName.copy(0, i)); 155 } 156 } 157 return _xDeclClass; 158 } 159 //__________________________________________________________________________________________________ 160 OUString IdlAttributeFieldImpl::getName() 161 { 162 return IdlMemberImpl::getName(); 163 } 164 165 // XIdlField 166 //__________________________________________________________________________________________________ 167 Reference< XIdlClass > IdlAttributeFieldImpl::getType() 168 { 169 return getReflection()->forType( 170 getAttributeTypeDescr()->pAttributeTypeRef ); 171 } 172 //__________________________________________________________________________________________________ 173 FieldAccessMode IdlAttributeFieldImpl::getAccessMode() 174 { 175 return (((typelib_InterfaceAttributeTypeDescription *)getAttributeTypeDescr())->bReadOnly 176 ? FieldAccessMode_READONLY : FieldAccessMode_READWRITE); 177 } 178 //__________________________________________________________________________________________________ 179 Any IdlAttributeFieldImpl::get( const Any & rObj ) 180 { 181 uno_Interface * pUnoI = getReflection()->mapToUno( 182 rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); 183 OSL_ENSURE( pUnoI, "### illegal destination object given!" ); 184 if (pUnoI) 185 { 186 TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef ); 187 typelib_TypeDescription * pTD = aTD.get(); 188 189 uno_Any aExc; 190 uno_Any * pExc = &aExc; 191 void * pReturn = alloca( pTD->nSize ); 192 193 (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), pReturn, 0, &pExc ); 194 (*pUnoI->release)( pUnoI ); 195 196 checkException( 197 pExc, 198 *static_cast< Reference< XInterface > const * >(rObj.getValue())); 199 Any aRet; 200 uno_any_destruct( 201 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); 202 uno_any_constructAndConvert( &aRet, pReturn, pTD, getReflection()->getUno2Cpp().get() ); 203 uno_destructData( pReturn, pTD, 0 ); 204 return aRet; 205 } 206 throw IllegalArgumentException( 207 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), 208 (XWeak *)(OWeakObject *)this, 0 ); 209 } 210 //__________________________________________________________________________________________________ 211 void IdlAttributeFieldImpl::set( Any & rObj, const Any & rValue ) 212 { 213 if (getAttributeTypeDescr()->bReadOnly) 214 { 215 throw IllegalAccessException( 216 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot set readonly attribute!") ), 217 (XWeak *)(OWeakObject *)this ); 218 } 219 220 uno_Interface * pUnoI = getReflection()->mapToUno( 221 rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); 222 OSL_ENSURE( pUnoI, "### illegal destination object given!" ); 223 if (pUnoI) 224 { 225 TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef ); 226 typelib_TypeDescription * pTD = aTD.get(); 227 228 // construct uno value to be set 229 void * pArgs[1]; 230 void * pArg = pArgs[0] = alloca( pTD->nSize ); 231 232 sal_Bool bAssign; 233 if (pTD->eTypeClass == typelib_TypeClass_ANY) 234 { 235 uno_copyAndConvertData( pArg, SAL_CONST_CAST( Any *, &rValue ), 236 pTD, getReflection()->getCpp2Uno().get() ); 237 bAssign = sal_True; 238 } 239 else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef )) 240 { 241 uno_copyAndConvertData( pArg, SAL_CONST_CAST( void *, rValue.getValue() ), 242 pTD, getReflection()->getCpp2Uno().get() ); 243 bAssign = sal_True; 244 } 245 else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) 246 { 247 Reference< XInterface > xObj; 248 bAssign = extract( 249 rValue, (typelib_InterfaceTypeDescription *)pTD, xObj, 250 getReflection() ); 251 if (bAssign) 252 { 253 *(void **)pArg = getReflection()->getCpp2Uno().mapInterface( 254 xObj.get(), (typelib_InterfaceTypeDescription *)pTD ); 255 } 256 } 257 else 258 { 259 typelib_TypeDescription * pValueTD = 0; 260 TYPELIB_DANGER_GET( &pValueTD, rValue.getValueTypeRef() ); 261 // construct temp uno val to do proper assignment: todo opt 262 void * pTemp = alloca( pValueTD->nSize ); 263 uno_copyAndConvertData( 264 pTemp, (void *)rValue.getValue(), pValueTD, getReflection()->getCpp2Uno().get() ); 265 uno_constructData( 266 pArg, pTD ); 267 // assignment does simple conversion 268 bAssign = uno_assignData( 269 pArg, pTD, pTemp, pValueTD, 0, 0, 0 ); 270 uno_destructData( 271 pTemp, pValueTD, 0 ); 272 TYPELIB_DANGER_RELEASE( pValueTD ); 273 } 274 275 if (bAssign) 276 { 277 uno_Any aExc; 278 uno_Any * pExc = &aExc; 279 (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), 0, pArgs, &pExc ); 280 (*pUnoI->release)( pUnoI ); 281 282 uno_destructData( pArg, pTD, 0 ); 283 checkException( 284 pExc, 285 *static_cast< Reference< XInterface > const * >( 286 rObj.getValue())); 287 return; 288 } 289 (*pUnoI->release)( pUnoI ); 290 291 throw IllegalArgumentException( 292 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), 293 *(const Reference< XInterface > *)rObj.getValue(), 1 ); 294 } 295 throw IllegalArgumentException( 296 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), 297 (XWeak *)(OWeakObject *)this, 0 ); 298 } 299 //__________________________________________________________________________________________________ 300 void IdlAttributeFieldImpl::set( const Any & rObj, const Any & rValue ) 301 { 302 IdlAttributeFieldImpl::set( const_cast< Any & >( rObj ), rValue ); 303 } 304 305 void IdlAttributeFieldImpl::checkException( 306 uno_Any * exception, Reference< XInterface > const & context) 307 { 308 if (exception != 0) { 309 Any e; 310 uno_any_destruct(&e, reinterpret_cast< uno_ReleaseFunc >(cpp_release)); 311 uno_type_any_constructAndConvert( 312 &e, exception->pData, exception->pType, 313 getReflection()->getUno2Cpp().get()); 314 uno_any_destruct(exception, 0); 315 if (e.isExtractableTo( 316 getCppuType(static_cast< RuntimeException const * >(0)))) 317 { 318 cppu::throwException(e); 319 } else { 320 throw WrappedTargetRuntimeException( 321 OUString( 322 RTL_CONSTASCII_USTRINGPARAM( 323 "non-RuntimeException occurred when accessing an" 324 " interface type attribute")), 325 context, e); 326 } 327 } 328 } 329 330 //################################################################################################## 331 //################################################################################################## 332 //################################################################################################## 333 334 335 //================================================================================================== 336 class IdlInterfaceMethodImpl 337 : public IdlMemberImpl 338 , public XIdlMethod 339 { 340 Sequence< Reference< XIdlClass > > * _pExceptionTypes; 341 Sequence< Reference< XIdlClass > > * _pParamTypes; 342 Sequence< ParamInfo > * _pParamInfos; 343 344 public: 345 typelib_InterfaceMethodTypeDescription * getMethodTypeDescr() 346 { return (typelib_InterfaceMethodTypeDescription *)getTypeDescr(); } 347 348 IdlInterfaceMethodImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, 349 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) 350 : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) 351 , _pExceptionTypes( 0 ) 352 , _pParamTypes( 0 ) 353 , _pParamInfos( 0 ) 354 {} 355 virtual ~IdlInterfaceMethodImpl(); 356 357 // XInterface 358 virtual Any SAL_CALL queryInterface( const Type & rType ); 359 virtual void SAL_CALL acquire() throw(); 360 virtual void SAL_CALL release() throw(); 361 362 // XTypeProvider 363 virtual Sequence< Type > SAL_CALL getTypes(); 364 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId(); 365 366 // XIdlMember 367 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass(); 368 virtual OUString SAL_CALL getName(); 369 // XIdlMethod 370 virtual Reference< XIdlClass > SAL_CALL getReturnType(); 371 virtual Sequence< Reference< XIdlClass > > SAL_CALL getParameterTypes(); 372 virtual Sequence< ParamInfo > SAL_CALL getParameterInfos(); 373 virtual Sequence< Reference< XIdlClass > > SAL_CALL getExceptionTypes(); 374 virtual MethodMode SAL_CALL getMode(); 375 virtual Any SAL_CALL invoke( const Any & rObj, Sequence< Any > & rArgs ); 376 }; 377 //__________________________________________________________________________________________________ 378 IdlInterfaceMethodImpl::~IdlInterfaceMethodImpl() 379 { 380 delete _pParamInfos; 381 delete _pParamTypes; 382 delete _pExceptionTypes; 383 } 384 385 // XInterface 386 //__________________________________________________________________________________________________ 387 Any IdlInterfaceMethodImpl::queryInterface( const Type & rType ) 388 { 389 Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlMethod * >( this ) ) ); 390 return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); 391 } 392 //__________________________________________________________________________________________________ 393 void IdlInterfaceMethodImpl::acquire() throw() 394 { 395 IdlMemberImpl::acquire(); 396 } 397 //__________________________________________________________________________________________________ 398 void IdlInterfaceMethodImpl::release() throw() 399 { 400 IdlMemberImpl::release(); 401 } 402 403 // XTypeProvider 404 //__________________________________________________________________________________________________ 405 Sequence< Type > IdlInterfaceMethodImpl::getTypes() 406 { 407 static OTypeCollection * s_pTypes = 0; 408 if (! s_pTypes) 409 { 410 MutexGuard aGuard( getMutexAccess() ); 411 if (! s_pTypes) 412 { 413 static OTypeCollection s_aTypes( 414 ::getCppuType( (const Reference< XIdlMethod > *)0 ), 415 IdlMemberImpl::getTypes() ); 416 s_pTypes = &s_aTypes; 417 } 418 } 419 return s_pTypes->getTypes(); 420 } 421 //__________________________________________________________________________________________________ 422 Sequence< sal_Int8 > IdlInterfaceMethodImpl::getImplementationId() 423 { 424 static OImplementationId * s_pId = 0; 425 if (! s_pId) 426 { 427 MutexGuard aGuard( getMutexAccess() ); 428 if (! s_pId) 429 { 430 static OImplementationId s_aId; 431 s_pId = &s_aId; 432 } 433 } 434 return s_pId->getImplementationId(); 435 } 436 437 // XIdlMember 438 //__________________________________________________________________________________________________ 439 Reference< XIdlClass > IdlInterfaceMethodImpl::getDeclaringClass() 440 { 441 if (! _xDeclClass.is()) 442 { 443 MutexGuard aGuard( getMutexAccess() ); 444 if (! _xDeclClass.is()) 445 { 446 rtl::OUString aName(getMethodTypeDescr()->aBase.aBase.pTypeName); 447 sal_Int32 i = aName.indexOf(':'); 448 OSL_ASSERT(i >= 0); 449 _xDeclClass = getReflection()->forName(aName.copy(0, i)); 450 } 451 } 452 return _xDeclClass; 453 } 454 //__________________________________________________________________________________________________ 455 OUString IdlInterfaceMethodImpl::getName() 456 { 457 return IdlMemberImpl::getName(); 458 } 459 460 // XIdlMethod 461 //__________________________________________________________________________________________________ 462 Reference< XIdlClass > SAL_CALL IdlInterfaceMethodImpl::getReturnType() 463 { 464 return getReflection()->forType( getMethodTypeDescr()->pReturnTypeRef ); 465 } 466 //__________________________________________________________________________________________________ 467 Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getExceptionTypes() 468 { 469 if (! _pExceptionTypes) 470 { 471 MutexGuard aGuard( getMutexAccess() ); 472 if (! _pExceptionTypes) 473 { 474 sal_Int32 nExc = getMethodTypeDescr()->nExceptions; 475 Sequence< Reference< XIdlClass > > * pTempExceptionTypes = 476 new Sequence< Reference< XIdlClass > >( nExc ); 477 Reference< XIdlClass > * pExceptionTypes = pTempExceptionTypes->getArray(); 478 479 typelib_TypeDescriptionReference ** ppExc = 480 getMethodTypeDescr()->ppExceptions; 481 IdlReflectionServiceImpl * pRefl = getReflection(); 482 483 while (nExc--) 484 pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] ); 485 486 _pExceptionTypes = pTempExceptionTypes; 487 } 488 } 489 return *_pExceptionTypes; 490 } 491 //__________________________________________________________________________________________________ 492 Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes() 493 { 494 if (! _pParamTypes) 495 { 496 MutexGuard aGuard( getMutexAccess() ); 497 if (! _pParamTypes) 498 { 499 sal_Int32 nParams = getMethodTypeDescr()->nParams; 500 Sequence< Reference< XIdlClass > > * pTempParamTypes = 501 new Sequence< Reference< XIdlClass > >( nParams ); 502 Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); 503 504 typelib_MethodParameter * pTypelibParams = 505 getMethodTypeDescr()->pParams; 506 IdlReflectionServiceImpl * pRefl = getReflection(); 507 508 while (nParams--) 509 pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef ); 510 511 _pParamTypes = pTempParamTypes; 512 } 513 } 514 return *_pParamTypes; 515 } 516 //__________________________________________________________________________________________________ 517 Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos() 518 { 519 if (! _pParamInfos) 520 { 521 MutexGuard aGuard( getMutexAccess() ); 522 if (! _pParamInfos) 523 { 524 sal_Int32 nParams = getMethodTypeDescr()->nParams; 525 Sequence< ParamInfo > * pTempParamInfos = new Sequence< ParamInfo >( nParams ); 526 ParamInfo * pParamInfos = pTempParamInfos->getArray(); 527 528 typelib_MethodParameter * pTypelibParams = 529 getMethodTypeDescr()->pParams; 530 531 if (_pParamTypes) // use param types 532 { 533 const Reference< XIdlClass > * pParamTypes = _pParamTypes->getConstArray(); 534 535 while (nParams--) 536 { 537 const typelib_MethodParameter & rParam = pTypelibParams[nParams]; 538 ParamInfo & rInfo = pParamInfos[nParams]; 539 rInfo.aName = rParam.pName; 540 if (rParam.bIn) 541 rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); 542 else 543 rInfo.aMode = ParamMode_OUT; 544 rInfo.aType = pParamTypes[nParams]; 545 } 546 } 547 else // make also param types sequence if not already initialized 548 { 549 Sequence< Reference< XIdlClass > > * pTempParamTypes = 550 new Sequence< Reference< XIdlClass > >( nParams ); 551 Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); 552 553 IdlReflectionServiceImpl * pRefl = getReflection(); 554 555 while (nParams--) 556 { 557 const typelib_MethodParameter & rParam = pTypelibParams[nParams]; 558 ParamInfo & rInfo = pParamInfos[nParams]; 559 rInfo.aName = rParam.pName; 560 if (rParam.bIn) 561 rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); 562 else 563 rInfo.aMode = ParamMode_OUT; 564 rInfo.aType = pParamTypes[nParams] = pRefl->forType( rParam.pTypeRef ); 565 } 566 567 _pParamTypes = pTempParamTypes; 568 } 569 570 _pParamInfos = pTempParamInfos; 571 } 572 } 573 return *_pParamInfos; 574 } 575 //__________________________________________________________________________________________________ 576 MethodMode SAL_CALL IdlInterfaceMethodImpl::getMode() 577 { 578 return 579 getMethodTypeDescr()->bOneWay ? MethodMode_ONEWAY : MethodMode_TWOWAY; 580 } 581 //__________________________________________________________________________________________________ 582 Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & rArgs ) 583 { 584 if (rObj.getValueTypeClass() == TypeClass_INTERFACE) 585 { 586 // acquire()/ release() 587 if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer, 588 "com.sun.star.uno.XInterface::acquire" ) == 0) 589 { 590 (*(const Reference< XInterface > *)rObj.getValue())->acquire(); 591 return Any(); 592 } 593 else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer, 594 "com.sun.star.uno.XInterface::release" ) == 0) 595 { 596 (*(const Reference< XInterface > *)rObj.getValue())->release(); 597 return Any(); 598 } 599 } 600 601 uno_Interface * pUnoI = getReflection()->mapToUno( 602 rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); 603 OSL_ENSURE( pUnoI, "### illegal destination object given!" ); 604 if (pUnoI) 605 { 606 sal_Int32 nParams = getMethodTypeDescr()->nParams; 607 if (rArgs.getLength() != nParams) 608 { 609 (*pUnoI->release)( pUnoI ); 610 throw IllegalArgumentException( 611 OUString( RTL_CONSTASCII_USTRINGPARAM("arguments len differ!") ), 612 *(const Reference< XInterface > *)rObj.getValue(), 1 ); 613 } 614 615 Any * pCppArgs = rArgs.getArray(); 616 typelib_MethodParameter * pParams = getMethodTypeDescr()->pParams; 617 typelib_TypeDescription * pReturnType = 0; 618 TYPELIB_DANGER_GET( 619 &pReturnType, getMethodTypeDescr()->pReturnTypeRef ); 620 621 void * pUnoReturn = alloca( pReturnType->nSize ); 622 void ** ppUnoArgs = (void **)alloca( sizeof(void *) * nParams *2 ); 623 typelib_TypeDescription ** ppParamTypes = (typelib_TypeDescription **)(ppUnoArgs + nParams); 624 625 // convert arguments 626 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 627 { 628 ppParamTypes[nPos] = 0; 629 TYPELIB_DANGER_GET( ppParamTypes + nPos, pParams[nPos].pTypeRef ); 630 typelib_TypeDescription * pTD = ppParamTypes[nPos]; 631 632 ppUnoArgs[nPos] = alloca( pTD->nSize ); 633 if (pParams[nPos].bIn) 634 { 635 sal_Bool bAssign; 636 if (typelib_typedescriptionreference_equals( 637 pCppArgs[nPos].getValueTypeRef(), pTD->pWeakRef )) 638 { 639 uno_type_copyAndConvertData( 640 ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), 641 pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() ); 642 bAssign = sal_True; 643 } 644 else if (pTD->eTypeClass == typelib_TypeClass_ANY) 645 { 646 uno_type_any_constructAndConvert( 647 (uno_Any *)ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), 648 pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() ); 649 bAssign = sal_True; 650 } 651 else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) 652 { 653 Reference< XInterface > xDest; 654 bAssign = extract( 655 pCppArgs[nPos], (typelib_InterfaceTypeDescription *)pTD, 656 xDest, getReflection() ); 657 if (bAssign) 658 { 659 *(void **)ppUnoArgs[nPos] = getReflection()->getCpp2Uno().mapInterface( 660 xDest.get(), (typelib_InterfaceTypeDescription *)pTD ); 661 } 662 } 663 else 664 { 665 typelib_TypeDescription * pValueTD = 0; 666 TYPELIB_DANGER_GET( &pValueTD, pCppArgs[nPos].getValueTypeRef() ); 667 // construct temp uno val to do proper assignment: todo opt 668 void * pTemp = alloca( pValueTD->nSize ); 669 uno_copyAndConvertData( 670 pTemp, (void *)pCppArgs[nPos].getValue(), pValueTD, 671 getReflection()->getCpp2Uno().get() ); 672 uno_constructData( 673 ppUnoArgs[nPos], pTD ); 674 // assignment does simple conversion 675 bAssign = uno_assignData( 676 ppUnoArgs[nPos], pTD, pTemp, pValueTD, 0, 0, 0 ); 677 uno_destructData( 678 pTemp, pValueTD, 0 ); 679 TYPELIB_DANGER_RELEASE( pValueTD ); 680 } 681 682 if (! bAssign) 683 { 684 IllegalArgumentException aExc( 685 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce argument type during corereflection call!") ), 686 *(const Reference< XInterface > *)rObj.getValue(), (sal_Int16)nPos ); 687 688 // cleanup 689 while (nPos--) 690 { 691 if (pParams[nPos].bIn) 692 uno_destructData( ppUnoArgs[nPos], ppParamTypes[nPos], 0 ); 693 TYPELIB_DANGER_RELEASE( ppParamTypes[nPos] ); 694 } 695 TYPELIB_DANGER_RELEASE( pReturnType ); 696 (*pUnoI->release)( pUnoI ); 697 698 throw aExc; 699 } 700 } 701 } 702 703 uno_Any aUnoExc; 704 uno_Any * pUnoExc = &aUnoExc; 705 706 (*pUnoI->pDispatcher)( 707 pUnoI, getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc ); 708 (*pUnoI->release)( pUnoI ); 709 710 Any aRet; 711 if (pUnoExc) 712 { 713 // cleanup 714 while (nParams--) 715 { 716 if (pParams[nParams].bIn) 717 uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); 718 TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); 719 } 720 TYPELIB_DANGER_RELEASE( pReturnType ); 721 722 InvocationTargetException aExc; 723 aExc.Context = *(const Reference< XInterface > *)rObj.getValue(); 724 aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("exception occurred during invocation!") ); 725 uno_any_destruct( 726 &aExc.TargetException, 727 reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); 728 uno_type_copyAndConvertData( 729 &aExc.TargetException, pUnoExc, ::getCppuType( (const Any *)0 ).getTypeLibType(), 730 getReflection()->getUno2Cpp().get() ); 731 uno_any_destruct( pUnoExc, 0 ); 732 throw aExc; 733 } 734 else 735 { 736 // reconvert arguments and cleanup 737 while (nParams--) 738 { 739 if (pParams[nParams].bOut) // write back 740 { 741 uno_any_destruct( 742 &pCppArgs[nParams], 743 reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); 744 uno_any_constructAndConvert( 745 &pCppArgs[nParams], ppUnoArgs[nParams], ppParamTypes[nParams], 746 getReflection()->getUno2Cpp().get() ); 747 } 748 uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); 749 TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); 750 } 751 uno_any_destruct( 752 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); 753 uno_any_constructAndConvert( 754 &aRet, pUnoReturn, pReturnType, 755 getReflection()->getUno2Cpp().get() ); 756 uno_destructData( pUnoReturn, pReturnType, 0 ); 757 TYPELIB_DANGER_RELEASE( pReturnType ); 758 } 759 return aRet; 760 } 761 throw IllegalArgumentException( 762 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), 763 (XWeak *)(OWeakObject *)this, 0 ); 764 } 765 766 767 //################################################################################################## 768 //################################################################################################## 769 //################################################################################################## 770 771 772 //__________________________________________________________________________________________________ 773 InterfaceIdlClassImpl::~InterfaceIdlClassImpl() 774 { 775 for ( sal_Int32 nPos = _nMethods + _nAttributes; nPos--; ) 776 typelib_typedescription_release( _pSortedMemberInit[nPos].second ); 777 778 delete [] _pSortedMemberInit; 779 } 780 781 //__________________________________________________________________________________________________ 782 Sequence< Reference< XIdlClass > > InterfaceIdlClassImpl::getSuperclasses() 783 { 784 MutexGuard aGuard(getMutexAccess()); 785 if (_xSuperClasses.getLength() == 0) { 786 typelib_InterfaceTypeDescription * pType = getTypeDescr(); 787 _xSuperClasses.realloc(pType->nBaseTypes); 788 for (sal_Int32 i = 0; i < pType->nBaseTypes; ++i) { 789 _xSuperClasses[i] = getReflection()->forType( 790 &pType->ppBaseTypes[i]->aBase); 791 OSL_ASSERT(_xSuperClasses[i].is()); 792 } 793 } 794 return Sequence< Reference< XIdlClass > >(_xSuperClasses); 795 } 796 //__________________________________________________________________________________________________ 797 void InterfaceIdlClassImpl::initMembers() 798 { 799 sal_Int32 nAll = getTypeDescr()->nAllMembers; 800 MemberInit * pSortedMemberInit = new MemberInit[nAll]; 801 typelib_TypeDescriptionReference ** ppAllMembers = getTypeDescr()->ppAllMembers; 802 803 for ( sal_Int32 nPos = 0; nPos < nAll; ++nPos ) 804 { 805 sal_Int32 nIndex; 806 if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) 807 { 808 // methods to front 809 nIndex = _nMethods; 810 ++_nMethods; 811 } 812 else 813 { 814 ++_nAttributes; 815 nIndex = (nAll - _nAttributes); 816 // attributes at the back 817 } 818 819 typelib_TypeDescription * pTD = 0; 820 typelib_typedescriptionreference_getDescription( &pTD, ppAllMembers[nPos] ); 821 OSL_ENSURE( pTD, "### cannot get type description!" ); 822 pSortedMemberInit[nIndex].first = ((typelib_InterfaceMemberTypeDescription *)pTD)->pMemberName; 823 pSortedMemberInit[nIndex].second = pTD; 824 } 825 826 _pSortedMemberInit = pSortedMemberInit; 827 } 828 //__________________________________________________________________________________________________ 829 sal_Bool InterfaceIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) 830 { 831 if (xType.is() && xType->getTypeClass() == TypeClass_INTERFACE) 832 { 833 if (equals( xType )) 834 return sal_True; 835 else 836 { 837 const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses(); 838 for (sal_Int32 i = 0; i < rSeq.getLength(); ++i) { 839 if (isAssignableFrom(rSeq[i])) { 840 return true; 841 } 842 } 843 } 844 } 845 return sal_False; 846 } 847 //__________________________________________________________________________________________________ 848 Uik InterfaceIdlClassImpl::getUik() 849 { 850 return Uik(0, 0, 0, 0, 0); 851 // Uiks are deprecated and this function must not be called 852 } 853 //__________________________________________________________________________________________________ 854 Sequence< Reference< XIdlMethod > > InterfaceIdlClassImpl::getMethods() 855 { 856 MutexGuard aGuard( getMutexAccess() ); 857 if (! _pSortedMemberInit) 858 initMembers(); 859 860 // create methods sequence 861 Sequence< Reference< XIdlMethod > > aRet( _nMethods ); 862 Reference< XIdlMethod > * pRet = aRet.getArray(); 863 for ( sal_Int32 nPos = _nMethods; nPos--; ) 864 { 865 866 /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet[nPos] = new IdlInterfaceMethodImpl( 867 getReflection(), _pSortedMemberInit[nPos].first, 868 _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); 869 } 870 return aRet; 871 } 872 //__________________________________________________________________________________________________ 873 Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields() 874 { 875 MutexGuard aGuard( getMutexAccess() ); 876 if (! _pSortedMemberInit) 877 initMembers(); 878 879 // create fields sequence 880 Sequence< Reference< XIdlField > > aRet( _nAttributes ); 881 Reference< XIdlField > * pRet = aRet.getArray(); 882 for ( sal_Int32 nPos = _nAttributes; nPos--; ) 883 { 884 /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet[_nAttributes-nPos-1] = 885 new IdlAttributeFieldImpl( 886 getReflection(), _pSortedMemberInit[_nMethods+nPos].first, 887 _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); 888 } 889 return aRet; 890 } 891 //__________________________________________________________________________________________________ 892 Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName ) 893 { 894 MutexGuard aGuard( getMutexAccess() ); 895 if (! _pSortedMemberInit) 896 initMembers(); 897 898 Reference< XIdlMethod > xRet; 899 900 // try weak map 901 const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) ); 902 if (iFind != _aName2Method.end()) 903 xRet = (*iFind).second; // harden ref 904 905 if (! xRet.is()) 906 { 907 for ( sal_Int32 nPos = _nMethods; nPos--; ) 908 { 909 if (_pSortedMemberInit[nPos].first == rName) 910 { 911 _aName2Method[rName] = xRet = new IdlInterfaceMethodImpl( 912 getReflection(), rName, 913 _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); 914 break; 915 } 916 } 917 } 918 return xRet; 919 } 920 //__________________________________________________________________________________________________ 921 Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName ) 922 { 923 MutexGuard aGuard( getMutexAccess() ); 924 if (! _pSortedMemberInit) 925 initMembers(); 926 927 Reference< XIdlField > xRet; 928 929 // try weak map 930 const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); 931 if (iFind != _aName2Field.end()) 932 xRet = (*iFind).second; // harden ref 933 934 if (! xRet.is()) 935 { 936 for ( sal_Int32 nPos = _nAttributes; nPos--; ) 937 { 938 if (_pSortedMemberInit[_nMethods+nPos].first == rName) 939 { 940 _aName2Field[rName] = xRet = new IdlAttributeFieldImpl( 941 getReflection(), rName, 942 _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); 943 break; 944 } 945 } 946 } 947 return xRet; 948 } 949 //__________________________________________________________________________________________________ 950 void InterfaceIdlClassImpl::createObject( Any & rObj ) 951 { 952 // interfaces cannot be constructed 953 rObj.clear(); 954 } 955 956 } 957