2010-10-14 08:30:07 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2000-09-18 14:29:57 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
2008-04-11 10:38:14 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-09-18 14:29:57 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 16:30:17 +00:00
|
|
|
|
2011-02-03 16:24:08 -07:00
|
|
|
#include <boost/unordered_map.hpp>
|
|
|
|
#include <boost/unordered_set.hpp>
|
2002-08-22 11:28:54 +00:00
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <osl/diagnose.h>
|
|
|
|
#include <osl/interlck.h>
|
2002-08-22 11:28:54 +00:00
|
|
|
#include <osl/mutex.hxx>
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
#include <uno/dispatcher.h>
|
|
|
|
#include <uno/data.h>
|
|
|
|
#include <uno/any2.h>
|
|
|
|
#include <uno/mapping.hxx>
|
|
|
|
|
|
|
|
#include <cppuhelper/factory.hxx>
|
|
|
|
#include <cppuhelper/implbase3.hxx>
|
2001-06-22 15:21:02 +00:00
|
|
|
#include <cppuhelper/implementationentry.hxx>
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
#include <com/sun/star/uno/XAggregation.hpp>
|
2002-08-22 11:28:54 +00:00
|
|
|
#include <com/sun/star/script/XTypeConverter.hpp>
|
2000-09-18 14:29:57 +00:00
|
|
|
#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
|
|
|
|
#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
|
|
|
|
#include <com/sun/star/script/XInvocation.hpp>
|
|
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
|
|
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
|
|
|
|
#include <com/sun/star/registry/XSimpleRegistry.hpp>
|
|
|
|
#include <com/sun/star/registry/XRegistryKey.hpp>
|
|
|
|
#include <com/sun/star/reflection/InvocationTargetException.hpp>
|
2004-06-04 01:30:55 +00:00
|
|
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
#define SERVICENAME "com.sun.star.script.InvocationAdapterFactory"
|
|
|
|
#define IMPLNAME "com.sun.star.comp.stoc.InvocationAdapterFactory"
|
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
|
|
|
|
using namespace ::std;
|
|
|
|
using namespace ::rtl;
|
|
|
|
using namespace ::osl;
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
|
2000-09-18 14:29:57 +00:00
|
|
|
namespace stoc_invadp
|
|
|
|
{
|
|
|
|
|
2001-06-22 15:21:02 +00:00
|
|
|
static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
|
|
|
|
|
|
|
|
static Sequence< OUString > invadp_getSupportedServiceNames()
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2011-06-01 15:34:41 +01:00
|
|
|
Sequence< OUString > seqNames(1);
|
|
|
|
seqNames.getArray()[0] =
|
|
|
|
OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
|
|
|
|
return seqNames;
|
2001-06-22 15:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static OUString invadp_getImplementationName()
|
|
|
|
{
|
2011-06-01 15:34:41 +01:00
|
|
|
return OUString(RTL_CONSTASCII_USTRINGPARAM(IMPLNAME));
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
struct hash_ptr
|
|
|
|
{
|
|
|
|
inline size_t operator() ( void * p ) const
|
|
|
|
{ return (size_t)p; }
|
|
|
|
};
|
2011-02-03 16:24:08 -07:00
|
|
|
typedef boost::unordered_set< void *, hash_ptr, equal_to< void * > > t_ptr_set;
|
|
|
|
typedef boost::unordered_map< void *, t_ptr_set, hash_ptr, equal_to< void * > > t_ptr_map;
|
2002-08-22 11:28:54 +00:00
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//==============================================================================
|
2000-09-18 14:29:57 +00:00
|
|
|
class FactoryImpl
|
2002-08-22 11:28:54 +00:00
|
|
|
: public ::cppu::WeakImplHelper3< lang::XServiceInfo,
|
|
|
|
script::XInvocationAdapterFactory,
|
|
|
|
script::XInvocationAdapterFactory2 >
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
public:
|
2002-08-22 11:28:54 +00:00
|
|
|
Mapping m_aUno2Cpp;
|
|
|
|
Mapping m_aCpp2Uno;
|
|
|
|
uno_Interface * m_pConverter;
|
|
|
|
|
|
|
|
typelib_TypeDescription * m_pInvokMethodTD;
|
|
|
|
typelib_TypeDescription * m_pSetValueTD;
|
|
|
|
typelib_TypeDescription * m_pGetValueTD;
|
|
|
|
typelib_TypeDescription * m_pAnySeqTD;
|
|
|
|
typelib_TypeDescription * m_pShortSeqTD;
|
|
|
|
typelib_TypeDescription * m_pConvertToTD;
|
|
|
|
|
|
|
|
Mutex m_mutex;
|
2002-08-22 13:41:39 +00:00
|
|
|
t_ptr_map m_receiver2adapters;
|
2002-08-22 11:28:54 +00:00
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
FactoryImpl( Reference< XComponentContext > const & xContext )
|
|
|
|
SAL_THROW( (RuntimeException) );
|
2002-08-22 11:28:54 +00:00
|
|
|
virtual ~FactoryImpl() SAL_THROW( () );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XServiceInfo
|
2002-08-22 11:28:54 +00:00
|
|
|
virtual OUString SAL_CALL getImplementationName()
|
|
|
|
throw (RuntimeException);
|
|
|
|
virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
|
|
|
|
throw (RuntimeException);
|
|
|
|
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
|
|
|
|
throw (RuntimeException);
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XInvocationAdapterFactory
|
|
|
|
virtual Reference< XInterface > SAL_CALL createAdapter(
|
2002-08-22 11:28:54 +00:00
|
|
|
const Reference< script::XInvocation > & xReceiver, const Type & rType )
|
|
|
|
throw (RuntimeException);
|
2000-09-18 14:29:57 +00:00
|
|
|
// XInvocationAdapterFactory2
|
|
|
|
virtual Reference< XInterface > SAL_CALL createAdapter(
|
2003-09-04 08:07:27 +00:00
|
|
|
const Reference< script::XInvocation > & xReceiver,
|
|
|
|
const Sequence< Type > & rTypes )
|
2002-08-22 11:28:54 +00:00
|
|
|
throw (RuntimeException);
|
2000-09-18 14:29:57 +00:00
|
|
|
};
|
|
|
|
struct AdapterImpl;
|
2003-09-04 08:07:27 +00:00
|
|
|
//==============================================================================
|
2000-09-18 14:29:57 +00:00
|
|
|
struct InterfaceAdapterImpl : public uno_Interface
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
AdapterImpl * m_pAdapter;
|
|
|
|
typelib_InterfaceTypeDescription * m_pTypeDescr;
|
2000-09-18 14:29:57 +00:00
|
|
|
};
|
2003-09-04 08:07:27 +00:00
|
|
|
//==============================================================================
|
2000-09-18 14:29:57 +00:00
|
|
|
struct AdapterImpl
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
oslInterlockedCount m_nRef;
|
|
|
|
FactoryImpl * m_pFactory;
|
|
|
|
void * m_key; // map key
|
|
|
|
uno_Interface * m_pReceiver; // XInvocation receiver
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
sal_Int32 m_nInterfaces;
|
|
|
|
InterfaceAdapterImpl * m_pInterfaces;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XInvocation calls
|
2002-08-22 11:28:54 +00:00
|
|
|
void getValue(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
|
|
|
void * pReturn, void * pArgs[], uno_Any ** ppException );
|
|
|
|
void setValue(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
|
|
|
void * pReturn, void * pArgs[], uno_Any ** ppException );
|
|
|
|
void invoke(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
|
|
|
void * pReturn, void * pArgs[], uno_Any ** ppException );
|
|
|
|
|
|
|
|
bool coerce_assign(
|
2003-09-04 08:07:27 +00:00
|
|
|
void * pDest, typelib_TypeDescriptionReference * pType,
|
|
|
|
uno_Any * pSource, uno_Any * pExc );
|
2002-08-22 11:28:54 +00:00
|
|
|
inline bool coerce_construct(
|
2003-09-04 08:07:27 +00:00
|
|
|
void * pDest, typelib_TypeDescriptionReference * pType,
|
|
|
|
uno_Any * pSource, uno_Any * pExc );
|
2002-08-22 11:28:54 +00:00
|
|
|
|
2002-08-22 13:41:39 +00:00
|
|
|
inline void acquire()
|
|
|
|
SAL_THROW( () );
|
|
|
|
inline void release()
|
|
|
|
SAL_THROW( () );
|
|
|
|
inline ~AdapterImpl()
|
|
|
|
SAL_THROW( () );
|
2002-08-22 11:28:54 +00:00
|
|
|
inline AdapterImpl(
|
|
|
|
void * key, Reference< script::XInvocation > const & xReceiver,
|
|
|
|
const Sequence< Type > & rTypes,
|
|
|
|
FactoryImpl * pFactory )
|
|
|
|
SAL_THROW( (RuntimeException) );
|
2000-09-18 14:29:57 +00:00
|
|
|
};
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 13:41:39 +00:00
|
|
|
inline AdapterImpl::~AdapterImpl()
|
|
|
|
SAL_THROW( () )
|
|
|
|
{
|
|
|
|
for ( sal_Int32 nPos = m_nInterfaces; nPos--; )
|
|
|
|
{
|
|
|
|
::typelib_typedescription_release(
|
|
|
|
(typelib_TypeDescription *)m_pInterfaces[ nPos ].m_pTypeDescr );
|
|
|
|
}
|
|
|
|
delete [] m_pInterfaces;
|
|
|
|
//
|
|
|
|
(*m_pReceiver->release)( m_pReceiver );
|
|
|
|
m_pFactory->release();
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 13:41:39 +00:00
|
|
|
inline void AdapterImpl::acquire()
|
|
|
|
SAL_THROW( () )
|
|
|
|
{
|
|
|
|
::osl_incrementInterlockedCount( &m_nRef );
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 13:41:39 +00:00
|
|
|
inline void AdapterImpl::release()
|
|
|
|
SAL_THROW( () )
|
|
|
|
{
|
2002-09-10 09:18:17 +00:00
|
|
|
bool delete_this = false;
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
MutexGuard guard( m_pFactory->m_mutex );
|
|
|
|
if (! ::osl_decrementInterlockedCount( &m_nRef ))
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
t_ptr_map::iterator iFind(
|
|
|
|
m_pFactory->m_receiver2adapters.find( m_key ) );
|
2002-08-22 13:41:39 +00:00
|
|
|
OSL_ASSERT( m_pFactory->m_receiver2adapters.end() != iFind );
|
|
|
|
t_ptr_set & adapter_set = iFind->second;
|
2006-06-19 23:02:47 +00:00
|
|
|
if (adapter_set.erase( this ) != 1) {
|
|
|
|
OSL_ASSERT( false );
|
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
if (adapter_set.empty())
|
|
|
|
{
|
|
|
|
m_pFactory->m_receiver2adapters.erase( iFind );
|
|
|
|
}
|
2002-09-10 09:18:17 +00:00
|
|
|
delete_this = true;
|
2002-08-22 13:41:39 +00:00
|
|
|
}
|
2002-09-10 09:18:17 +00:00
|
|
|
}
|
|
|
|
if (delete_this)
|
|
|
|
delete this;
|
2002-08-22 13:41:39 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
static inline void constructRuntimeException(
|
|
|
|
uno_Any * pExc, const OUString & rMsg )
|
|
|
|
{
|
|
|
|
RuntimeException exc( rMsg, Reference< XInterface >() );
|
|
|
|
// no conversion neeeded due to binary compatibility + no convertable type
|
|
|
|
::uno_type_any_construct(
|
|
|
|
pExc, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2003-12-01 16:59:47 +00:00
|
|
|
static inline sal_Bool type_equals(
|
2003-09-04 08:07:27 +00:00
|
|
|
typelib_TypeDescriptionReference * pType1,
|
|
|
|
typelib_TypeDescriptionReference * pType2 )
|
2002-08-22 11:28:54 +00:00
|
|
|
SAL_THROW( () )
|
|
|
|
{
|
|
|
|
return (pType1 == pType2 ||
|
|
|
|
(pType1->pTypeName->length == pType2->pTypeName->length &&
|
2003-09-04 08:07:27 +00:00
|
|
|
0 == ::rtl_ustr_compare(
|
|
|
|
pType1->pTypeName->buffer, pType2->pTypeName->buffer )));
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
|
|
|
|
//______________________________________________________________________________
|
2002-08-22 11:28:54 +00:00
|
|
|
bool AdapterImpl::coerce_assign(
|
2003-09-04 08:07:27 +00:00
|
|
|
void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource,
|
|
|
|
uno_Any * pOutExc )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
if (typelib_TypeClass_ANY == pType->eTypeClass)
|
|
|
|
{
|
|
|
|
::uno_type_any_assign(
|
|
|
|
(uno_Any *)pDest, pSource->pData, pSource->pType, 0, 0 );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (::uno_type_assignData(
|
|
|
|
pDest, pType, pSource->pData, pSource->pType, 0, 0, 0 ))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else // try type converter
|
|
|
|
{
|
|
|
|
uno_Any ret;
|
|
|
|
void * args[ 2 ];
|
|
|
|
args[ 0 ] = pSource;
|
|
|
|
args[ 1 ] = &pType;
|
|
|
|
uno_Any exc;
|
|
|
|
uno_Any * p_exc = &exc;
|
|
|
|
|
|
|
|
// converTo()
|
|
|
|
(*m_pFactory->m_pConverter->pDispatcher)(
|
|
|
|
m_pFactory->m_pConverter,
|
|
|
|
m_pFactory->m_pConvertToTD, &ret, args, &p_exc );
|
|
|
|
|
2010-12-05 19:11:58 +00:00
|
|
|
if (p_exc) // exception occurred
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
OSL_ASSERT(
|
|
|
|
p_exc->pType->eTypeClass == typelib_TypeClass_EXCEPTION );
|
|
|
|
if (typelib_typedescriptionreference_isAssignableFrom(
|
|
|
|
::getCppuType(
|
|
|
|
(RuntimeException const *) 0 ).getTypeLibType(),
|
|
|
|
p_exc->pType ))
|
|
|
|
{
|
|
|
|
// is RuntimeException or derived: rethrow
|
|
|
|
uno_type_any_construct(
|
|
|
|
pOutExc, p_exc->pData, p_exc->pType, 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// set runtime exception
|
|
|
|
constructRuntimeException(
|
|
|
|
pOutExc, OUSTR("type coercion failed: ") +
|
|
|
|
reinterpret_cast< Exception const * >(
|
|
|
|
p_exc->pData )->Message );
|
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( p_exc, 0 );
|
2003-09-04 08:07:27 +00:00
|
|
|
// pOutExc constructed
|
2002-08-22 11:28:54 +00:00
|
|
|
return false;
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
else
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
|
|
|
bool succ = (sal_False != ::uno_type_assignData(
|
|
|
|
pDest, pType, ret.pData, ret.pType, 0, 0, 0 ));
|
|
|
|
::uno_any_destruct( &ret, 0 );
|
2003-09-04 08:07:27 +00:00
|
|
|
OSL_ENSURE(
|
|
|
|
succ, "### conversion succeeded, but assignment failed!?" );
|
|
|
|
if (! succ)
|
|
|
|
{
|
|
|
|
// set runtime exception
|
|
|
|
constructRuntimeException(
|
|
|
|
pOutExc,
|
|
|
|
OUSTR("type coercion failed: "
|
|
|
|
"conversion succeeded, but assignment failed?!") );
|
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
return succ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 11:28:54 +00:00
|
|
|
inline bool AdapterImpl::coerce_construct(
|
2003-09-04 08:07:27 +00:00
|
|
|
void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource,
|
|
|
|
uno_Any * pExc )
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
|
|
|
if (typelib_TypeClass_ANY == pType->eTypeClass)
|
|
|
|
{
|
|
|
|
::uno_type_copyData( pDest, pSource, pType, 0 );
|
|
|
|
return true;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
if (type_equals( pType, pSource->pType))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_type_copyData( pDest, pSource->pData, pType, 0 );
|
|
|
|
return true;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_type_constructData( pDest, pType );
|
2003-09-04 08:07:27 +00:00
|
|
|
return coerce_assign( pDest, pType, pSource, pExc );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2001-11-26 14:18:28 +00:00
|
|
|
static void handleInvokExc( uno_Any * pDest, uno_Any * pSource )
|
|
|
|
{
|
|
|
|
OUString const & name =
|
2002-08-22 11:28:54 +00:00
|
|
|
*reinterpret_cast< OUString const * >( &pSource->pType->pTypeName );
|
2001-11-26 14:18:28 +00:00
|
|
|
|
|
|
|
if (name.equalsAsciiL(
|
2003-09-04 08:07:27 +00:00
|
|
|
RTL_CONSTASCII_STRINGPARAM(
|
|
|
|
"com.sun.star.reflection.InvocationTargetException") ))
|
2001-11-26 14:18:28 +00:00
|
|
|
{
|
|
|
|
// unwrap invocation target exception
|
|
|
|
uno_Any * target_exc =
|
2003-09-04 08:07:27 +00:00
|
|
|
&reinterpret_cast< reflection::InvocationTargetException * >(
|
|
|
|
pSource->pData )->TargetException;
|
|
|
|
::uno_type_any_construct(
|
|
|
|
pDest, target_exc->pData, target_exc->pType, 0 );
|
2001-11-26 14:18:28 +00:00
|
|
|
}
|
|
|
|
else // all other exceptions are wrapped to RuntimeException
|
|
|
|
{
|
|
|
|
if (typelib_TypeClass_EXCEPTION == pSource->pType->eTypeClass)
|
|
|
|
{
|
|
|
|
constructRuntimeException(
|
|
|
|
pDest, ((Exception const *)pSource->pData)->Message );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
constructRuntimeException(
|
2002-08-22 11:28:54 +00:00
|
|
|
pDest, OUSTR("no exception has been thrown via invocation?!") );
|
2001-11-26 14:18:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
void AdapterImpl::getValue(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
2006-06-19 23:02:47 +00:00
|
|
|
void * pReturn, void * [], uno_Any ** ppException )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
uno_Any aInvokRet;
|
|
|
|
void * pInvokArgs[1];
|
2003-09-04 08:07:27 +00:00
|
|
|
pInvokArgs[0] =
|
|
|
|
&((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
|
2000-09-18 14:29:57 +00:00
|
|
|
uno_Any aInvokExc;
|
|
|
|
uno_Any * pInvokExc = &aInvokExc;
|
|
|
|
|
|
|
|
// getValue()
|
2002-08-22 11:28:54 +00:00
|
|
|
(*m_pReceiver->pDispatcher)(
|
2003-09-04 08:07:27 +00:00
|
|
|
m_pReceiver, m_pFactory->m_pGetValueTD,
|
|
|
|
&aInvokRet, pInvokArgs, &pInvokExc );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
if (pInvokExc) // getValue() call exception
|
|
|
|
{
|
2001-11-26 14:18:28 +00:00
|
|
|
handleInvokExc( *ppException, pInvokExc );
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( pInvokExc, 0 ); // cleanup
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else // invocation call succeeded
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
if (coerce_construct(
|
|
|
|
pReturn,
|
2003-09-04 08:07:27 +00:00
|
|
|
((typelib_InterfaceAttributeTypeDescription *)
|
|
|
|
pMemberType)->pAttributeTypeRef,
|
|
|
|
&aInvokRet, *ppException ))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
*ppException = 0; // no exceptions be thrown
|
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( &aInvokRet, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
void AdapterImpl::setValue(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
2006-06-19 23:02:47 +00:00
|
|
|
void *, void * pArgs[], uno_Any ** ppException )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
uno_Any aInvokVal;
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_type_any_construct(
|
|
|
|
&aInvokVal, pArgs[0],
|
2003-09-04 08:07:27 +00:00
|
|
|
((typelib_InterfaceAttributeTypeDescription *)
|
|
|
|
pMemberType)->pAttributeTypeRef, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
void * pInvokArgs[2];
|
2003-09-04 08:07:27 +00:00
|
|
|
pInvokArgs[0] =
|
|
|
|
&((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
|
2000-09-18 14:29:57 +00:00
|
|
|
pInvokArgs[1] = &aInvokVal;
|
|
|
|
uno_Any aInvokExc;
|
|
|
|
uno_Any * pInvokExc = &aInvokExc;
|
|
|
|
|
|
|
|
// setValue()
|
2002-08-22 11:28:54 +00:00
|
|
|
(*m_pReceiver->pDispatcher)(
|
|
|
|
m_pReceiver, m_pFactory->m_pSetValueTD, 0, pInvokArgs, &pInvokExc );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
if (pInvokExc) // setValue() call exception
|
|
|
|
{
|
2001-11-26 14:18:28 +00:00
|
|
|
handleInvokExc( *ppException, pInvokExc );
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( pInvokExc, 0 ); // cleanup
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else // invocation call succeeded
|
|
|
|
{
|
|
|
|
*ppException = 0; // no exceptions be thrown
|
|
|
|
}
|
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( &aInvokVal, 0 ); // cleanup
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
void AdapterImpl::invoke(
|
|
|
|
const typelib_TypeDescription * pMemberType,
|
|
|
|
void * pReturn, void * pArgs[], uno_Any ** ppException )
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
sal_Int32 nParams =
|
|
|
|
((typelib_InterfaceMethodTypeDescription *)pMemberType)->nParams;
|
2002-08-22 11:28:54 +00:00
|
|
|
typelib_MethodParameter * pFormalParams =
|
|
|
|
((typelib_InterfaceMethodTypeDescription *)pMemberType)->pParams;
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// in params
|
|
|
|
uno_Sequence * pInParamsSeq = 0;
|
2003-09-04 08:07:27 +00:00
|
|
|
::uno_sequence_construct(
|
|
|
|
&pInParamsSeq, m_pFactory->m_pAnySeqTD, 0, nParams, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
uno_Any * pInAnys = (uno_Any *)pInParamsSeq->elements;
|
2003-07-16 16:44:57 +00:00
|
|
|
sal_Int32 nOutParams = 0;
|
2003-12-01 16:59:47 +00:00
|
|
|
sal_Int32 nPos;
|
|
|
|
for ( nPos = nParams; nPos--; )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
typelib_MethodParameter const & rParam = pFormalParams[nPos];
|
|
|
|
if (rParam.bIn) // is in/inout param
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
::uno_type_any_assign(
|
|
|
|
&pInAnys[nPos], pArgs[nPos], rParam.pTypeRef, 0, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-07-16 16:44:57 +00:00
|
|
|
// else: pure out is empty any
|
|
|
|
|
|
|
|
if (rParam.bOut)
|
|
|
|
++nOutParams;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// out params, out indices
|
|
|
|
uno_Sequence * pOutIndices;
|
|
|
|
uno_Sequence * pOutParams;
|
2002-08-22 11:28:54 +00:00
|
|
|
// return value
|
2000-09-18 14:29:57 +00:00
|
|
|
uno_Any aInvokRet;
|
|
|
|
// perform call
|
|
|
|
void * pInvokArgs[4];
|
2003-09-04 08:07:27 +00:00
|
|
|
pInvokArgs[0] =
|
|
|
|
&((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
|
2000-09-18 14:29:57 +00:00
|
|
|
pInvokArgs[1] = &pInParamsSeq;
|
|
|
|
pInvokArgs[2] = &pOutIndices;
|
|
|
|
pInvokArgs[3] = &pOutParams;
|
|
|
|
uno_Any aInvokExc;
|
|
|
|
uno_Any * pInvokExc = &aInvokExc;
|
|
|
|
|
|
|
|
// invoke() call
|
2002-08-22 11:28:54 +00:00
|
|
|
(*m_pReceiver->pDispatcher)(
|
2003-09-04 08:07:27 +00:00
|
|
|
m_pReceiver, m_pFactory->m_pInvokMethodTD,
|
|
|
|
&aInvokRet, pInvokArgs, &pInvokExc );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
if (pInvokExc)
|
|
|
|
{
|
2001-11-26 14:18:28 +00:00
|
|
|
handleInvokExc( *ppException, pInvokExc );
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( pInvokExc, 0 ); // cleanup
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else // no invocation exception
|
|
|
|
{
|
|
|
|
// write changed out params
|
2002-08-22 11:28:54 +00:00
|
|
|
OSL_ENSURE(
|
2003-07-16 16:44:57 +00:00
|
|
|
pOutParams->nElements == nOutParams &&
|
|
|
|
pOutIndices->nElements == nOutParams,
|
2002-08-22 11:28:54 +00:00
|
|
|
"### out params lens differ!" );
|
2003-07-16 16:44:57 +00:00
|
|
|
if (pOutParams->nElements == nOutParams &&
|
|
|
|
pOutIndices->nElements == nOutParams)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
sal_Int16 * pIndices = (sal_Int16 *)pOutIndices->elements;
|
|
|
|
uno_Any * pOut = (uno_Any *)pOutParams->elements;
|
2003-07-16 16:44:57 +00:00
|
|
|
for ( nPos = 0; nPos < nOutParams; ++nPos )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nIndex = pIndices[nPos];
|
2001-03-12 14:38:06 +00:00
|
|
|
OSL_ENSURE( nIndex < nParams, "### illegal index!" );
|
2002-08-22 11:28:54 +00:00
|
|
|
typelib_MethodParameter const & rParam = pFormalParams[nIndex];
|
|
|
|
bool succ;
|
|
|
|
if (rParam.bIn) // is in/inout param
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
succ = coerce_assign(
|
|
|
|
pArgs[nIndex], rParam.pTypeRef, &pOut[nPos],
|
|
|
|
*ppException );
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
else // pure out
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
succ = coerce_construct(
|
|
|
|
pArgs[nIndex], rParam.pTypeRef, &pOut[nPos],
|
|
|
|
*ppException );
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
if (! succ) // cleanup of out params
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
for ( sal_Int32 n = 0; n <= nPos; ++n )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2006-06-19 23:02:47 +00:00
|
|
|
sal_Int32 nIndex2 = pIndices[n];
|
|
|
|
OSL_ENSURE( nIndex2 < nParams, "### illegal index!" );
|
|
|
|
typelib_MethodParameter const & rParam2 =
|
|
|
|
pFormalParams[nIndex2];
|
|
|
|
if (! rParam2.bIn) // is pure out param
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
::uno_type_destructData(
|
2006-06-19 23:02:47 +00:00
|
|
|
pArgs[nIndex2], rParam2.pTypeRef, 0 );
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
if (nPos == pOutIndices->nElements)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
// out param copy ok; write return value
|
2002-08-22 11:28:54 +00:00
|
|
|
if (coerce_construct(
|
|
|
|
pReturn,
|
2003-09-04 08:07:27 +00:00
|
|
|
((typelib_InterfaceMethodTypeDescription *)
|
|
|
|
pMemberType)->pReturnTypeRef,
|
|
|
|
&aInvokRet, *ppException ))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
|
|
|
*ppException = 0; // no exception
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// set runtime exception
|
|
|
|
constructRuntimeException(
|
|
|
|
*ppException,
|
2002-08-22 11:28:54 +00:00
|
|
|
OUSTR("out params lengths differ after invocation call!") );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
// cleanup invok out params
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_destructData( &pOutIndices, m_pFactory->m_pShortSeqTD, 0 );
|
|
|
|
::uno_destructData( &pOutParams, m_pFactory->m_pAnySeqTD, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
// cleanup invok return value
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_any_destruct( &aInvokRet, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
// cleanup constructed in params
|
2002-08-22 11:28:54 +00:00
|
|
|
::uno_destructData( &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
static void SAL_CALL adapter_acquire( uno_Interface * pUnoI )
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->acquire();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
static void SAL_CALL adapter_release( uno_Interface * pUnoI )
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->release();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
static void SAL_CALL adapter_dispatch(
|
|
|
|
uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType,
|
|
|
|
void * pReturn, void * pArgs[], uno_Any ** ppException )
|
|
|
|
{
|
|
|
|
// query to emulated interface
|
|
|
|
switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition)
|
|
|
|
{
|
|
|
|
case 0: // queryInterface()
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
AdapterImpl * that =
|
2002-08-22 11:28:54 +00:00
|
|
|
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
|
2000-09-18 14:29:57 +00:00
|
|
|
*ppException = 0; // no exc
|
|
|
|
typelib_TypeDescriptionReference * pDemanded =
|
|
|
|
*(typelib_TypeDescriptionReference **)pArgs[0];
|
|
|
|
// pInterfaces[0] is XInterface
|
2002-08-22 13:41:39 +00:00
|
|
|
for ( sal_Int32 nPos = 0; nPos < that->m_nInterfaces; ++nPos )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
typelib_InterfaceTypeDescription * pTD =
|
|
|
|
that->m_pInterfaces[nPos].m_pTypeDescr;
|
2000-09-18 14:29:57 +00:00
|
|
|
while (pTD)
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
if (type_equals(
|
|
|
|
((typelib_TypeDescription *)pTD)->pWeakRef, pDemanded ))
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2006-06-19 23:02:47 +00:00
|
|
|
uno_Interface * pUnoI2 = &that->m_pInterfaces[nPos];
|
2000-09-18 14:29:57 +00:00
|
|
|
::uno_any_construct(
|
2006-06-19 23:02:47 +00:00
|
|
|
(uno_Any *)pReturn, &pUnoI2,
|
2003-09-04 08:07:27 +00:00
|
|
|
(typelib_TypeDescription *)pTD, 0 );
|
2000-09-18 14:29:57 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
pTD = pTD->pBaseTypeDescription;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
::uno_any_construct( (uno_Any *)pReturn, 0, 0, 0 ); // clear()
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: // acquire()
|
|
|
|
*ppException = 0; // no exc
|
|
|
|
adapter_acquire( pUnoI );
|
|
|
|
break;
|
|
|
|
case 2: // release()
|
|
|
|
*ppException = 0; // no exc
|
|
|
|
adapter_release( pUnoI );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
AdapterImpl * that =
|
2002-08-22 11:28:54 +00:00
|
|
|
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
|
2003-09-04 08:07:27 +00:00
|
|
|
if (pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
that->invoke( pMemberType, pReturn, pArgs, ppException );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
else // attribute
|
|
|
|
{
|
|
|
|
if (pReturn)
|
2002-08-22 13:41:39 +00:00
|
|
|
that->getValue( pMemberType, pReturn, pArgs, ppException );
|
2000-09-18 14:29:57 +00:00
|
|
|
else
|
2002-08-22 13:41:39 +00:00
|
|
|
that->setValue( pMemberType, pReturn, pArgs, ppException );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 11:28:54 +00:00
|
|
|
AdapterImpl::AdapterImpl(
|
|
|
|
void * key, Reference< script::XInvocation > const & xReceiver,
|
|
|
|
const Sequence< Type > & rTypes,
|
|
|
|
FactoryImpl * pFactory )
|
|
|
|
SAL_THROW( (RuntimeException) )
|
|
|
|
: m_nRef( 1 ),
|
2006-06-19 23:02:47 +00:00
|
|
|
m_pFactory( pFactory ),
|
|
|
|
m_key( key )
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
|
|
|
// init adapters
|
|
|
|
m_nInterfaces = rTypes.getLength();
|
|
|
|
m_pInterfaces = new InterfaceAdapterImpl[ rTypes.getLength() ];
|
2000-09-18 14:29:57 +00:00
|
|
|
const Type * pTypes = rTypes.getConstArray();
|
|
|
|
for ( sal_Int32 nPos = rTypes.getLength(); nPos--; )
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
InterfaceAdapterImpl * pInterface = &m_pInterfaces[nPos];
|
2000-09-18 14:29:57 +00:00
|
|
|
pInterface->acquire = adapter_acquire;
|
|
|
|
pInterface->release = adapter_release;
|
|
|
|
pInterface->pDispatcher = adapter_dispatch;
|
2002-08-22 11:28:54 +00:00
|
|
|
pInterface->m_pAdapter = this;
|
|
|
|
pInterface->m_pTypeDescr = 0;
|
2003-09-04 08:07:27 +00:00
|
|
|
pTypes[nPos].getDescription(
|
|
|
|
(typelib_TypeDescription **)&pInterface->m_pTypeDescr );
|
2002-08-22 11:28:54 +00:00
|
|
|
OSL_ASSERT( pInterface->m_pTypeDescr );
|
|
|
|
if (! pInterface->m_pTypeDescr)
|
|
|
|
{
|
|
|
|
for ( sal_Int32 n = 0; n < nPos; ++n )
|
|
|
|
{
|
|
|
|
::typelib_typedescription_release(
|
2003-09-04 08:07:27 +00:00
|
|
|
(typelib_TypeDescription *)
|
|
|
|
m_pInterfaces[ n ].m_pTypeDescr );
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
delete [] m_pInterfaces;
|
|
|
|
throw RuntimeException(
|
2003-09-04 08:07:27 +00:00
|
|
|
OUSTR("cannot retrieve all interface type infos!"),
|
|
|
|
Reference< XInterface >() );
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
// map receiver
|
|
|
|
m_pReceiver = (uno_Interface *)m_pFactory->m_aCpp2Uno.mapInterface(
|
|
|
|
xReceiver.get(), ::getCppuType( &xReceiver ) );
|
|
|
|
OSL_ASSERT( 0 != m_pReceiver );
|
|
|
|
if (! m_pReceiver)
|
|
|
|
{
|
|
|
|
throw RuntimeException(
|
|
|
|
OUSTR("cannot map receiver!"), Reference< XInterface >() );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pFactory->acquire();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2002-08-22 11:28:54 +00:00
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 11:28:54 +00:00
|
|
|
FactoryImpl::FactoryImpl( Reference< XComponentContext > const & xContext )
|
|
|
|
SAL_THROW( (RuntimeException) )
|
|
|
|
: m_pInvokMethodTD( 0 ),
|
|
|
|
m_pSetValueTD( 0 ),
|
|
|
|
m_pGetValueTD( 0 ),
|
|
|
|
m_pAnySeqTD( 0 ),
|
|
|
|
m_pShortSeqTD( 0 ),
|
|
|
|
m_pConvertToTD( 0 )
|
|
|
|
{
|
|
|
|
// C++/UNO bridge
|
|
|
|
OUString aCppEnvTypeName = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
|
|
|
|
OUString aUnoEnvTypeName = OUSTR(UNO_LB_UNO);
|
|
|
|
m_aUno2Cpp = Mapping( aUnoEnvTypeName, aCppEnvTypeName );
|
|
|
|
m_aCpp2Uno = Mapping( aCppEnvTypeName, aUnoEnvTypeName );
|
2003-09-04 08:07:27 +00:00
|
|
|
OSL_ENSURE(
|
|
|
|
m_aUno2Cpp.is() && m_aCpp2Uno.is(), "### no uno / C++ mappings!" );
|
2002-08-22 11:28:54 +00:00
|
|
|
|
|
|
|
// type converter
|
|
|
|
Reference< script::XTypeConverter > xConverter(
|
|
|
|
xContext->getServiceManager()->createInstanceWithContext(
|
2003-09-04 08:07:27 +00:00
|
|
|
OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter") ),
|
|
|
|
xContext ),
|
2002-08-22 11:28:54 +00:00
|
|
|
UNO_QUERY_THROW );
|
|
|
|
m_pConverter = (uno_Interface *)m_aCpp2Uno.mapInterface(
|
|
|
|
xConverter.get(), ::getCppuType( &xConverter ) );
|
|
|
|
OSL_ASSERT( 0 != m_pConverter );
|
|
|
|
|
|
|
|
// some type info:
|
|
|
|
// sequence< any >
|
|
|
|
Type const & rAnySeqType = ::getCppuType( (const Sequence< Any > *)0 );
|
|
|
|
rAnySeqType.getDescription( &m_pAnySeqTD );
|
|
|
|
// sequence< short >
|
2003-09-04 08:07:27 +00:00
|
|
|
const Type & rShortSeqType =
|
|
|
|
::getCppuType( (const Sequence< sal_Int16 > *)0 );
|
2002-08-22 11:28:54 +00:00
|
|
|
rShortSeqType.getDescription( &m_pShortSeqTD );
|
|
|
|
// script.XInvocation
|
2010-01-29 11:40:11 +01:00
|
|
|
typelib_TypeDescription * pTD = 0;
|
2003-09-04 08:07:27 +00:00
|
|
|
const Type & rInvType = ::getCppuType(
|
|
|
|
(const Reference< script::XInvocation > *)0 );
|
2010-01-29 11:40:11 +01:00
|
|
|
TYPELIB_DANGER_GET( &pTD, rInvType.getTypeLibType() );
|
|
|
|
typelib_InterfaceTypeDescription * pITD;
|
|
|
|
pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
|
|
|
|
if( ! pITD->aBase.bComplete )
|
|
|
|
typelib_typedescription_complete( &pTD );
|
2002-08-22 11:28:54 +00:00
|
|
|
::typelib_typedescriptionreference_getDescription(
|
2010-01-29 11:40:11 +01:00
|
|
|
&m_pInvokMethodTD, pITD->ppMembers[ 1 ] ); // invoke()
|
2002-08-22 11:28:54 +00:00
|
|
|
::typelib_typedescriptionreference_getDescription(
|
2010-01-29 11:40:11 +01:00
|
|
|
&m_pSetValueTD, pITD->ppMembers[ 2 ] ); // setValue()
|
2002-08-22 11:28:54 +00:00
|
|
|
::typelib_typedescriptionreference_getDescription(
|
2010-01-29 11:40:11 +01:00
|
|
|
&m_pGetValueTD, pITD->ppMembers[ 3 ] ); // getValue()
|
2002-08-22 11:28:54 +00:00
|
|
|
// script.XTypeConverter
|
2003-09-04 08:07:27 +00:00
|
|
|
const Type & rTCType =
|
|
|
|
::getCppuType( (const Reference< script::XTypeConverter > *)0 );
|
2010-01-29 11:40:11 +01:00
|
|
|
TYPELIB_DANGER_GET( &pTD, rTCType.getTypeLibType() );
|
|
|
|
pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
|
2002-08-22 11:28:54 +00:00
|
|
|
::typelib_typedescriptionreference_getDescription(
|
2010-01-29 11:40:11 +01:00
|
|
|
&m_pConvertToTD, pITD->ppMembers[ 0 ] ); // convertTo()
|
|
|
|
TYPELIB_DANGER_RELEASE( pTD );
|
2002-08-22 11:28:54 +00:00
|
|
|
|
|
|
|
if (!m_pInvokMethodTD || !m_pSetValueTD || !m_pGetValueTD ||
|
|
|
|
!m_pConvertToTD ||
|
|
|
|
!m_pAnySeqTD || !m_pShortSeqTD)
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
throw RuntimeException(
|
|
|
|
OUSTR("missing type descriptions!"), Reference< XInterface >() );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 11:28:54 +00:00
|
|
|
FactoryImpl::~FactoryImpl() SAL_THROW( () )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
::typelib_typedescription_release( m_pInvokMethodTD );
|
|
|
|
::typelib_typedescription_release( m_pSetValueTD );
|
|
|
|
::typelib_typedescription_release( m_pGetValueTD );
|
|
|
|
::typelib_typedescription_release( m_pAnySeqTD );
|
|
|
|
::typelib_typedescription_release( m_pShortSeqTD );
|
|
|
|
::typelib_typedescription_release( m_pConvertToTD );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
(*m_pConverter->release)( m_pConverter );
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2003-04-15 16:12:57 +00:00
|
|
|
#if OSL_DEBUG_LEVEL > 1
|
2002-08-22 13:41:39 +00:00
|
|
|
OSL_ENSURE( m_receiver2adapters.empty(), "### still adapters out there!?" );
|
|
|
|
#endif
|
2001-06-22 15:21:02 +00:00
|
|
|
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
|
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//------------------------------------------------------------------------------
|
2002-08-22 13:41:39 +00:00
|
|
|
static inline AdapterImpl * lookup_adapter(
|
|
|
|
t_ptr_set ** pp_adapter_set,
|
|
|
|
t_ptr_map & map, void * key, Sequence< Type > const & rTypes )
|
|
|
|
SAL_THROW( () )
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
t_ptr_set & adapters_set = map[ key ];
|
|
|
|
*pp_adapter_set = &adapters_set;
|
|
|
|
if (adapters_set.empty())
|
|
|
|
return 0; // shortcut
|
|
|
|
// find matching adapter
|
|
|
|
Type const * pTypes = rTypes.getConstArray();
|
|
|
|
sal_Int32 nTypes = rTypes.getLength();
|
|
|
|
t_ptr_set::const_iterator iPos( adapters_set.begin() );
|
|
|
|
t_ptr_set::const_iterator const iEnd( adapters_set.end() );
|
|
|
|
while (iEnd != iPos)
|
|
|
|
{
|
|
|
|
AdapterImpl * that = reinterpret_cast< AdapterImpl * >( *iPos );
|
|
|
|
// iterate thru all types if that is a matching adapter
|
2003-12-01 16:59:47 +00:00
|
|
|
sal_Int32 nPosTypes;
|
|
|
|
for ( nPosTypes = nTypes; nPosTypes--; )
|
2002-08-22 13:41:39 +00:00
|
|
|
{
|
|
|
|
Type const & rType = pTypes[ nPosTypes ];
|
|
|
|
// find in adapter's type list
|
2003-12-01 16:59:47 +00:00
|
|
|
sal_Int32 nPos;
|
|
|
|
for ( nPos = that->m_nInterfaces; nPos--; )
|
2002-08-22 13:41:39 +00:00
|
|
|
{
|
|
|
|
if (::typelib_typedescriptionreference_isAssignableFrom(
|
|
|
|
rType.getTypeLibType(),
|
|
|
|
((typelib_TypeDescription *)that->
|
|
|
|
m_pInterfaces[ nPos ].m_pTypeDescr)->pWeakRef ))
|
|
|
|
{
|
|
|
|
// found
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nPos < 0) // type not found => next adapter
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (nPosTypes < 0) // all types found
|
|
|
|
return that;
|
|
|
|
++iPos;
|
|
|
|
}
|
|
|
|
return 0;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
|
|
|
|
// XInvocationAdapterFactory2 impl
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
Reference< XInterface > FactoryImpl::createAdapter(
|
2003-09-04 08:07:27 +00:00
|
|
|
const Reference< script::XInvocation > & xReceiver,
|
|
|
|
const Sequence< Type > & rTypes )
|
2000-09-18 14:29:57 +00:00
|
|
|
throw (RuntimeException)
|
|
|
|
{
|
|
|
|
Reference< XInterface > xRet;
|
|
|
|
if (xReceiver.is() && rTypes.getLength())
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
t_ptr_set * adapter_set;
|
|
|
|
AdapterImpl * that;
|
2002-08-22 11:28:54 +00:00
|
|
|
Reference< XInterface > xKey( xReceiver, UNO_QUERY );
|
|
|
|
{
|
|
|
|
ClearableMutexGuard guard( m_mutex );
|
2003-09-04 08:07:27 +00:00
|
|
|
that = lookup_adapter(
|
|
|
|
&adapter_set, m_receiver2adapters, xKey.get(), rTypes );
|
2002-08-22 13:41:39 +00:00
|
|
|
if (0 == that) // no entry
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
|
|
|
guard.clear();
|
2002-08-22 13:41:39 +00:00
|
|
|
// create adapter; already acquired: m_nRef == 1
|
2003-09-04 08:07:27 +00:00
|
|
|
AdapterImpl * pNew =
|
|
|
|
new AdapterImpl( xKey.get(), xReceiver, rTypes, this );
|
2002-08-22 11:28:54 +00:00
|
|
|
// lookup again
|
2006-06-19 23:02:47 +00:00
|
|
|
ClearableMutexGuard guard2( m_mutex );
|
2003-09-04 08:07:27 +00:00
|
|
|
that = lookup_adapter(
|
|
|
|
&adapter_set, m_receiver2adapters, xKey.get(), rTypes );
|
2002-08-22 13:41:39 +00:00
|
|
|
if (0 == that) // again no entry
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
pair< t_ptr_set::iterator, bool > insertion(
|
|
|
|
adapter_set->insert( pNew ) );
|
2002-08-22 11:28:54 +00:00
|
|
|
OSL_ASSERT( insertion.second );
|
2002-08-22 13:41:39 +00:00
|
|
|
that = pNew;
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
that->acquire();
|
2006-06-19 23:02:47 +00:00
|
|
|
guard2.clear();
|
2002-08-22 13:41:39 +00:00
|
|
|
delete pNew; // has never been inserted
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
else // found adapter
|
2002-08-22 11:28:54 +00:00
|
|
|
{
|
2002-08-22 13:41:39 +00:00
|
|
|
that->acquire();
|
2002-08-22 11:28:54 +00:00
|
|
|
}
|
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
// map one interface to C++
|
|
|
|
uno_Interface * pUnoI = &that->m_pInterfaces[ 0 ];
|
2003-09-04 08:07:27 +00:00
|
|
|
m_aUno2Cpp.mapInterface(
|
|
|
|
(void **)&xRet, pUnoI, ::getCppuType( &xRet ) );
|
2002-08-22 13:41:39 +00:00
|
|
|
that->release();
|
2002-08-22 11:28:54 +00:00
|
|
|
OSL_ASSERT( xRet.is() );
|
|
|
|
if (! xRet.is())
|
2000-09-18 14:29:57 +00:00
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
throw RuntimeException(
|
2003-09-04 08:07:27 +00:00
|
|
|
OUSTR("mapping UNO to C++ failed!"),
|
|
|
|
Reference< XInterface >() );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return xRet;
|
|
|
|
}
|
2002-08-22 13:41:39 +00:00
|
|
|
// XInvocationAdapterFactory impl
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2002-08-22 13:41:39 +00:00
|
|
|
Reference< XInterface > FactoryImpl::createAdapter(
|
|
|
|
const Reference< script::XInvocation > & xReceiver, const Type & rType )
|
|
|
|
throw (RuntimeException)
|
|
|
|
{
|
|
|
|
return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) );
|
|
|
|
}
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
// XServiceInfo
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
OUString FactoryImpl::getImplementationName()
|
|
|
|
throw (RuntimeException)
|
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
return invadp_getImplementationName();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
sal_Bool FactoryImpl::supportsService( const OUString & rServiceName )
|
|
|
|
throw (RuntimeException)
|
|
|
|
{
|
|
|
|
const Sequence< OUString > & rSNL = getSupportedServiceNames();
|
|
|
|
const OUString * pArray = rSNL.getConstArray();
|
|
|
|
for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
if (pArray[nPos].equals( rServiceName ))
|
2000-09-18 14:29:57 +00:00
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
return sal_False;
|
|
|
|
}
|
2003-09-04 08:07:27 +00:00
|
|
|
//______________________________________________________________________________
|
2000-09-18 14:29:57 +00:00
|
|
|
Sequence< OUString > FactoryImpl::getSupportedServiceNames()
|
|
|
|
throw (RuntimeException)
|
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
return invadp_getSupportedServiceNames();
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//==============================================================================
|
2000-09-18 14:29:57 +00:00
|
|
|
static Reference< XInterface > SAL_CALL FactoryImpl_create(
|
2002-08-22 11:28:54 +00:00
|
|
|
const Reference< XComponentContext > & xContext )
|
2000-09-18 14:29:57 +00:00
|
|
|
throw (Exception)
|
|
|
|
{
|
2001-06-22 15:21:02 +00:00
|
|
|
Reference< XInterface > rRet;
|
|
|
|
{
|
|
|
|
MutexGuard guard( Mutex::getGlobalMutex() );
|
|
|
|
static WeakReference < XInterface > rwInstance;
|
|
|
|
rRet = rwInstance;
|
|
|
|
|
|
|
|
if( ! rRet.is() )
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
rRet = (::cppu::OWeakObject *)new FactoryImpl( xContext );
|
2001-06-22 15:21:02 +00:00
|
|
|
rwInstance = rRet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rRet;
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//##############################################################################
|
|
|
|
//##############################################################################
|
|
|
|
//##############################################################################
|
2000-09-18 14:29:57 +00:00
|
|
|
|
2002-08-22 11:28:54 +00:00
|
|
|
static struct ::cppu::ImplementationEntry g_entries[] =
|
2001-06-22 15:21:02 +00:00
|
|
|
{
|
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
::stoc_invadp::FactoryImpl_create,
|
|
|
|
::stoc_invadp::invadp_getImplementationName,
|
2002-08-22 11:28:54 +00:00
|
|
|
::stoc_invadp::invadp_getSupportedServiceNames,
|
2003-09-04 08:07:27 +00:00
|
|
|
::cppu::createSingleComponentFactory,
|
|
|
|
&::stoc_invadp::g_moduleCount.modCnt , 0
|
2001-06-22 15:21:02 +00:00
|
|
|
},
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }
|
|
|
|
};
|
2000-09-18 14:29:57 +00:00
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
2011-12-27 15:42:14 +01:00
|
|
|
SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload(
|
2002-08-22 11:28:54 +00:00
|
|
|
TimeValue *pTime )
|
2001-06-22 15:21:02 +00:00
|
|
|
{
|
2003-09-04 08:07:27 +00:00
|
|
|
return ::stoc_invadp::g_moduleCount.canUnload(
|
|
|
|
&::stoc_invadp::g_moduleCount, pTime );
|
2001-06-22 15:21:02 +00:00
|
|
|
}
|
|
|
|
|
2003-09-04 08:07:27 +00:00
|
|
|
//==============================================================================
|
2011-04-21 16:06:40 +02:00
|
|
|
SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
|
2000-09-18 14:29:57 +00:00
|
|
|
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
|
|
|
|
{
|
2002-08-22 11:28:54 +00:00
|
|
|
return ::cppu::component_getFactoryHelper(
|
|
|
|
pImplName, pServiceManager, pRegistryKey , g_entries );
|
2000-09-18 14:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
2010-10-14 08:30:07 +02:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|