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