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