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