| 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: */ |