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