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 <hash_map> 28 #include <hash_set> 29 30 #include <osl/diagnose.h> 31 #include <osl/interlck.h> 32 #include <osl/mutex.hxx> 33 34 #include <uno/dispatcher.h> 35 #include <uno/data.h> 36 #include <uno/any2.h> 37 #include <uno/mapping.hxx> 38 39 #include <cppuhelper/factory.hxx> 40 #include <cppuhelper/implbase3.hxx> 41 #include <cppuhelper/implementationentry.hxx> 42 43 #include <com/sun/star/uno/XAggregation.hpp> 44 #include <com/sun/star/script/XTypeConverter.hpp> 45 #include <com/sun/star/script/XInvocationAdapterFactory.hpp> 46 #include <com/sun/star/script/XInvocationAdapterFactory2.hpp> 47 #include <com/sun/star/script/XInvocation.hpp> 48 #include <com/sun/star/lang/XServiceInfo.hpp> 49 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 50 #include <com/sun/star/registry/XSimpleRegistry.hpp> 51 #include <com/sun/star/registry/XRegistryKey.hpp> 52 #include <com/sun/star/reflection/InvocationTargetException.hpp> 53 #include "com/sun/star/uno/RuntimeException.hpp" 54 55 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 56 57 #define SERVICENAME "com.sun.star.script.InvocationAdapterFactory" 58 #define IMPLNAME "com.sun.star.comp.stoc.InvocationAdapterFactory" 59 60 61 using namespace ::std; 62 using namespace ::rtl; 63 using namespace ::osl; 64 using namespace ::com::sun::star; 65 using namespace ::com::sun::star::uno; 66 67 namespace stoc_invadp 68 { 69 70 static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 71 72 static Sequence< OUString > invadp_getSupportedServiceNames() 73 { 74 static Sequence < OUString > *pNames = 0; 75 if( ! pNames ) 76 { 77 MutexGuard guard( Mutex::getGlobalMutex() ); 78 if( !pNames ) 79 { 80 static Sequence< OUString > seqNames(1); 81 seqNames.getArray()[0] = 82 OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME)); 83 pNames = &seqNames; 84 } 85 } 86 return *pNames; 87 } 88 89 static OUString invadp_getImplementationName() 90 { 91 static OUString *pImplName = 0; 92 if( ! pImplName ) 93 { 94 MutexGuard guard( Mutex::getGlobalMutex() ); 95 if( ! pImplName ) 96 { 97 static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); 98 pImplName = &implName; 99 } 100 } 101 return *pImplName; 102 } 103 104 struct hash_ptr 105 { 106 inline size_t operator() ( void * p ) const 107 { return (size_t)p; } 108 }; 109 typedef hash_set< void *, hash_ptr, equal_to< void * > > t_ptr_set; 110 typedef hash_map< void *, t_ptr_set, hash_ptr, equal_to< void * > > t_ptr_map; 111 112 //============================================================================== 113 class FactoryImpl 114 : public ::cppu::WeakImplHelper3< lang::XServiceInfo, 115 script::XInvocationAdapterFactory, 116 script::XInvocationAdapterFactory2 > 117 { 118 public: 119 Mapping m_aUno2Cpp; 120 Mapping m_aCpp2Uno; 121 uno_Interface * m_pConverter; 122 123 typelib_TypeDescription * m_pInvokMethodTD; 124 typelib_TypeDescription * m_pSetValueTD; 125 typelib_TypeDescription * m_pGetValueTD; 126 typelib_TypeDescription * m_pAnySeqTD; 127 typelib_TypeDescription * m_pShortSeqTD; 128 typelib_TypeDescription * m_pConvertToTD; 129 130 Mutex m_mutex; 131 t_ptr_map m_receiver2adapters; 132 133 FactoryImpl( Reference< XComponentContext > const & xContext ) 134 SAL_THROW( (RuntimeException) ); 135 virtual ~FactoryImpl() SAL_THROW( () ); 136 137 // XServiceInfo 138 virtual OUString SAL_CALL getImplementationName() 139 throw (RuntimeException); 140 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) 141 throw (RuntimeException); 142 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() 143 throw (RuntimeException); 144 145 // XInvocationAdapterFactory 146 virtual Reference< XInterface > SAL_CALL createAdapter( 147 const Reference< script::XInvocation > & xReceiver, const Type & rType ) 148 throw (RuntimeException); 149 // XInvocationAdapterFactory2 150 virtual Reference< XInterface > SAL_CALL createAdapter( 151 const Reference< script::XInvocation > & xReceiver, 152 const Sequence< Type > & rTypes ) 153 throw (RuntimeException); 154 }; 155 struct AdapterImpl; 156 //============================================================================== 157 struct InterfaceAdapterImpl : public uno_Interface 158 { 159 AdapterImpl * m_pAdapter; 160 typelib_InterfaceTypeDescription * m_pTypeDescr; 161 }; 162 //============================================================================== 163 struct AdapterImpl 164 { 165 oslInterlockedCount m_nRef; 166 FactoryImpl * m_pFactory; 167 void * m_key; // map key 168 uno_Interface * m_pReceiver; // XInvocation receiver 169 170 sal_Int32 m_nInterfaces; 171 InterfaceAdapterImpl * m_pInterfaces; 172 173 // XInvocation calls 174 void getValue( 175 const typelib_TypeDescription * pMemberType, 176 void * pReturn, void * pArgs[], uno_Any ** ppException ); 177 void setValue( 178 const typelib_TypeDescription * pMemberType, 179 void * pReturn, void * pArgs[], uno_Any ** ppException ); 180 void invoke( 181 const typelib_TypeDescription * pMemberType, 182 void * pReturn, void * pArgs[], uno_Any ** ppException ); 183 184 bool coerce_assign( 185 void * pDest, typelib_TypeDescriptionReference * pType, 186 uno_Any * pSource, uno_Any * pExc ); 187 inline bool coerce_construct( 188 void * pDest, typelib_TypeDescriptionReference * pType, 189 uno_Any * pSource, uno_Any * pExc ); 190 191 inline void acquire() 192 SAL_THROW( () ); 193 inline void release() 194 SAL_THROW( () ); 195 inline ~AdapterImpl() 196 SAL_THROW( () ); 197 inline AdapterImpl( 198 void * key, Reference< script::XInvocation > const & xReceiver, 199 const Sequence< Type > & rTypes, 200 FactoryImpl * pFactory ) 201 SAL_THROW( (RuntimeException) ); 202 }; 203 //______________________________________________________________________________ 204 inline AdapterImpl::~AdapterImpl() 205 SAL_THROW( () ) 206 { 207 for ( sal_Int32 nPos = m_nInterfaces; nPos--; ) 208 { 209 ::typelib_typedescription_release( 210 (typelib_TypeDescription *)m_pInterfaces[ nPos ].m_pTypeDescr ); 211 } 212 delete [] m_pInterfaces; 213 // 214 (*m_pReceiver->release)( m_pReceiver ); 215 m_pFactory->release(); 216 } 217 //______________________________________________________________________________ 218 inline void AdapterImpl::acquire() 219 SAL_THROW( () ) 220 { 221 ::osl_incrementInterlockedCount( &m_nRef ); 222 } 223 //______________________________________________________________________________ 224 inline void AdapterImpl::release() 225 SAL_THROW( () ) 226 { 227 bool delete_this = false; 228 { 229 MutexGuard guard( m_pFactory->m_mutex ); 230 if (! ::osl_decrementInterlockedCount( &m_nRef )) 231 { 232 t_ptr_map::iterator iFind( 233 m_pFactory->m_receiver2adapters.find( m_key ) ); 234 OSL_ASSERT( m_pFactory->m_receiver2adapters.end() != iFind ); 235 t_ptr_set & adapter_set = iFind->second; 236 if (adapter_set.erase( this ) != 1) { 237 OSL_ASSERT( false ); 238 } 239 if (adapter_set.empty()) 240 { 241 m_pFactory->m_receiver2adapters.erase( iFind ); 242 } 243 delete_this = true; 244 } 245 } 246 if (delete_this) 247 delete this; 248 } 249 250 //------------------------------------------------------------------------------ 251 static inline void constructRuntimeException( 252 uno_Any * pExc, const OUString & rMsg ) 253 { 254 RuntimeException exc( rMsg, Reference< XInterface >() ); 255 // no conversion neeeded due to binary compatibility + no convertable type 256 ::uno_type_any_construct( 257 pExc, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 ); 258 } 259 260 //------------------------------------------------------------------------------ 261 static inline sal_Bool type_equals( 262 typelib_TypeDescriptionReference * pType1, 263 typelib_TypeDescriptionReference * pType2 ) 264 SAL_THROW( () ) 265 { 266 return (pType1 == pType2 || 267 (pType1->pTypeName->length == pType2->pTypeName->length && 268 0 == ::rtl_ustr_compare( 269 pType1->pTypeName->buffer, pType2->pTypeName->buffer ))); 270 } 271 272 //______________________________________________________________________________ 273 bool AdapterImpl::coerce_assign( 274 void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource, 275 uno_Any * pOutExc ) 276 { 277 if (typelib_TypeClass_ANY == pType->eTypeClass) 278 { 279 ::uno_type_any_assign( 280 (uno_Any *)pDest, pSource->pData, pSource->pType, 0, 0 ); 281 return true; 282 } 283 if (::uno_type_assignData( 284 pDest, pType, pSource->pData, pSource->pType, 0, 0, 0 )) 285 { 286 return true; 287 } 288 else // try type converter 289 { 290 uno_Any ret; 291 void * args[ 2 ]; 292 args[ 0 ] = pSource; 293 args[ 1 ] = &pType; 294 uno_Any exc; 295 uno_Any * p_exc = &exc; 296 297 // converTo() 298 (*m_pFactory->m_pConverter->pDispatcher)( 299 m_pFactory->m_pConverter, 300 m_pFactory->m_pConvertToTD, &ret, args, &p_exc ); 301 302 if (p_exc) // exception occured 303 { 304 OSL_ASSERT( 305 p_exc->pType->eTypeClass == typelib_TypeClass_EXCEPTION ); 306 if (typelib_typedescriptionreference_isAssignableFrom( 307 ::getCppuType( 308 (RuntimeException const *) 0 ).getTypeLibType(), 309 p_exc->pType )) 310 { 311 // is RuntimeException or derived: rethrow 312 uno_type_any_construct( 313 pOutExc, p_exc->pData, p_exc->pType, 0 ); 314 } 315 else 316 { 317 // set runtime exception 318 constructRuntimeException( 319 pOutExc, OUSTR("type coercion failed: ") + 320 reinterpret_cast< Exception const * >( 321 p_exc->pData )->Message ); 322 } 323 ::uno_any_destruct( p_exc, 0 ); 324 // pOutExc constructed 325 return false; 326 } 327 else 328 { 329 bool succ = (sal_False != ::uno_type_assignData( 330 pDest, pType, ret.pData, ret.pType, 0, 0, 0 )); 331 ::uno_any_destruct( &ret, 0 ); 332 OSL_ENSURE( 333 succ, "### conversion succeeded, but assignment failed!?" ); 334 if (! succ) 335 { 336 // set runtime exception 337 constructRuntimeException( 338 pOutExc, 339 OUSTR("type coercion failed: " 340 "conversion succeeded, but assignment failed?!") ); 341 } 342 return succ; 343 } 344 } 345 } 346 //______________________________________________________________________________ 347 inline bool AdapterImpl::coerce_construct( 348 void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource, 349 uno_Any * pExc ) 350 { 351 if (typelib_TypeClass_ANY == pType->eTypeClass) 352 { 353 ::uno_type_copyData( pDest, pSource, pType, 0 ); 354 return true; 355 } 356 if (type_equals( pType, pSource->pType)) 357 { 358 ::uno_type_copyData( pDest, pSource->pData, pType, 0 ); 359 return true; 360 } 361 ::uno_type_constructData( pDest, pType ); 362 return coerce_assign( pDest, pType, pSource, pExc ); 363 } 364 365 //------------------------------------------------------------------------------ 366 static void handleInvokExc( uno_Any * pDest, uno_Any * pSource ) 367 { 368 OUString const & name = 369 *reinterpret_cast< OUString const * >( &pSource->pType->pTypeName ); 370 371 if (name.equalsAsciiL( 372 RTL_CONSTASCII_STRINGPARAM( 373 "com.sun.star.reflection.InvocationTargetException") )) 374 { 375 // unwrap invocation target exception 376 uno_Any * target_exc = 377 &reinterpret_cast< reflection::InvocationTargetException * >( 378 pSource->pData )->TargetException; 379 ::uno_type_any_construct( 380 pDest, target_exc->pData, target_exc->pType, 0 ); 381 } 382 else // all other exceptions are wrapped to RuntimeException 383 { 384 if (typelib_TypeClass_EXCEPTION == pSource->pType->eTypeClass) 385 { 386 constructRuntimeException( 387 pDest, ((Exception const *)pSource->pData)->Message ); 388 } 389 else 390 { 391 constructRuntimeException( 392 pDest, OUSTR("no exception has been thrown via invocation?!") ); 393 } 394 } 395 } 396 //______________________________________________________________________________ 397 void AdapterImpl::getValue( 398 const typelib_TypeDescription * pMemberType, 399 void * pReturn, void * [], uno_Any ** ppException ) 400 { 401 uno_Any aInvokRet; 402 void * pInvokArgs[1]; 403 pInvokArgs[0] = 404 &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; 405 uno_Any aInvokExc; 406 uno_Any * pInvokExc = &aInvokExc; 407 408 // getValue() 409 (*m_pReceiver->pDispatcher)( 410 m_pReceiver, m_pFactory->m_pGetValueTD, 411 &aInvokRet, pInvokArgs, &pInvokExc ); 412 413 if (pInvokExc) // getValue() call exception 414 { 415 handleInvokExc( *ppException, pInvokExc ); 416 ::uno_any_destruct( pInvokExc, 0 ); // cleanup 417 } 418 else // invocation call succeeded 419 { 420 if (coerce_construct( 421 pReturn, 422 ((typelib_InterfaceAttributeTypeDescription *) 423 pMemberType)->pAttributeTypeRef, 424 &aInvokRet, *ppException )) 425 { 426 *ppException = 0; // no exceptions be thrown 427 } 428 ::uno_any_destruct( &aInvokRet, 0 ); 429 } 430 } 431 //______________________________________________________________________________ 432 void AdapterImpl::setValue( 433 const typelib_TypeDescription * pMemberType, 434 void *, void * pArgs[], uno_Any ** ppException ) 435 { 436 uno_Any aInvokVal; 437 ::uno_type_any_construct( 438 &aInvokVal, pArgs[0], 439 ((typelib_InterfaceAttributeTypeDescription *) 440 pMemberType)->pAttributeTypeRef, 0 ); 441 442 void * pInvokArgs[2]; 443 pInvokArgs[0] = 444 &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; 445 pInvokArgs[1] = &aInvokVal; 446 uno_Any aInvokExc; 447 uno_Any * pInvokExc = &aInvokExc; 448 449 // setValue() 450 (*m_pReceiver->pDispatcher)( 451 m_pReceiver, m_pFactory->m_pSetValueTD, 0, pInvokArgs, &pInvokExc ); 452 453 if (pInvokExc) // setValue() call exception 454 { 455 handleInvokExc( *ppException, pInvokExc ); 456 ::uno_any_destruct( pInvokExc, 0 ); // cleanup 457 } 458 else // invocation call succeeded 459 { 460 *ppException = 0; // no exceptions be thrown 461 } 462 463 ::uno_any_destruct( &aInvokVal, 0 ); // cleanup 464 } 465 //______________________________________________________________________________ 466 void AdapterImpl::invoke( 467 const typelib_TypeDescription * pMemberType, 468 void * pReturn, void * pArgs[], uno_Any ** ppException ) 469 { 470 sal_Int32 nParams = 471 ((typelib_InterfaceMethodTypeDescription *)pMemberType)->nParams; 472 typelib_MethodParameter * pFormalParams = 473 ((typelib_InterfaceMethodTypeDescription *)pMemberType)->pParams; 474 475 // in params 476 uno_Sequence * pInParamsSeq = 0; 477 ::uno_sequence_construct( 478 &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0, nParams, 0 ); 479 uno_Any * pInAnys = (uno_Any *)pInParamsSeq->elements; 480 sal_Int32 nOutParams = 0; 481 sal_Int32 nPos; 482 for ( nPos = nParams; nPos--; ) 483 { 484 typelib_MethodParameter const & rParam = pFormalParams[nPos]; 485 if (rParam.bIn) // is in/inout param 486 { 487 ::uno_type_any_assign( 488 &pInAnys[nPos], pArgs[nPos], rParam.pTypeRef, 0, 0 ); 489 } 490 // else: pure out is empty any 491 492 if (rParam.bOut) 493 ++nOutParams; 494 } 495 496 // out params, out indices 497 uno_Sequence * pOutIndices; 498 uno_Sequence * pOutParams; 499 // return value 500 uno_Any aInvokRet; 501 // perform call 502 void * pInvokArgs[4]; 503 pInvokArgs[0] = 504 &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; 505 pInvokArgs[1] = &pInParamsSeq; 506 pInvokArgs[2] = &pOutIndices; 507 pInvokArgs[3] = &pOutParams; 508 uno_Any aInvokExc; 509 uno_Any * pInvokExc = &aInvokExc; 510 511 // invoke() call 512 (*m_pReceiver->pDispatcher)( 513 m_pReceiver, m_pFactory->m_pInvokMethodTD, 514 &aInvokRet, pInvokArgs, &pInvokExc ); 515 516 if (pInvokExc) 517 { 518 handleInvokExc( *ppException, pInvokExc ); 519 ::uno_any_destruct( pInvokExc, 0 ); // cleanup 520 } 521 else // no invocation exception 522 { 523 // write changed out params 524 OSL_ENSURE( 525 pOutParams->nElements == nOutParams && 526 pOutIndices->nElements == nOutParams, 527 "### out params lens differ!" ); 528 if (pOutParams->nElements == nOutParams && 529 pOutIndices->nElements == nOutParams) 530 { 531 sal_Int16 * pIndices = (sal_Int16 *)pOutIndices->elements; 532 uno_Any * pOut = (uno_Any *)pOutParams->elements; 533 for ( nPos = 0; nPos < nOutParams; ++nPos ) 534 { 535 sal_Int32 nIndex = pIndices[nPos]; 536 OSL_ENSURE( nIndex < nParams, "### illegal index!" ); 537 typelib_MethodParameter const & rParam = pFormalParams[nIndex]; 538 bool succ; 539 if (rParam.bIn) // is in/inout param 540 { 541 succ = coerce_assign( 542 pArgs[nIndex], rParam.pTypeRef, &pOut[nPos], 543 *ppException ); 544 } 545 else // pure out 546 { 547 succ = coerce_construct( 548 pArgs[nIndex], rParam.pTypeRef, &pOut[nPos], 549 *ppException ); 550 } 551 if (! succ) // cleanup of out params 552 { 553 for ( sal_Int32 n = 0; n <= nPos; ++n ) 554 { 555 sal_Int32 nIndex2 = pIndices[n]; 556 OSL_ENSURE( nIndex2 < nParams, "### illegal index!" ); 557 typelib_MethodParameter const & rParam2 = 558 pFormalParams[nIndex2]; 559 if (! rParam2.bIn) // is pure out param 560 { 561 ::uno_type_destructData( 562 pArgs[nIndex2], rParam2.pTypeRef, 0 ); 563 } 564 } 565 } 566 } 567 if (nPos == pOutIndices->nElements) 568 { 569 // out param copy ok; write return value 570 if (coerce_construct( 571 pReturn, 572 ((typelib_InterfaceMethodTypeDescription *) 573 pMemberType)->pReturnTypeRef, 574 &aInvokRet, *ppException )) 575 { 576 *ppException = 0; // no exception 577 } 578 } 579 } 580 else 581 { 582 // set runtime exception 583 constructRuntimeException( 584 *ppException, 585 OUSTR("out params lengths differ after invocation call!") ); 586 } 587 // cleanup invok out params 588 ::uno_destructData( &pOutIndices, m_pFactory->m_pShortSeqTD, 0 ); 589 ::uno_destructData( &pOutParams, m_pFactory->m_pAnySeqTD, 0 ); 590 // cleanup invok return value 591 ::uno_any_destruct( &aInvokRet, 0 ); 592 } 593 // cleanup constructed in params 594 ::uno_destructData( &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0 ); 595 } 596 597 extern "C" 598 { 599 //______________________________________________________________________________ 600 static void SAL_CALL adapter_acquire( uno_Interface * pUnoI ) 601 { 602 static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->acquire(); 603 } 604 //______________________________________________________________________________ 605 static void SAL_CALL adapter_release( uno_Interface * pUnoI ) 606 { 607 static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->release(); 608 } 609 //______________________________________________________________________________ 610 static void SAL_CALL adapter_dispatch( 611 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType, 612 void * pReturn, void * pArgs[], uno_Any ** ppException ) 613 { 614 // query to emulated interface 615 switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition) 616 { 617 case 0: // queryInterface() 618 { 619 AdapterImpl * that = 620 static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter; 621 *ppException = 0; // no exc 622 typelib_TypeDescriptionReference * pDemanded = 623 *(typelib_TypeDescriptionReference **)pArgs[0]; 624 // pInterfaces[0] is XInterface 625 for ( sal_Int32 nPos = 0; nPos < that->m_nInterfaces; ++nPos ) 626 { 627 typelib_InterfaceTypeDescription * pTD = 628 that->m_pInterfaces[nPos].m_pTypeDescr; 629 while (pTD) 630 { 631 if (type_equals( 632 ((typelib_TypeDescription *)pTD)->pWeakRef, pDemanded )) 633 { 634 uno_Interface * pUnoI2 = &that->m_pInterfaces[nPos]; 635 ::uno_any_construct( 636 (uno_Any *)pReturn, &pUnoI2, 637 (typelib_TypeDescription *)pTD, 0 ); 638 return; 639 } 640 pTD = pTD->pBaseTypeDescription; 641 } 642 } 643 ::uno_any_construct( (uno_Any *)pReturn, 0, 0, 0 ); // clear() 644 break; 645 } 646 case 1: // acquire() 647 *ppException = 0; // no exc 648 adapter_acquire( pUnoI ); 649 break; 650 case 2: // release() 651 *ppException = 0; // no exc 652 adapter_release( pUnoI ); 653 break; 654 655 default: 656 { 657 AdapterImpl * that = 658 static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter; 659 if (pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) 660 { 661 that->invoke( pMemberType, pReturn, pArgs, ppException ); 662 } 663 else // attribute 664 { 665 if (pReturn) 666 that->getValue( pMemberType, pReturn, pArgs, ppException ); 667 else 668 that->setValue( pMemberType, pReturn, pArgs, ppException ); 669 } 670 } 671 } 672 } 673 } 674 //______________________________________________________________________________ 675 AdapterImpl::AdapterImpl( 676 void * key, Reference< script::XInvocation > const & xReceiver, 677 const Sequence< Type > & rTypes, 678 FactoryImpl * pFactory ) 679 SAL_THROW( (RuntimeException) ) 680 : m_nRef( 1 ), 681 m_pFactory( pFactory ), 682 m_key( key ) 683 { 684 // init adapters 685 m_nInterfaces = rTypes.getLength(); 686 m_pInterfaces = new InterfaceAdapterImpl[ rTypes.getLength() ]; 687 const Type * pTypes = rTypes.getConstArray(); 688 for ( sal_Int32 nPos = rTypes.getLength(); nPos--; ) 689 { 690 InterfaceAdapterImpl * pInterface = &m_pInterfaces[nPos]; 691 pInterface->acquire = adapter_acquire; 692 pInterface->release = adapter_release; 693 pInterface->pDispatcher = adapter_dispatch; 694 pInterface->m_pAdapter = this; 695 pInterface->m_pTypeDescr = 0; 696 pTypes[nPos].getDescription( 697 (typelib_TypeDescription **)&pInterface->m_pTypeDescr ); 698 OSL_ASSERT( pInterface->m_pTypeDescr ); 699 if (! pInterface->m_pTypeDescr) 700 { 701 for ( sal_Int32 n = 0; n < nPos; ++n ) 702 { 703 ::typelib_typedescription_release( 704 (typelib_TypeDescription *) 705 m_pInterfaces[ n ].m_pTypeDescr ); 706 } 707 delete [] m_pInterfaces; 708 throw RuntimeException( 709 OUSTR("cannot retrieve all interface type infos!"), 710 Reference< XInterface >() ); 711 } 712 } 713 714 // map receiver 715 m_pReceiver = (uno_Interface *)m_pFactory->m_aCpp2Uno.mapInterface( 716 xReceiver.get(), ::getCppuType( &xReceiver ) ); 717 OSL_ASSERT( 0 != m_pReceiver ); 718 if (! m_pReceiver) 719 { 720 throw RuntimeException( 721 OUSTR("cannot map receiver!"), Reference< XInterface >() ); 722 } 723 724 m_pFactory->acquire(); 725 } 726 727 //______________________________________________________________________________ 728 FactoryImpl::FactoryImpl( Reference< XComponentContext > const & xContext ) 729 SAL_THROW( (RuntimeException) ) 730 : m_pInvokMethodTD( 0 ), 731 m_pSetValueTD( 0 ), 732 m_pGetValueTD( 0 ), 733 m_pAnySeqTD( 0 ), 734 m_pShortSeqTD( 0 ), 735 m_pConvertToTD( 0 ) 736 { 737 // C++/UNO bridge 738 OUString aCppEnvTypeName = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME); 739 OUString aUnoEnvTypeName = OUSTR(UNO_LB_UNO); 740 m_aUno2Cpp = Mapping( aUnoEnvTypeName, aCppEnvTypeName ); 741 m_aCpp2Uno = Mapping( aCppEnvTypeName, aUnoEnvTypeName ); 742 OSL_ENSURE( 743 m_aUno2Cpp.is() && m_aCpp2Uno.is(), "### no uno / C++ mappings!" ); 744 745 // type converter 746 Reference< script::XTypeConverter > xConverter( 747 xContext->getServiceManager()->createInstanceWithContext( 748 OUString( 749 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter") ), 750 xContext ), 751 UNO_QUERY_THROW ); 752 m_pConverter = (uno_Interface *)m_aCpp2Uno.mapInterface( 753 xConverter.get(), ::getCppuType( &xConverter ) ); 754 OSL_ASSERT( 0 != m_pConverter ); 755 756 // some type info: 757 // sequence< any > 758 Type const & rAnySeqType = ::getCppuType( (const Sequence< Any > *)0 ); 759 rAnySeqType.getDescription( &m_pAnySeqTD ); 760 // sequence< short > 761 const Type & rShortSeqType = 762 ::getCppuType( (const Sequence< sal_Int16 > *)0 ); 763 rShortSeqType.getDescription( &m_pShortSeqTD ); 764 // script.XInvocation 765 typelib_TypeDescription * pTD = 0; 766 const Type & rInvType = ::getCppuType( 767 (const Reference< script::XInvocation > *)0 ); 768 TYPELIB_DANGER_GET( &pTD, rInvType.getTypeLibType() ); 769 typelib_InterfaceTypeDescription * pITD; 770 pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD); 771 if( ! pITD->aBase.bComplete ) 772 typelib_typedescription_complete( &pTD ); 773 ::typelib_typedescriptionreference_getDescription( 774 &m_pInvokMethodTD, pITD->ppMembers[ 1 ] ); // invoke() 775 ::typelib_typedescriptionreference_getDescription( 776 &m_pSetValueTD, pITD->ppMembers[ 2 ] ); // setValue() 777 ::typelib_typedescriptionreference_getDescription( 778 &m_pGetValueTD, pITD->ppMembers[ 3 ] ); // getValue() 779 // script.XTypeConverter 780 const Type & rTCType = 781 ::getCppuType( (const Reference< script::XTypeConverter > *)0 ); 782 TYPELIB_DANGER_GET( &pTD, rTCType.getTypeLibType() ); 783 pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD); 784 ::typelib_typedescriptionreference_getDescription( 785 &m_pConvertToTD, pITD->ppMembers[ 0 ] ); // convertTo() 786 TYPELIB_DANGER_RELEASE( pTD ); 787 788 if (!m_pInvokMethodTD || !m_pSetValueTD || !m_pGetValueTD || 789 !m_pConvertToTD || 790 !m_pAnySeqTD || !m_pShortSeqTD) 791 { 792 throw RuntimeException( 793 OUSTR("missing type descriptions!"), Reference< XInterface >() ); 794 } 795 796 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 797 } 798 //______________________________________________________________________________ 799 FactoryImpl::~FactoryImpl() SAL_THROW( () ) 800 { 801 ::typelib_typedescription_release( m_pInvokMethodTD ); 802 ::typelib_typedescription_release( m_pSetValueTD ); 803 ::typelib_typedescription_release( m_pGetValueTD ); 804 ::typelib_typedescription_release( m_pAnySeqTD ); 805 ::typelib_typedescription_release( m_pShortSeqTD ); 806 ::typelib_typedescription_release( m_pConvertToTD ); 807 808 (*m_pConverter->release)( m_pConverter ); 809 810 #if OSL_DEBUG_LEVEL > 1 811 OSL_ENSURE( m_receiver2adapters.empty(), "### still adapters out there!?" ); 812 #endif 813 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 814 } 815 816 //------------------------------------------------------------------------------ 817 static inline AdapterImpl * lookup_adapter( 818 t_ptr_set ** pp_adapter_set, 819 t_ptr_map & map, void * key, Sequence< Type > const & rTypes ) 820 SAL_THROW( () ) 821 { 822 t_ptr_set & adapters_set = map[ key ]; 823 *pp_adapter_set = &adapters_set; 824 if (adapters_set.empty()) 825 return 0; // shortcut 826 // find matching adapter 827 Type const * pTypes = rTypes.getConstArray(); 828 sal_Int32 nTypes = rTypes.getLength(); 829 t_ptr_set::const_iterator iPos( adapters_set.begin() ); 830 t_ptr_set::const_iterator const iEnd( adapters_set.end() ); 831 while (iEnd != iPos) 832 { 833 AdapterImpl * that = reinterpret_cast< AdapterImpl * >( *iPos ); 834 // iterate thru all types if that is a matching adapter 835 sal_Int32 nPosTypes; 836 for ( nPosTypes = nTypes; nPosTypes--; ) 837 { 838 Type const & rType = pTypes[ nPosTypes ]; 839 // find in adapter's type list 840 sal_Int32 nPos; 841 for ( nPos = that->m_nInterfaces; nPos--; ) 842 { 843 if (::typelib_typedescriptionreference_isAssignableFrom( 844 rType.getTypeLibType(), 845 ((typelib_TypeDescription *)that-> 846 m_pInterfaces[ nPos ].m_pTypeDescr)->pWeakRef )) 847 { 848 // found 849 break; 850 } 851 } 852 if (nPos < 0) // type not found => next adapter 853 break; 854 } 855 if (nPosTypes < 0) // all types found 856 return that; 857 ++iPos; 858 } 859 return 0; 860 } 861 862 // XInvocationAdapterFactory2 impl 863 //______________________________________________________________________________ 864 Reference< XInterface > FactoryImpl::createAdapter( 865 const Reference< script::XInvocation > & xReceiver, 866 const Sequence< Type > & rTypes ) 867 throw (RuntimeException) 868 { 869 Reference< XInterface > xRet; 870 if (xReceiver.is() && rTypes.getLength()) 871 { 872 t_ptr_set * adapter_set; 873 AdapterImpl * that; 874 Reference< XInterface > xKey( xReceiver, UNO_QUERY ); 875 { 876 ClearableMutexGuard guard( m_mutex ); 877 that = lookup_adapter( 878 &adapter_set, m_receiver2adapters, xKey.get(), rTypes ); 879 if (0 == that) // no entry 880 { 881 guard.clear(); 882 // create adapter; already acquired: m_nRef == 1 883 AdapterImpl * pNew = 884 new AdapterImpl( xKey.get(), xReceiver, rTypes, this ); 885 // lookup again 886 ClearableMutexGuard guard2( m_mutex ); 887 that = lookup_adapter( 888 &adapter_set, m_receiver2adapters, xKey.get(), rTypes ); 889 if (0 == that) // again no entry 890 { 891 pair< t_ptr_set::iterator, bool > insertion( 892 adapter_set->insert( pNew ) ); 893 OSL_ASSERT( insertion.second ); 894 that = pNew; 895 } 896 else 897 { 898 that->acquire(); 899 guard2.clear(); 900 delete pNew; // has never been inserted 901 } 902 } 903 else // found adapter 904 { 905 that->acquire(); 906 } 907 } 908 // map one interface to C++ 909 uno_Interface * pUnoI = &that->m_pInterfaces[ 0 ]; 910 m_aUno2Cpp.mapInterface( 911 (void **)&xRet, pUnoI, ::getCppuType( &xRet ) ); 912 that->release(); 913 OSL_ASSERT( xRet.is() ); 914 if (! xRet.is()) 915 { 916 throw RuntimeException( 917 OUSTR("mapping UNO to C++ failed!"), 918 Reference< XInterface >() ); 919 } 920 } 921 return xRet; 922 } 923 // XInvocationAdapterFactory impl 924 //______________________________________________________________________________ 925 Reference< XInterface > FactoryImpl::createAdapter( 926 const Reference< script::XInvocation > & xReceiver, const Type & rType ) 927 throw (RuntimeException) 928 { 929 return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) ); 930 } 931 932 // XServiceInfo 933 //______________________________________________________________________________ 934 OUString FactoryImpl::getImplementationName() 935 throw (RuntimeException) 936 { 937 return invadp_getImplementationName(); 938 } 939 //______________________________________________________________________________ 940 sal_Bool FactoryImpl::supportsService( const OUString & rServiceName ) 941 throw (RuntimeException) 942 { 943 const Sequence< OUString > & rSNL = getSupportedServiceNames(); 944 const OUString * pArray = rSNL.getConstArray(); 945 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) 946 { 947 if (pArray[nPos].equals( rServiceName )) 948 return sal_True; 949 } 950 return sal_False; 951 } 952 //______________________________________________________________________________ 953 Sequence< OUString > FactoryImpl::getSupportedServiceNames() 954 throw (RuntimeException) 955 { 956 return invadp_getSupportedServiceNames(); 957 } 958 959 //============================================================================== 960 static Reference< XInterface > SAL_CALL FactoryImpl_create( 961 const Reference< XComponentContext > & xContext ) 962 throw (Exception) 963 { 964 Reference< XInterface > rRet; 965 { 966 MutexGuard guard( Mutex::getGlobalMutex() ); 967 static WeakReference < XInterface > rwInstance; 968 rRet = rwInstance; 969 970 if( ! rRet.is() ) 971 { 972 rRet = (::cppu::OWeakObject *)new FactoryImpl( xContext ); 973 rwInstance = rRet; 974 } 975 } 976 return rRet; 977 } 978 979 } 980 981 982 //############################################################################## 983 //############################################################################## 984 //############################################################################## 985 986 static struct ::cppu::ImplementationEntry g_entries[] = 987 { 988 { 989 ::stoc_invadp::FactoryImpl_create, 990 ::stoc_invadp::invadp_getImplementationName, 991 ::stoc_invadp::invadp_getSupportedServiceNames, 992 ::cppu::createSingleComponentFactory, 993 &::stoc_invadp::g_moduleCount.modCnt , 0 994 }, 995 { 0, 0, 0, 0, 0, 0 } 996 }; 997 998 extern "C" 999 { 1000 sal_Bool SAL_CALL component_canUnload( 1001 TimeValue *pTime ) 1002 { 1003 return ::stoc_invadp::g_moduleCount.canUnload( 1004 &::stoc_invadp::g_moduleCount, pTime ); 1005 } 1006 1007 //============================================================================== 1008 void SAL_CALL component_getImplementationEnvironment( 1009 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 1010 { 1011 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 1012 } 1013 1014 //============================================================================== 1015 void * SAL_CALL component_getFactory( 1016 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) 1017 { 1018 return ::cppu::component_getFactoryHelper( 1019 pImplName, pServiceManager, pRegistryKey , g_entries ); 1020 } 1021 } 1022