diff options
Diffstat (limited to 'bridges/source/remote/static')
-rw-r--r-- | bridges/source/remote/static/helper.cxx | 212 | ||||
-rw-r--r-- | bridges/source/remote/static/makefile.mk | 65 | ||||
-rw-r--r-- | bridges/source/remote/static/mapping.cxx | 221 | ||||
-rw-r--r-- | bridges/source/remote/static/proxy.cxx | 347 | ||||
-rw-r--r-- | bridges/source/remote/static/remote.cxx | 170 | ||||
-rw-r--r-- | bridges/source/remote/static/remote_types.cxx | 99 | ||||
-rw-r--r-- | bridges/source/remote/static/remote_types.hxx | 92 | ||||
-rw-r--r-- | bridges/source/remote/static/stub.cxx | 339 |
8 files changed, 1545 insertions, 0 deletions
diff --git a/bridges/source/remote/static/helper.cxx b/bridges/source/remote/static/helper.cxx new file mode 100644 index 000000000000..c54075ce04a7 --- /dev/null +++ b/bridges/source/remote/static/helper.cxx @@ -0,0 +1,212 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: helper.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#include <rtl/alloc.h> +#include <osl/diagnose.h> + +#include <bridges/remote/helper.hxx> + +#include <bridges/remote/stub.hxx> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/remote.hxx> + +#include <com/sun/star/uno/Sequence.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace bridges_remote +{ + +void SAL_CALL remote_createStub ( + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pTypeRef, + uno_Environment *pEnvRemote, + ReleaseRemoteCallbackFunc releaseRemoteCallback ) +{ + typelib_TypeDescription *pType = 0; + typelib_typedescriptionreference_getDescription( &pType, pTypeRef ); + + (void) pEnvRemote->pExtEnv->getRegisteredInterface( + pEnvRemote->pExtEnv, + (void **)ppRemoteI, + pOid, + (typelib_InterfaceTypeDescription* )pType ); + + if( *ppRemoteI ) + { + if( (*ppRemoteI)->acquire == acquireRemote2RemoteStub ) { + + if( releaseRemoteCallback ) + { + // use the callback handler, the bridge wants to send the call immeadiatly + releaseRemoteCallback( *ppRemoteI , pOid, pTypeRef , pEnvRemote ); + } + else + { + ((::bridges_remote::Remote2RemoteStub *)*ppRemoteI)->releaseRemote(); + } + } + else + { + // Uno2RemoteStub + // no release necessary + } + } + else + { + remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl; + *ppRemoteI = + new ::bridges_remote::Remote2RemoteStub( + pOid, + (typelib_InterfaceTypeDescription * ) pType, + pEnvRemote, + pImpl->m_sendRequest); + + // ppRemoteI may change during registration + pEnvRemote->pExtEnv->registerProxyInterface( + pEnvRemote->pExtEnv, + (void **) ppRemoteI, + freeRemote2RemoteStub, + pOid, + (typelib_InterfaceTypeDescription * ) pType ); + } + + typelib_typedescription_release( pType ); +} + +void SAL_CALL remote_sendQueryInterface( + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pTypeRef, + uno_Any **ppException + ) +{ + OSL_ASSERT( ppRemoteI ); + + typelib_InterfaceTypeDescription *pType = 0; + typelib_typedescriptionreference_getDescription( (typelib_TypeDescription ** )&pType, pTypeRef ); + + if( *ppRemoteI ) + { + (*ppRemoteI)->release( *ppRemoteI ); + (*ppRemoteI) = 0; + } + + remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl; + + Type type = ::getCppuType( (Reference < XInterface > *)0 ); + + // get type for queryInterface + OUString sCompleteMethodName = type.getTypeName(); + sCompleteMethodName += OUString::createFromAscii("::queryInterface"); + + typelib_InterfaceMemberTypeDescription *pMemberType = 0; + typelib_typedescription_getByName( + (typelib_TypeDescription **) &pMemberType, + sCompleteMethodName.pData ); + + OSL_ASSERT( pMemberType ); + + uno_Any anyInterface; + anyInterface.pType = 0; + anyInterface.pData = 0; + + void *pReturn = &anyInterface; + void *ppArgs[1]; + + ppArgs[0] = 0; + typelib_TypeDescriptionReference *pRef = 0; + typelib_typedescriptionreference_new( &pRef , + pType->aBase.eTypeClass, + pType->aBase.pTypeName); + + ppArgs[0] = &pRef; + +// uno_Any anyException; +// uno_Any *pAnyException = &anyException; + + // do the queryInterface + pImpl->m_sendRequest( + pEnvRemote, + (typelib_TypeDescription * ) pMemberType, + pOid, + pType, + pReturn, + ppArgs, + ppException ); + + + // now release everything + typelib_typedescriptionreference_release( pRef ); + typelib_typedescription_release( (typelib_TypeDescription * ) pMemberType ); + + if( *ppException ) + { + *ppRemoteI = 0; + } + else + { + // set out parameter + if( typelib_TypeClass_INTERFACE == anyInterface.pType->eTypeClass ) + { + *ppRemoteI = ( remote_Interface * ) anyInterface.pReserved; + } + typelib_typedescriptionreference_release( anyInterface.pType ); + } + + typelib_typedescription_release( (typelib_TypeDescription * ) pType ); +} + + +void SAL_CALL remote_retrieveOidFromProxy( + remote_Interface *pRemoteI, + rtl_uString **ppOid ) +{ + if( pRemoteI->acquire == acquireRemote2RemoteStub ) + { + // Remote2RemoteStub + ::bridges_remote::Remote2RemoteStub *pStub = (::bridges_remote::Remote2RemoteStub * ) pRemoteI; + rtl_uString_newFromString( ppOid , pStub->m_sOid.pData ); + } + else + { + // Uno2RemoteStub + ::bridges_remote::Uno2RemoteStub *pStub = (::bridges_remote::Uno2RemoteStub * ) pRemoteI; + rtl_uString_newFromString( ppOid , pStub->m_sOid.pData ); + pRemoteI->acquire( pRemoteI ); + } +} + +} diff --git a/bridges/source/remote/static/makefile.mk b/bridges/source/remote/static/makefile.mk new file mode 100644 index 000000000000..56237bb0a859 --- /dev/null +++ b/bridges/source/remote/static/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.8 $ +# +# This file is part of OpenOffice.org. +# +# 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. +# +# 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). +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=bridges +TARGET=bridges_remote_static +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/proxy.obj \ + $(SLO)$/stub.obj \ + $(SLO)$/remote.obj \ + $(SLO)$/mapping.obj \ + $(SLO)$/helper.obj \ + $(SLO)$/remote_types.obj + +# Forte6 update 1 on Solaris Intel dies with internal compiler error +# on stub.cxx if optimization is on. Switch it off for now. +# To be reevaluated on compiler upgrade +.IF "$(OS)$(CPU)"=="SOLARISI" +NOOPTFILES=\ + $(SLO)$/stub.obj +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/bridges/source/remote/static/mapping.cxx b/bridges/source/remote/static/mapping.cxx new file mode 100644 index 000000000000..164481b5bfe0 --- /dev/null +++ b/bridges/source/remote/static/mapping.cxx @@ -0,0 +1,221 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: mapping.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#include <osl/diagnose.h> + +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/stub.hxx> +#include <bridges/remote/counter.hxx> +#include <bridges/remote/mapping.hxx> + +using namespace bridges_remote; + +extern "C" { + +static void SAL_CALL thisAcquire( uno_Mapping *pMap ) +{ + RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap ); + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + if( remoteToUno == pMap->mapInterface ) + { + uno_registerMapping( &pMap , + freeRemoteMapping, + p->pEnvRemote , + p->pEnvUno , + p->m_sPurpose.pData ); + } + else + { + uno_registerMapping( &pMap , + freeRemoteMapping, + p->pEnvUno , + p->pEnvRemote , + p->m_sPurpose.pData ); + } + + } +} + +static void SAL_CALL thisRelease( uno_Mapping *pMap ) +{ + RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap ); + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + uno_revokeMapping( pMap ); + } +} + +} + +namespace bridges_remote { + +void remoteToUno( uno_Mapping *pMapping, void **ppUnoI, void *pRemoteI, + typelib_InterfaceTypeDescription *pTypeDescr ) +{ + remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping; + + OSL_ASSERT( ppUnoI && pTypeDescr ); + if (*ppUnoI) + { + ((uno_Interface *)*ppUnoI)->release( (uno_Interface *)*ppUnoI ); + *ppUnoI = 0; + } + + if (pRemoteI && pTypeDescr) + { + // get object id of interface to be wrapped + rtl_uString * pOid = 0; + pRemoteMapping->pEnvRemote->pExtEnv->getObjectIdentifier( + pRemoteMapping->pEnvRemote->pExtEnv, + &pOid, + pRemoteI ); + + OSL_ASSERT(pOid); + if( ! pOid ) + { + return; + } + + // try to get any known interface from target environment + pRemoteMapping->pEnvUno->pExtEnv->getRegisteredInterface( + pRemoteMapping->pEnvUno->pExtEnv, + ppUnoI, + pOid, + pTypeDescr); + + if ( ! *ppUnoI) // already existing interface + { + // try to publish a new proxy; proxy may be exchanged during registration + *ppUnoI = new Remote2UnoProxy( + ( remote_Interface * ) pRemoteI, + pOid, + pTypeDescr , + pRemoteMapping->pEnvUno, + pRemoteMapping->pEnvRemote); + + pRemoteMapping->pEnvUno->pExtEnv->registerProxyInterface( + pRemoteMapping->pEnvUno->pExtEnv, + ppUnoI, + freeRemote2UnoProxy, + pOid, + pTypeDescr ); + + OSL_ASSERT( *ppUnoI ); + } + rtl_uString_release( pOid ); + } +} + +void unoToRemote( uno_Mapping *pMapping, void **ppRemoteI, void *pUnoI, + typelib_InterfaceTypeDescription *pTypeDescr ) +{ + remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping; + OSL_ASSERT( ppRemoteI && pTypeDescr ); + if (*ppRemoteI) + { + ((remote_Interface *)*ppRemoteI)->release( (remote_Interface *)*ppRemoteI); + *ppRemoteI = 0; + } + if (pUnoI && pTypeDescr) + { + // get object id of interface to be wrapped + rtl_uString * pOid = 0; + pRemoteMapping->pEnvUno->pExtEnv->getObjectIdentifier( + pRemoteMapping->pEnvUno->pExtEnv, + &pOid, + pUnoI ); + + OSL_ASSERT( pOid ); + if( ! pOid ) + { + return; + } + + pRemoteMapping->pEnvRemote->pExtEnv->getRegisteredInterface( + pRemoteMapping->pEnvRemote->pExtEnv, + (void**)ppRemoteI, + pOid, + pTypeDescr ); + + if( !*ppRemoteI ) + { + // try to publish a new proxy; + *ppRemoteI = new Uno2RemoteStub( + ( uno_Interface * ) pUnoI, + pOid, + pTypeDescr, + pRemoteMapping->pEnvUno, + pRemoteMapping->pEnvRemote ); + + // note : ppRemoteI may change during registration + pRemoteMapping->pEnvRemote->pExtEnv->registerProxyInterface( + pRemoteMapping->pEnvRemote->pExtEnv, + (void**) ppRemoteI, + freeUno2RemoteStub, + pOid, + pTypeDescr ); + } + + rtl_uString_release( pOid ); + } +} + +void freeRemoteMapping(uno_Mapping * mapping) { + delete reinterpret_cast< RemoteMapping * >(mapping); +} + +RemoteMapping::RemoteMapping( uno_Environment *pEnvUno_ , + uno_Environment *pEnvRemote_, + uno_MapInterfaceFunc func, + const ::rtl::OUString sPurpose) : + m_nRef( 1 ), + m_sPurpose( sPurpose ) +{ + pEnvUno = pEnvUno_; + pEnvRemote = pEnvRemote_; + + pEnvUno->acquire( pEnvUno ); + pEnvRemote->acquire( pEnvRemote ); + + aBase.mapInterface = func; + aBase.acquire = thisAcquire; + aBase.release = thisRelease; +} + +RemoteMapping::~RemoteMapping( ) +{ + pEnvUno->release( pEnvUno ); + pEnvRemote->release( pEnvRemote ); +} + +} diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx new file mode 100644 index 000000000000..6f07ba95d6ff --- /dev/null +++ b/bridges/source/remote/static/proxy.cxx @@ -0,0 +1,347 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: proxy.cxx,v $ + * $Revision: 1.13 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#if OSL_DEBUG_LEVEL == 0 +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> +#include <sal/alloca.h> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/context.h> + +#include <uno/data.h> +#include <uno/mapping.hxx> +#include <uno/environment.h> + +#include <com/sun/star/uno/Any.hxx> + +#include <bridges/remote/bridgeimpl.hxx> + +#include "remote_types.hxx" + +#if OSL_DEBUG_LEVEL > 1 +#include <bridges/remote/counter.hxx> +static MyCounter thisCounter( "DEBUG : Remote2UnoProxy"); +#endif + +using namespace ::bridges_remote; +using namespace ::com::sun::star::uno; + +extern "C" { + +void SAL_CALL remote_release( void *pRemoteI ) +{ + ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI ); +} + +} + +namespace bridges_remote { + +void freeRemote2UnoProxy(uno_ExtEnvironment *, void * proxy) { + delete static_cast< Remote2UnoProxy * >(proxy); +} + +void acquireRemote2UnoProxy( uno_Interface *pThis ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + p->m_pEnvUno->pExtEnv->registerProxyInterface( + p->m_pEnvUno->pExtEnv, + (void**)&pThis, + freeRemote2UnoProxy, + p->m_sOid.pData, + p->m_pType ); + assert( (uno_Interface *)p == pThis ); + } +} + +void releaseRemote2UnoProxy( uno_Interface *pThis ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis; + if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p ); + } +} + +void SAL_CALL dispatchRemote2UnoProxy( + uno_Interface * pUnoI, + typelib_TypeDescription const * pType, + void * pReturn, + void * ppArgs[], + uno_Any ** ppException ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI; + RemoteThreadCounter counter( p->m_pEnvRemote ); + + typelib_InterfaceMethodTypeDescription *pMethodType = 0; + typelib_InterfaceAttributeTypeDescription *pAttributeType = 0; + typelib_TypeDescription *pReturnType = 0; + typelib_TypeDescription **ppArgType = 0; + sal_Int32 nArgCount = 0; + sal_Bool *pbIsIn = 0; + sal_Bool *pbIsOut = 0; + sal_Bool *pbConversionNeeded = 0; + sal_Bool bConversionNeededForReturn = 0; + + //-------------------------------- + // Collect all needed types ! + //-------------------------------- + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass ) + { + pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType; + if( pReturn ) + { + TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + } + else + { + nArgCount = 1; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) ); + pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) ); + + pbIsIn[0] = sal_True; + pbIsOut[0] = sal_False; + ppArgType[0] = 0; + TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef ); + pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] ); + + } + } + if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass ) + { + pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType; + TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + nArgCount = pMethodType->nParams; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount ); + pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount ); + sal_Int32 i; + for( i = 0 ; i < nArgCount ; i ++ ) + { + ppArgType[i] = 0; + TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef ); + pbIsIn[i] = pMethodType->pParams[i].bIn; + pbIsOut[i] = pMethodType->pParams[i].bOut; + pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] ); + } + } + + void *pRemoteReturn = 0; + if( pReturnType ) + { + if( bConversionNeededForReturn ) + { + pRemoteReturn = alloca( pReturnType->nSize ); + } + else + { + pRemoteReturn = pReturn; + } + } + + void ** ppRemoteArgs = 0; + if( nArgCount ) + { + ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount ); + } + + sal_Int32 i; + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + ppRemoteArgs[i] = alloca( ppArgType[i]->nSize ); + + if( pbIsIn[i] ) { + uno_copyAndConvertData( + ppRemoteArgs[i], + ppArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + } + else + { + ppRemoteArgs[i] = ppArgs[i]; + } + } + + uno_Any any; + uno_Any *pAny = &any; + + p->m_pRemoteI->pDispatcher( p->m_pRemoteI, + pType, + pRemoteReturn, + ppRemoteArgs, + &pAny ); + + if( ! pAny ) + { + if( pReturn && bConversionNeededForReturn ) + { + uno_copyAndConvertData( + pReturn , + pRemoteReturn, + pReturnType, + p->m_mapRemote2Uno.get() ); + uno_destructData( pRemoteReturn , pReturnType , remote_release ); + } + + sal_Int32 j; + for( j = 0 ; j < nArgCount ; j ++ ) + { + if( pbConversionNeeded[j] ) + { + if( pbIsIn[j] ) { + if( pbIsOut[j] ) { + uno_destructData( ppArgs[j] , + ppArgType[j] , + 0 ); + uno_copyAndConvertData( ppArgs[j] , + ppRemoteArgs[j], + ppArgType[j], + p->m_mapRemote2Uno.get() ); + } + } + else // pure out + { + uno_copyAndConvertData( ppArgs[j] , + ppRemoteArgs[j], + ppArgType[j], + p->m_mapRemote2Uno.get() ); + } + uno_destructData( ppRemoteArgs[j], + ppArgType[j], + remote_release ); + } + } + *ppException = 0; + } + else + { + // ----------------------- + // an exception occured + // ----------------------- + typelib_TypeDescription *pAnyType = 0; + getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType ); + uno_copyAndConvertData( *ppException , + pAny , + pAnyType, + p->m_mapRemote2Uno.get() ); + uno_destructData( pAny , pAnyType , remote_release ); + typelib_typedescription_release( pAnyType ); + + // destruct remote in parameters ( out parameters have not been constructed ) + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] && pbIsIn[i] ) + { + uno_destructData( ppRemoteArgs[i], + ppArgType[i], + remote_release ); + } + } + } + + //-------------------------- + // release all acquired types + //-------------------------- + if( pReturnType ) + { + TYPELIB_DANGER_RELEASE( pReturnType ); + } + for( i = 0 ; i < nArgCount ; i ++ ) + { + TYPELIB_DANGER_RELEASE( ppArgType[ i] ); + } + +} + +Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote ) : + m_sOid( pOid ), + m_pType( pType ), + m_pRemoteI( pRemoteI ), + m_pEnvUno( pEnvUno ), + m_pEnvRemote( pEnvRemote ), + m_mapRemote2Uno( pEnvRemote, pEnvUno ), + m_mapUno2Remote( pEnvUno , pEnvRemote ), + m_nRef( 1 ) +{ + typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType ); + m_pEnvUno->acquire( m_pEnvUno ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = acquireRemote2UnoProxy; + release = releaseRemote2UnoProxy; + pDispatcher = dispatchRemote2UnoProxy; + + m_pEnvRemote->pExtEnv->registerInterface( + m_pEnvRemote->pExtEnv, + (void**)&m_pRemoteI, + m_sOid.pData, + m_pType ); + m_pRemoteI->acquire( m_pRemoteI ); + +#if OSL_DEBUG_LEVEL > 1 + thisCounter.acquire(); +#endif +} + +Remote2UnoProxy::~Remote2UnoProxy() +{ + // revoke external ref (oid) + m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI ); + + typelib_typedescription_release( (typelib_TypeDescription * )m_pType ); + m_pRemoteI->release( m_pRemoteI ); + m_pEnvUno->release( m_pEnvUno ); + m_pEnvRemote->release( m_pEnvRemote ); +#if OSL_DEBUG_LEVEL > 1 + thisCounter.release(); +#endif +} + +} // end namespace bridge_remote diff --git a/bridges/source/remote/static/remote.cxx b/bridges/source/remote/static/remote.cxx new file mode 100644 index 000000000000..1cb26b4ccd9c --- /dev/null +++ b/bridges/source/remote/static/remote.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: remote.cxx,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#if OSL_DEBUG_LEVEL == 0 +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> +#include <bridges/remote/remote.hxx> +#include <bridges/remote/counter.hxx> + +#if OSL_DEBUG_LEVEL > 1 +static MyCounter thisCounter( "DEBUG : Remote2RemoteStub"); +#endif + +using namespace bridges_remote; + +extern "C" { + +static void SAL_CALL thisRelease( remote_Interface *pThis ) +{ + Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis; + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis ); + + } +} + +static void SAL_CALL thisDispatch( + remote_Interface * pRemoteI, + typelib_TypeDescription const * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ) +{ + Remote2RemoteStub *pThis = ( Remote2RemoteStub * ) pRemoteI; + + pThis->m_dispatch( pThis->m_pEnvRemote, + pMemberType, + pThis->m_sOid.pData, + pThis->m_pType, + pReturn, + pArgs, + ppException ); +} + +} + +namespace bridges_remote { + +void acquireRemote2RemoteStub( remote_Interface *pThis ) +{ + Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + p->m_pEnvRemote->pExtEnv->registerProxyInterface( + p->m_pEnvRemote->pExtEnv, + (void**)&pThis, + freeRemote2RemoteStub, + p->m_sOid.pData, + p->m_pType ); + assert( (remote_Interface *)p == pThis ); + } +} + +void freeRemote2RemoteStub(uno_ExtEnvironment *, void * stub) { + delete static_cast< Remote2RemoteStub * >(stub); +} + +Remote2RemoteStub::Remote2RemoteStub( rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvRemote, + requestClientSideDispatcher dispatch ) : + m_sOid( pOid ), + m_pType( (typelib_InterfaceTypeDescription * ) pType ), + m_nRef( 1 ), + m_pEnvRemote( pEnvRemote ), + m_dispatch( dispatch ), + m_nReleaseRemote( 1 ) +{ + typelib_typedescription_acquire( ( typelib_TypeDescription * ) m_pType ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = acquireRemote2RemoteStub; + release = thisRelease; + pDispatcher = thisDispatch; +#if OSL_DEBUG_LEVEL > 1 + thisCounter.acquire(); +#endif +} + +Remote2RemoteStub::~Remote2RemoteStub() +{ + + // send a release via the connection ! + sal_Bool bNeedsRelease = sal_False; + if( ! m_pType->aBase.bComplete ) + { + // m_pType may be exchanged during complete, so it needs to be acquired + // (MT : Another thread may use m_pType during e.g. dispatch ! ). + typelib_typedescription_acquire( (typelib_TypeDescription*)m_pType ); + bNeedsRelease = sal_True; + typelib_typedescription_complete( (typelib_TypeDescription **) &m_pType ); + } + + uno_Any any; + uno_Any *pAny = &any; + + typelib_TypeDescription *pReleaseMethod = 0; + typelib_typedescriptionreference_getDescription( + &pReleaseMethod , + m_pType->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] ); + for( int i = 0 ; i < m_nReleaseRemote ; i ++ ) + { + thisDispatch( this, + pReleaseMethod, + 0, + 0, + &pAny ); + } + typelib_typedescription_release( pReleaseMethod ); + if( bNeedsRelease ) + { + typelib_typedescription_release( (typelib_TypeDescription * ) m_pType ); + } + + typelib_typedescription_release( (typelib_TypeDescription * ) m_pType ); + m_pEnvRemote->release( m_pEnvRemote ); +#if OSL_DEBUG_LEVEL > 1 + thisCounter.release(); +#endif +} + +void Remote2RemoteStub::releaseRemote() +{ + osl_incrementInterlockedCount( &m_nReleaseRemote ); +} + +} // end namespace bridges_remote diff --git a/bridges/source/remote/static/remote_types.cxx b/bridges/source/remote/static/remote_types.cxx new file mode 100644 index 000000000000..d2c8b17516de --- /dev/null +++ b/bridges/source/remote/static/remote_types.cxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: remote_types.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#include "remote_types.hxx" + +namespace bridges_remote { + +sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr ) +{ + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + { + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + sal_Bool bRel = remote_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return bRel; + } + default: + break; + } + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + // ...optimized... to avoid getDescription() calls! + typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr; + typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs; + for ( sal_Int32 nPos = pComp->nMembers; nPos--; ) + { + switch (pTypes[nPos]->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pTypes[nPos] ); + sal_Bool bRel = remote_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + if (bRel) + return sal_True; + break; + } + default: + break; + } + } + if (pComp->pBaseTypeDescription) + return remote_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription ); + break; + } + default: + OSL_ASSERT( 0 ); + } + return sal_False; +} + +} diff --git a/bridges/source/remote/static/remote_types.hxx b/bridges/source/remote/static/remote_types.hxx new file mode 100644 index 000000000000..b6276f51a55a --- /dev/null +++ b/bridges/source/remote/static/remote_types.hxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: remote_types.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_TYPES_HXX_ +#define _BRIDGES_REMOTE_TYPES_HXX_ + +#include <osl/diagnose.h> +#include <sal/types.h> +#include <typelib/typedescription.h> + +namespace bridges_remote +{ + +inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription *pTypeDescr ); +sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr ); + + +/** Determines whether given type might relate or relates to an interface, + i.e. values of this type are interface or may contain interface(s).<br> + @param pTypeDescr type description of type + @return true if type might relate to an interface, false otherwise +*/ +inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription * pTypeDescr ) +{ + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + return remote_relatesToInterface2( pTypeDescr ); + default: + return sal_False; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + return remote_relatesToInterface2( pTypeDescr ); + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + case typelib_TypeClass_INTERFACE: + return sal_True; + default: + return sal_False; + } +} + +/** Determines whether given type is a cpp simple type, e.g. int, enum.<br> + @param pTypeDescr type description of type + @return true if type is a cpp simple type, false otherwise +*/ +inline sal_Bool SAL_CALL remote_isSimpleType( typelib_TypeDescription * pTypeDescr ) +{ + return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM && + pTypeDescr->eTypeClass != typelib_TypeClass_STRING && + pTypeDescr->eTypeClass != typelib_TypeClass_ANY && + pTypeDescr->eTypeClass != typelib_TypeClass_TYPE); +} + +} +#endif diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx new file mode 100644 index 000000000000..471d564fc219 --- /dev/null +++ b/bridges/source/remote/static/stub.cxx @@ -0,0 +1,339 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: stub.cxx,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * 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. + * + * 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). + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" +#include <sal/alloca.h> +#include <osl/diagnose.h> + +#include <uno/data.h> +#include <uno/mapping.hxx> + +#include <bridges/remote/stub.hxx> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/context.h> +#include <bridges/remote/bridgeimpl.hxx> + +#include "remote_types.hxx" + +#if OSL_DEBUG_LEVEL > 1 +#include <bridges/remote/counter.hxx> +static MyCounter thisCounter( "DEBUG : Uno2RemoteStub"); +#endif + +using namespace ::com::sun::star::uno; +using namespace bridges_remote; + +extern "C" { + +void SAL_CALL thisRelease( remote_Interface *pThis ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis; + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis ); + } +} + +void SAL_CALL thisDispatch( + remote_Interface * pRemoteI, + typelib_TypeDescription const * pType, + void * pReturn, + void * ppArgs[], + uno_Any ** ppException ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI; + + RemoteThreadCounter counter( p->m_pEnvRemote ); + + typelib_InterfaceMethodTypeDescription *pMethodType = 0; + typelib_InterfaceAttributeTypeDescription *pAttributeType = 0; + typelib_TypeDescription *pReturnType = 0; + typelib_TypeDescription **ppArgType = 0; + sal_Int32 nArgCount = 0; + sal_Bool *pbIsIn = 0; + sal_Bool *pbIsOut = 0; + sal_Bool bConversionNeededForReturn = sal_False; + sal_Bool *pbConversionNeeded = 0; + + sal_Int32 i; + //-------------------------------- + // Collect all needed types ! + //-------------------------------- + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass ) + { + pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType; + if( pReturn ) + { + TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + } + else + { + nArgCount = 1; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) ); + pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsIn[0] = sal_True; + pbIsOut[0] = sal_False; + ppArgType[0] = 0; + TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef ); + pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] ); + } + } + if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass ) + { + pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType; + TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + nArgCount = pMethodType->nParams; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount ); + pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + + for( i = 0 ; i < nArgCount ; i ++ ) + { + ppArgType[i] = 0; + TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef ); + pbIsIn[i] = pMethodType->pParams[i].bIn; + pbIsOut[i] = pMethodType->pParams[i].bOut; + pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] ); + } + } + + // create Mapping + + void *pUnoReturn = 0; + void **ppUnoArgs = 0; + + if( pReturnType ) + { + if( bConversionNeededForReturn ) + { + pUnoReturn = alloca( pReturnType->nSize ); + } + else + { + pUnoReturn = pReturn; + } + } + + ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) ); + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + ppUnoArgs[i] = alloca( ppArgType[i]->nSize ); + if( pbIsIn[i] ) + { + uno_copyAndConvertData( + ppUnoArgs[i], + ppArgs[i], + ppArgType[i], + p->m_mapRemote2Uno.get() + ); + } + } + else + { + ppUnoArgs[i] = ppArgs[i]; + } + } + + // do the call + uno_Any any; + uno_Any *pAny = &any; + + p->m_pUnoI->pDispatcher( p->m_pUnoI, + pType, + pUnoReturn, + ppUnoArgs, + &pAny); + + if( ! pAny ) + { + // ------------------ + // No Exception + // ------------------ + + // Map return value + if( pReturnType && bConversionNeededForReturn ) + { + uno_copyAndConvertData( + pReturn , + pUnoReturn, + pReturnType, + p->m_mapUno2Remote.get() ); + uno_destructData( pUnoReturn , pReturnType, 0 ); + } + + // map arguments + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + if( pbIsIn[i] ) { + if( pbIsOut[i] ) { + uno_destructData( + ppArgs[i] , + ppArgType[i] , + remote_release ); + uno_copyAndConvertData( ppArgs[i] , + ppUnoArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + } + else // pure out + { + uno_copyAndConvertData( ppArgs[i] , + ppUnoArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + uno_destructData( ppUnoArgs[i], + ppArgType[i], + 0 ); + } + } + *ppException = 0; + } + else + { + // ----------------------- + // an exception occured + // ----------------------- + typelib_TypeDescription *pAnyType = 0; + getCppuType( (Any*) 0 ).getDescription( &pAnyType ); + uno_copyAndConvertData( *ppException , + pAny , + pAnyType, + p->m_mapUno2Remote.get() ); + uno_destructData( pAny , pAnyType , 0 ); + typelib_typedescription_release( pAnyType ); + + // destruct uno in parameters ( out parameters have not been constructed ) + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] && pbIsIn[i] ) + { + uno_destructData( ppUnoArgs[i], + ppArgType[i], + 0 ); + } + } + } + + //-------------------------- + // release all acquired types + //-------------------------- + if( pReturnType ) + { + TYPELIB_DANGER_RELEASE( pReturnType ); + } + for( i = 0 ; i < nArgCount ; i ++ ) + { + TYPELIB_DANGER_RELEASE( ppArgType[ i] ); + } +} + +} + +namespace bridges_remote { + +void acquireUno2RemoteStub( remote_Interface *pThis ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + + p->m_pEnvRemote->pExtEnv->registerProxyInterface( + p->m_pEnvRemote->pExtEnv, + (void**)&pThis, + freeUno2RemoteStub, + p->m_sOid.pData, + p->m_pType ); + + OSL_ASSERT( (remote_Interface*) p == pThis ); + } +} + +void freeUno2RemoteStub(uno_ExtEnvironment *, void * stub) { + delete static_cast< Uno2RemoteStub * >(stub); +} + +Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote ) : + m_sOid( pOid ), + m_pType( pType ), + m_pUnoI( pUnoI ), + m_nRef( 1 ), + m_pEnvUno( pEnvUno ), + m_pEnvRemote( pEnvRemote ), + m_mapRemote2Uno( pEnvRemote, pEnvUno ), + m_mapUno2Remote( pEnvUno, pEnvRemote ) +{ + typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType ); + m_pEnvUno->acquire( m_pEnvUno ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = acquireUno2RemoteStub; + release = thisRelease; + pDispatcher = thisDispatch; + + m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv, + (void **)&m_pUnoI, + m_sOid.pData, + m_pType ); + m_pUnoI->acquire( m_pUnoI ); +#if OSL_DEBUG_LEVEL > 1 + thisCounter.acquire(); +#endif +} + +Uno2RemoteStub::~Uno2RemoteStub() +{ + m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI ); + + typelib_typedescription_release( (typelib_TypeDescription * )m_pType ); + m_pUnoI->release( m_pUnoI ); + m_pEnvUno->release( m_pEnvUno ); + m_pEnvRemote->release( m_pEnvRemote ); +#if OSL_DEBUG_LEVEL > 1 + thisCounter.release(); +#endif +} + +} // end namespace bridges_remote |