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