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