1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <boost/unordered_map.hpp>
22 #include <boost/unordered_set.hpp>
24 #include <osl/diagnose.h>
25 #include <osl/interlck.h>
26 #include <osl/mutex.hxx>
28 #include <uno/dispatcher.h>
31 #include <uno/mapping.hxx>
33 #include <cppuhelper/factory.hxx>
34 #include <cppuhelper/implbase3.hxx>
35 #include <cppuhelper/implementationentry.hxx>
37 #include <com/sun/star/uno/XAggregation.hpp>
38 #include <com/sun/star/script/XTypeConverter.hpp>
39 #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
40 #include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
41 #include <com/sun/star/script/XInvocation.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 #include <com/sun/star/registry/XSimpleRegistry.hpp>
45 #include <com/sun/star/registry/XRegistryKey.hpp>
46 #include <com/sun/star/reflection/InvocationTargetException.hpp>
47 #include "com/sun/star/uno/RuntimeException.hpp"
49 #define SERVICENAME "com.sun.star.script.InvocationAdapterFactory"
50 #define IMPLNAME "com.sun.star.comp.stoc.InvocationAdapterFactory"
53 using namespace ::std
;
54 using namespace ::rtl
;
55 using namespace ::osl
;
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::uno
;
62 static Sequence
< OUString
> invadp_getSupportedServiceNames()
64 Sequence
< OUString
> seqNames(1);
65 seqNames
.getArray()[0] =
66 OUString(SERVICENAME
);
70 static OUString
invadp_getImplementationName()
72 return OUString(IMPLNAME
);
77 inline size_t operator() ( void * p
) const
80 typedef boost::unordered_set
< void *, hash_ptr
, equal_to
< void * > > t_ptr_set
;
81 typedef boost::unordered_map
< void *, t_ptr_set
, hash_ptr
, equal_to
< void * > > t_ptr_map
;
83 //==============================================================================
85 : public ::cppu::WeakImplHelper3
< lang::XServiceInfo
,
86 script::XInvocationAdapterFactory
,
87 script::XInvocationAdapterFactory2
>
92 uno_Interface
* m_pConverter
;
94 typelib_TypeDescription
* m_pInvokMethodTD
;
95 typelib_TypeDescription
* m_pSetValueTD
;
96 typelib_TypeDescription
* m_pGetValueTD
;
97 typelib_TypeDescription
* m_pAnySeqTD
;
98 typelib_TypeDescription
* m_pShortSeqTD
;
99 typelib_TypeDescription
* m_pConvertToTD
;
102 t_ptr_map m_receiver2adapters
;
104 FactoryImpl( Reference
< XComponentContext
> const & xContext
)
105 SAL_THROW( (RuntimeException
) );
106 virtual ~FactoryImpl() SAL_THROW(());
109 virtual OUString SAL_CALL
getImplementationName()
110 throw (RuntimeException
);
111 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
)
112 throw (RuntimeException
);
113 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames()
114 throw (RuntimeException
);
116 // XInvocationAdapterFactory
117 virtual Reference
< XInterface
> SAL_CALL
createAdapter(
118 const Reference
< script::XInvocation
> & xReceiver
, const Type
& rType
)
119 throw (RuntimeException
);
120 // XInvocationAdapterFactory2
121 virtual Reference
< XInterface
> SAL_CALL
createAdapter(
122 const Reference
< script::XInvocation
> & xReceiver
,
123 const Sequence
< Type
> & rTypes
)
124 throw (RuntimeException
);
127 //==============================================================================
128 struct InterfaceAdapterImpl
: public uno_Interface
130 AdapterImpl
* m_pAdapter
;
131 typelib_InterfaceTypeDescription
* m_pTypeDescr
;
133 //==============================================================================
136 oslInterlockedCount m_nRef
;
137 FactoryImpl
* m_pFactory
;
138 void * m_key
; // map key
139 uno_Interface
* m_pReceiver
; // XInvocation receiver
141 sal_Int32 m_nInterfaces
;
142 InterfaceAdapterImpl
* m_pInterfaces
;
146 const typelib_TypeDescription
* pMemberType
,
147 void * pReturn
, uno_Any
** ppException
);
149 const typelib_TypeDescription
* pMemberType
,
150 void * pArgs
[], uno_Any
** ppException
);
152 const typelib_TypeDescription
* pMemberType
,
153 void * pReturn
, void * pArgs
[], uno_Any
** ppException
);
156 void * pDest
, typelib_TypeDescriptionReference
* pType
,
157 uno_Any
* pSource
, uno_Any
* pExc
);
158 inline bool coerce_construct(
159 void * pDest
, typelib_TypeDescriptionReference
* pType
,
160 uno_Any
* pSource
, uno_Any
* pExc
);
162 inline void acquire()
164 inline void release()
166 inline ~AdapterImpl()
169 void * key
, Reference
< script::XInvocation
> const & xReceiver
,
170 const Sequence
< Type
> & rTypes
,
171 FactoryImpl
* pFactory
)
172 SAL_THROW( (RuntimeException
) );
174 //______________________________________________________________________________
175 inline AdapterImpl::~AdapterImpl()
178 for ( sal_Int32 nPos
= m_nInterfaces
; nPos
--; )
180 ::typelib_typedescription_release(
181 (typelib_TypeDescription
*)m_pInterfaces
[ nPos
].m_pTypeDescr
);
183 delete [] m_pInterfaces
;
185 (*m_pReceiver
->release
)( m_pReceiver
);
186 m_pFactory
->release();
188 //______________________________________________________________________________
189 inline void AdapterImpl::acquire()
192 osl_atomic_increment( &m_nRef
);
194 //______________________________________________________________________________
195 inline void AdapterImpl::release()
198 bool delete_this
= false;
200 MutexGuard
guard( m_pFactory
->m_mutex
);
201 if (! osl_atomic_decrement( &m_nRef
))
203 t_ptr_map::iterator
iFind(
204 m_pFactory
->m_receiver2adapters
.find( m_key
) );
205 OSL_ASSERT( m_pFactory
->m_receiver2adapters
.end() != iFind
);
206 t_ptr_set
& adapter_set
= iFind
->second
;
207 if (adapter_set
.erase( this ) != 1) {
210 if (adapter_set
.empty())
212 m_pFactory
->m_receiver2adapters
.erase( iFind
);
221 //------------------------------------------------------------------------------
222 static inline void constructRuntimeException(
223 uno_Any
* pExc
, const OUString
& rMsg
)
225 RuntimeException
exc( rMsg
, Reference
< XInterface
>() );
226 // no conversion needed due to binary compatibility + no convertible type
227 ::uno_type_any_construct(
228 pExc
, &exc
, ::getCppuType( &exc
).getTypeLibType(), 0 );
231 //------------------------------------------------------------------------------
232 static inline sal_Bool
type_equals(
233 typelib_TypeDescriptionReference
* pType1
,
234 typelib_TypeDescriptionReference
* pType2
)
237 return (pType1
== pType2
||
238 (pType1
->pTypeName
->length
== pType2
->pTypeName
->length
&&
239 0 == ::rtl_ustr_compare(
240 pType1
->pTypeName
->buffer
, pType2
->pTypeName
->buffer
)));
243 //______________________________________________________________________________
244 bool AdapterImpl::coerce_assign(
245 void * pDest
, typelib_TypeDescriptionReference
* pType
, uno_Any
* pSource
,
248 if (typelib_TypeClass_ANY
== pType
->eTypeClass
)
250 ::uno_type_any_assign(
251 (uno_Any
*)pDest
, pSource
->pData
, pSource
->pType
, 0, 0 );
254 if (::uno_type_assignData(
255 pDest
, pType
, pSource
->pData
, pSource
->pType
, 0, 0, 0 ))
259 else // try type converter
266 uno_Any
* p_exc
= &exc
;
269 (*m_pFactory
->m_pConverter
->pDispatcher
)(
270 m_pFactory
->m_pConverter
,
271 m_pFactory
->m_pConvertToTD
, &ret
, args
, &p_exc
);
273 if (p_exc
) // exception occurred
276 p_exc
->pType
->eTypeClass
== typelib_TypeClass_EXCEPTION
);
277 if (typelib_typedescriptionreference_isAssignableFrom(
279 (RuntimeException
const *) 0 ).getTypeLibType(),
282 // is RuntimeException or derived: rethrow
283 uno_type_any_construct(
284 pOutExc
, p_exc
->pData
, p_exc
->pType
, 0 );
288 // set runtime exception
289 constructRuntimeException(
290 pOutExc
, "type coercion failed: " +
291 reinterpret_cast< Exception
const * >(
292 p_exc
->pData
)->Message
);
294 ::uno_any_destruct( p_exc
, 0 );
295 // pOutExc constructed
300 bool succ
= (sal_False
!= ::uno_type_assignData(
301 pDest
, pType
, ret
.pData
, ret
.pType
, 0, 0, 0 ));
302 ::uno_any_destruct( &ret
, 0 );
304 succ
, "### conversion succeeded, but assignment failed!?" );
307 // set runtime exception
308 constructRuntimeException(
310 "type coercion failed: "
311 "conversion succeeded, but assignment failed?!" );
317 //______________________________________________________________________________
318 inline bool AdapterImpl::coerce_construct(
319 void * pDest
, typelib_TypeDescriptionReference
* pType
, uno_Any
* pSource
,
322 if (typelib_TypeClass_ANY
== pType
->eTypeClass
)
324 ::uno_type_copyData( pDest
, pSource
, pType
, 0 );
327 if (type_equals( pType
, pSource
->pType
))
329 ::uno_type_copyData( pDest
, pSource
->pData
, pType
, 0 );
332 ::uno_type_constructData( pDest
, pType
);
333 return coerce_assign( pDest
, pType
, pSource
, pExc
);
336 //------------------------------------------------------------------------------
337 static void handleInvokExc( uno_Any
* pDest
, uno_Any
* pSource
)
339 OUString
const & name
=
340 *reinterpret_cast< OUString
const * >( &pSource
->pType
->pTypeName
);
342 if ( name
== "com.sun.star.reflection.InvocationTargetException" )
344 // unwrap invocation target exception
345 uno_Any
* target_exc
=
346 &reinterpret_cast< reflection::InvocationTargetException
* >(
347 pSource
->pData
)->TargetException
;
348 ::uno_type_any_construct(
349 pDest
, target_exc
->pData
, target_exc
->pType
, 0 );
351 else // all other exceptions are wrapped to RuntimeException
353 if (typelib_TypeClass_EXCEPTION
== pSource
->pType
->eTypeClass
)
355 constructRuntimeException(
356 pDest
, ((Exception
const *)pSource
->pData
)->Message
);
360 constructRuntimeException(
361 pDest
, "no exception has been thrown via invocation?!" );
365 //______________________________________________________________________________
366 void AdapterImpl::getValue(
367 const typelib_TypeDescription
* pMemberType
,
368 void * pReturn
, uno_Any
** ppException
)
371 void * pInvokArgs
[1];
373 &((typelib_InterfaceMemberTypeDescription
*)pMemberType
)->pMemberName
;
375 uno_Any
* pInvokExc
= &aInvokExc
;
378 (*m_pReceiver
->pDispatcher
)(
379 m_pReceiver
, m_pFactory
->m_pGetValueTD
,
380 &aInvokRet
, pInvokArgs
, &pInvokExc
);
382 if (pInvokExc
) // getValue() call exception
384 handleInvokExc( *ppException
, pInvokExc
);
385 ::uno_any_destruct( pInvokExc
, 0 ); // cleanup
387 else // invocation call succeeded
389 if (coerce_construct(
391 ((typelib_InterfaceAttributeTypeDescription
*)
392 pMemberType
)->pAttributeTypeRef
,
393 &aInvokRet
, *ppException
))
395 *ppException
= 0; // no exceptions be thrown
397 ::uno_any_destruct( &aInvokRet
, 0 );
400 //______________________________________________________________________________
401 void AdapterImpl::setValue(
402 const typelib_TypeDescription
* pMemberType
,
403 void * pArgs
[], uno_Any
** ppException
)
406 ::uno_type_any_construct(
407 &aInvokVal
, pArgs
[0],
408 ((typelib_InterfaceAttributeTypeDescription
*)
409 pMemberType
)->pAttributeTypeRef
, 0 );
411 void * pInvokArgs
[2];
413 &((typelib_InterfaceMemberTypeDescription
*)pMemberType
)->pMemberName
;
414 pInvokArgs
[1] = &aInvokVal
;
416 uno_Any
* pInvokExc
= &aInvokExc
;
419 (*m_pReceiver
->pDispatcher
)(
420 m_pReceiver
, m_pFactory
->m_pSetValueTD
, 0, pInvokArgs
, &pInvokExc
);
422 if (pInvokExc
) // setValue() call exception
424 handleInvokExc( *ppException
, pInvokExc
);
425 ::uno_any_destruct( pInvokExc
, 0 ); // cleanup
427 else // invocation call succeeded
429 *ppException
= 0; // no exceptions be thrown
432 ::uno_any_destruct( &aInvokVal
, 0 ); // cleanup
434 //______________________________________________________________________________
435 void AdapterImpl::invoke(
436 const typelib_TypeDescription
* pMemberType
,
437 void * pReturn
, void * pArgs
[], uno_Any
** ppException
)
440 ((typelib_InterfaceMethodTypeDescription
*)pMemberType
)->nParams
;
441 typelib_MethodParameter
* pFormalParams
=
442 ((typelib_InterfaceMethodTypeDescription
*)pMemberType
)->pParams
;
445 uno_Sequence
* pInParamsSeq
= 0;
446 ::uno_sequence_construct(
447 &pInParamsSeq
, m_pFactory
->m_pAnySeqTD
, 0, nParams
, 0 );
448 uno_Any
* pInAnys
= (uno_Any
*)pInParamsSeq
->elements
;
449 sal_Int32 nOutParams
= 0;
451 for ( nPos
= nParams
; nPos
--; )
453 typelib_MethodParameter
const & rParam
= pFormalParams
[nPos
];
454 if (rParam
.bIn
) // is in/inout param
456 ::uno_type_any_assign(
457 &pInAnys
[nPos
], pArgs
[nPos
], rParam
.pTypeRef
, 0, 0 );
459 // else: pure out is empty any
465 // out params, out indices
466 uno_Sequence
* pOutIndices
;
467 uno_Sequence
* pOutParams
;
471 void * pInvokArgs
[4];
473 &((typelib_InterfaceMemberTypeDescription
*)pMemberType
)->pMemberName
;
474 pInvokArgs
[1] = &pInParamsSeq
;
475 pInvokArgs
[2] = &pOutIndices
;
476 pInvokArgs
[3] = &pOutParams
;
478 uno_Any
* pInvokExc
= &aInvokExc
;
481 (*m_pReceiver
->pDispatcher
)(
482 m_pReceiver
, m_pFactory
->m_pInvokMethodTD
,
483 &aInvokRet
, pInvokArgs
, &pInvokExc
);
487 handleInvokExc( *ppException
, pInvokExc
);
488 ::uno_any_destruct( pInvokExc
, 0 ); // cleanup
490 else // no invocation exception
492 // write changed out params
494 pOutParams
->nElements
== nOutParams
&&
495 pOutIndices
->nElements
== nOutParams
,
496 "### out params lens differ!" );
497 if (pOutParams
->nElements
== nOutParams
&&
498 pOutIndices
->nElements
== nOutParams
)
500 sal_Int16
* pIndices
= (sal_Int16
*)pOutIndices
->elements
;
501 uno_Any
* pOut
= (uno_Any
*)pOutParams
->elements
;
502 for ( nPos
= 0; nPos
< nOutParams
; ++nPos
)
504 sal_Int32 nIndex
= pIndices
[nPos
];
505 OSL_ENSURE( nIndex
< nParams
, "### illegal index!" );
506 typelib_MethodParameter
const & rParam
= pFormalParams
[nIndex
];
508 if (rParam
.bIn
) // is in/inout param
510 succ
= coerce_assign(
511 pArgs
[nIndex
], rParam
.pTypeRef
, &pOut
[nPos
],
516 succ
= coerce_construct(
517 pArgs
[nIndex
], rParam
.pTypeRef
, &pOut
[nPos
],
520 if (! succ
) // cleanup of out params
522 for ( sal_Int32 n
= 0; n
<= nPos
; ++n
)
524 sal_Int32 nIndex2
= pIndices
[n
];
525 OSL_ENSURE( nIndex2
< nParams
, "### illegal index!" );
526 typelib_MethodParameter
const & rParam2
=
527 pFormalParams
[nIndex2
];
528 if (! rParam2
.bIn
) // is pure out param
530 ::uno_type_destructData(
531 pArgs
[nIndex2
], rParam2
.pTypeRef
, 0 );
536 if (nPos
== pOutIndices
->nElements
)
538 // out param copy ok; write return value
539 if (coerce_construct(
541 ((typelib_InterfaceMethodTypeDescription
*)
542 pMemberType
)->pReturnTypeRef
,
543 &aInvokRet
, *ppException
))
545 *ppException
= 0; // no exception
551 // set runtime exception
552 constructRuntimeException(
554 "out params lengths differ after invocation call!" );
556 // cleanup invok out params
557 ::uno_destructData( &pOutIndices
, m_pFactory
->m_pShortSeqTD
, 0 );
558 ::uno_destructData( &pOutParams
, m_pFactory
->m_pAnySeqTD
, 0 );
559 // cleanup invok return value
560 ::uno_any_destruct( &aInvokRet
, 0 );
562 // cleanup constructed in params
563 ::uno_destructData( &pInParamsSeq
, m_pFactory
->m_pAnySeqTD
, 0 );
568 //______________________________________________________________________________
569 static void SAL_CALL
adapter_acquire( uno_Interface
* pUnoI
)
571 static_cast< InterfaceAdapterImpl
* >( pUnoI
)->m_pAdapter
->acquire();
573 //______________________________________________________________________________
574 static void SAL_CALL
adapter_release( uno_Interface
* pUnoI
)
576 static_cast< InterfaceAdapterImpl
* >( pUnoI
)->m_pAdapter
->release();
578 //______________________________________________________________________________
579 static void SAL_CALL
adapter_dispatch(
580 uno_Interface
* pUnoI
, const typelib_TypeDescription
* pMemberType
,
581 void * pReturn
, void * pArgs
[], uno_Any
** ppException
)
583 // query to emulated interface
584 switch (((typelib_InterfaceMemberTypeDescription
*)pMemberType
)->nPosition
)
586 case 0: // queryInterface()
589 static_cast< InterfaceAdapterImpl
* >( pUnoI
)->m_pAdapter
;
590 *ppException
= 0; // no exc
591 typelib_TypeDescriptionReference
* pDemanded
=
592 *(typelib_TypeDescriptionReference
**)pArgs
[0];
593 // pInterfaces[0] is XInterface
594 for ( sal_Int32 nPos
= 0; nPos
< that
->m_nInterfaces
; ++nPos
)
596 typelib_InterfaceTypeDescription
* pTD
=
597 that
->m_pInterfaces
[nPos
].m_pTypeDescr
;
601 ((typelib_TypeDescription
*)pTD
)->pWeakRef
, pDemanded
))
603 uno_Interface
* pUnoI2
= &that
->m_pInterfaces
[nPos
];
605 (uno_Any
*)pReturn
, &pUnoI2
,
606 (typelib_TypeDescription
*)pTD
, 0 );
609 pTD
= pTD
->pBaseTypeDescription
;
612 ::uno_any_construct( (uno_Any
*)pReturn
, 0, 0, 0 ); // clear()
616 *ppException
= 0; // no exc
617 adapter_acquire( pUnoI
);
620 *ppException
= 0; // no exc
621 adapter_release( pUnoI
);
627 static_cast< InterfaceAdapterImpl
* >( pUnoI
)->m_pAdapter
;
628 if (pMemberType
->eTypeClass
== typelib_TypeClass_INTERFACE_METHOD
)
630 that
->invoke( pMemberType
, pReturn
, pArgs
, ppException
);
635 that
->getValue( pMemberType
, pReturn
, ppException
);
637 that
->setValue( pMemberType
, pArgs
, ppException
);
643 //______________________________________________________________________________
644 AdapterImpl::AdapterImpl(
645 void * key
, Reference
< script::XInvocation
> const & xReceiver
,
646 const Sequence
< Type
> & rTypes
,
647 FactoryImpl
* pFactory
)
648 SAL_THROW( (RuntimeException
) )
650 m_pFactory( pFactory
),
654 m_nInterfaces
= rTypes
.getLength();
655 m_pInterfaces
= new InterfaceAdapterImpl
[ rTypes
.getLength() ];
656 const Type
* pTypes
= rTypes
.getConstArray();
657 for ( sal_Int32 nPos
= rTypes
.getLength(); nPos
--; )
659 InterfaceAdapterImpl
* pInterface
= &m_pInterfaces
[nPos
];
660 pInterface
->acquire
= adapter_acquire
;
661 pInterface
->release
= adapter_release
;
662 pInterface
->pDispatcher
= adapter_dispatch
;
663 pInterface
->m_pAdapter
= this;
664 pInterface
->m_pTypeDescr
= 0;
665 pTypes
[nPos
].getDescription(
666 (typelib_TypeDescription
**)&pInterface
->m_pTypeDescr
);
667 OSL_ASSERT( pInterface
->m_pTypeDescr
);
668 if (! pInterface
->m_pTypeDescr
)
670 for ( sal_Int32 n
= 0; n
< nPos
; ++n
)
672 ::typelib_typedescription_release(
673 (typelib_TypeDescription
*)
674 m_pInterfaces
[ n
].m_pTypeDescr
);
676 delete [] m_pInterfaces
;
677 throw RuntimeException(
678 "cannot retrieve all interface type infos!",
679 Reference
< XInterface
>() );
684 m_pReceiver
= (uno_Interface
*)m_pFactory
->m_aCpp2Uno
.mapInterface(
685 xReceiver
.get(), ::getCppuType( &xReceiver
) );
686 OSL_ASSERT( 0 != m_pReceiver
);
689 throw RuntimeException(
690 "cannot map receiver!", Reference
< XInterface
>() );
693 m_pFactory
->acquire();
696 //______________________________________________________________________________
697 FactoryImpl::FactoryImpl( Reference
< XComponentContext
> const & xContext
)
698 SAL_THROW( (RuntimeException
) )
699 : m_pInvokMethodTD( 0 ),
707 OUString aCppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
708 OUString aUnoEnvTypeName
= UNO_LB_UNO
;
709 m_aUno2Cpp
= Mapping( aUnoEnvTypeName
, aCppEnvTypeName
);
710 m_aCpp2Uno
= Mapping( aCppEnvTypeName
, aUnoEnvTypeName
);
712 m_aUno2Cpp
.is() && m_aCpp2Uno
.is(), "### no uno / C++ mappings!" );
715 Reference
< script::XTypeConverter
> xConverter(
716 xContext
->getServiceManager()->createInstanceWithContext(
717 OUString("com.sun.star.script.Converter"),
720 m_pConverter
= (uno_Interface
*)m_aCpp2Uno
.mapInterface(
721 xConverter
.get(), ::getCppuType( &xConverter
) );
722 OSL_ASSERT( 0 != m_pConverter
);
726 Type
const & rAnySeqType
= ::getCppuType( (const Sequence
< Any
> *)0 );
727 rAnySeqType
.getDescription( &m_pAnySeqTD
);
729 const Type
& rShortSeqType
=
730 ::getCppuType( (const Sequence
< sal_Int16
> *)0 );
731 rShortSeqType
.getDescription( &m_pShortSeqTD
);
732 // script.XInvocation
733 typelib_TypeDescription
* pTD
= 0;
734 const Type
& rInvType
= ::getCppuType(
735 (const Reference
< script::XInvocation
> *)0 );
736 TYPELIB_DANGER_GET( &pTD
, rInvType
.getTypeLibType() );
737 typelib_InterfaceTypeDescription
* pITD
;
738 pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
739 if( ! pITD
->aBase
.bComplete
)
740 typelib_typedescription_complete( &pTD
);
741 ::typelib_typedescriptionreference_getDescription(
742 &m_pInvokMethodTD
, pITD
->ppMembers
[ 1 ] ); // invoke()
743 ::typelib_typedescriptionreference_getDescription(
744 &m_pSetValueTD
, pITD
->ppMembers
[ 2 ] ); // setValue()
745 ::typelib_typedescriptionreference_getDescription(
746 &m_pGetValueTD
, pITD
->ppMembers
[ 3 ] ); // getValue()
747 // script.XTypeConverter
748 const Type
& rTCType
=
749 ::getCppuType( (const Reference
< script::XTypeConverter
> *)0 );
750 TYPELIB_DANGER_GET( &pTD
, rTCType
.getTypeLibType() );
751 pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
752 ::typelib_typedescriptionreference_getDescription(
753 &m_pConvertToTD
, pITD
->ppMembers
[ 0 ] ); // convertTo()
754 TYPELIB_DANGER_RELEASE( pTD
);
756 if (!m_pInvokMethodTD
|| !m_pSetValueTD
|| !m_pGetValueTD
||
758 !m_pAnySeqTD
|| !m_pShortSeqTD
)
760 throw RuntimeException(
761 "missing type descriptions!", Reference
< XInterface
>() );
764 //______________________________________________________________________________
765 FactoryImpl::~FactoryImpl() SAL_THROW(())
767 ::typelib_typedescription_release( m_pInvokMethodTD
);
768 ::typelib_typedescription_release( m_pSetValueTD
);
769 ::typelib_typedescription_release( m_pGetValueTD
);
770 ::typelib_typedescription_release( m_pAnySeqTD
);
771 ::typelib_typedescription_release( m_pShortSeqTD
);
772 ::typelib_typedescription_release( m_pConvertToTD
);
774 (*m_pConverter
->release
)( m_pConverter
);
776 #if OSL_DEBUG_LEVEL > 1
777 OSL_ENSURE( m_receiver2adapters
.empty(), "### still adapters out there!?" );
781 //------------------------------------------------------------------------------
782 static inline AdapterImpl
* lookup_adapter(
783 t_ptr_set
** pp_adapter_set
,
784 t_ptr_map
& map
, void * key
, Sequence
< Type
> const & rTypes
)
787 t_ptr_set
& adapters_set
= map
[ key
];
788 *pp_adapter_set
= &adapters_set
;
789 if (adapters_set
.empty())
790 return 0; // shortcut
791 // find matching adapter
792 Type
const * pTypes
= rTypes
.getConstArray();
793 sal_Int32 nTypes
= rTypes
.getLength();
794 t_ptr_set::const_iterator
iPos( adapters_set
.begin() );
795 t_ptr_set::const_iterator
const iEnd( adapters_set
.end() );
798 AdapterImpl
* that
= reinterpret_cast< AdapterImpl
* >( *iPos
);
799 // iterate thru all types if that is a matching adapter
801 for ( nPosTypes
= nTypes
; nPosTypes
--; )
803 Type
const & rType
= pTypes
[ nPosTypes
];
804 // find in adapter's type list
806 for ( nPos
= that
->m_nInterfaces
; nPos
--; )
808 if (::typelib_typedescriptionreference_isAssignableFrom(
809 rType
.getTypeLibType(),
810 ((typelib_TypeDescription
*)that
->
811 m_pInterfaces
[ nPos
].m_pTypeDescr
)->pWeakRef
))
817 if (nPos
< 0) // type not found => next adapter
820 if (nPosTypes
< 0) // all types found
827 // XInvocationAdapterFactory2 impl
828 //______________________________________________________________________________
829 Reference
< XInterface
> FactoryImpl::createAdapter(
830 const Reference
< script::XInvocation
> & xReceiver
,
831 const Sequence
< Type
> & rTypes
)
832 throw (RuntimeException
)
834 Reference
< XInterface
> xRet
;
835 if (xReceiver
.is() && rTypes
.getLength())
837 t_ptr_set
* adapter_set
;
839 Reference
< XInterface
> xKey( xReceiver
, UNO_QUERY
);
841 ClearableMutexGuard
guard( m_mutex
);
842 that
= lookup_adapter(
843 &adapter_set
, m_receiver2adapters
, xKey
.get(), rTypes
);
844 if (0 == that
) // no entry
847 // create adapter; already acquired: m_nRef == 1
849 new AdapterImpl( xKey
.get(), xReceiver
, rTypes
, this );
851 ClearableMutexGuard
guard2( m_mutex
);
852 that
= lookup_adapter(
853 &adapter_set
, m_receiver2adapters
, xKey
.get(), rTypes
);
854 if (0 == that
) // again no entry
856 pair
< t_ptr_set::iterator
, bool > i(adapter_set
->insert(pNew
));
859 "set already contains " << *(i
.first
) << " != " << pNew
);
866 delete pNew
; // has never been inserted
869 else // found adapter
874 // map one interface to C++
875 uno_Interface
* pUnoI
= &that
->m_pInterfaces
[ 0 ];
876 m_aUno2Cpp
.mapInterface(
877 (void **)&xRet
, pUnoI
, ::getCppuType( &xRet
) );
879 OSL_ASSERT( xRet
.is() );
882 throw RuntimeException(
883 "mapping UNO to C++ failed!",
884 Reference
< XInterface
>() );
889 // XInvocationAdapterFactory impl
890 //______________________________________________________________________________
891 Reference
< XInterface
> FactoryImpl::createAdapter(
892 const Reference
< script::XInvocation
> & xReceiver
, const Type
& rType
)
893 throw (RuntimeException
)
895 return createAdapter( xReceiver
, Sequence
< Type
>( &rType
, 1 ) );
899 //______________________________________________________________________________
900 OUString
FactoryImpl::getImplementationName()
901 throw (RuntimeException
)
903 return invadp_getImplementationName();
905 //______________________________________________________________________________
906 sal_Bool
FactoryImpl::supportsService( const OUString
& rServiceName
)
907 throw (RuntimeException
)
909 const Sequence
< OUString
> & rSNL
= getSupportedServiceNames();
910 const OUString
* pArray
= rSNL
.getConstArray();
911 for ( sal_Int32 nPos
= rSNL
.getLength(); nPos
--; )
913 if (pArray
[nPos
].equals( rServiceName
))
918 //______________________________________________________________________________
919 Sequence
< OUString
> FactoryImpl::getSupportedServiceNames()
920 throw (RuntimeException
)
922 return invadp_getSupportedServiceNames();
925 //==============================================================================
926 static Reference
< XInterface
> SAL_CALL
FactoryImpl_create(
927 const Reference
< XComponentContext
> & xContext
)
930 return (::cppu::OWeakObject
*)new FactoryImpl( xContext
);
936 //##############################################################################
937 //##############################################################################
938 //##############################################################################
940 static struct ::cppu::ImplementationEntry g_entries
[] =
943 ::stoc_invadp::FactoryImpl_create
,
944 ::stoc_invadp::invadp_getImplementationName
,
945 ::stoc_invadp::invadp_getSupportedServiceNames
,
946 ::cppu::createOneInstanceComponentFactory
,
952 extern "C" SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
invocadapt_component_getFactory(
953 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
955 return ::cppu::component_getFactoryHelper(
956 pImplName
, pServiceManager
, pRegistryKey
, g_entries
);
959 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */