File: | stoc/source/invocation_adapterfactory/iafactory.cxx |
Location: | line 758, column 26 |
Description: | Access to field 'ppMembers' results in a dereference of a null pointer (loaded from variable 'pITD') |
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 ) | |||
| ||||
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: */ |