1*61dff127SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*61dff127SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*61dff127SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*61dff127SAndrew Rist * distributed with this work for additional information 6*61dff127SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*61dff127SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*61dff127SAndrew Rist * "License"); you may not use this file except in compliance 9*61dff127SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*61dff127SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*61dff127SAndrew Rist * software distributed under the License is distributed on an 15*61dff127SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*61dff127SAndrew Rist * KIND, either express or implied. See the License for the 17*61dff127SAndrew Rist * specific language governing permissions and limitations 18*61dff127SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*61dff127SAndrew Rist *************************************************************/ 21*61dff127SAndrew Rist 22*61dff127SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_bridges.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "component.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" 32cdf0e10cSrcweir #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 35cdf0e10cSrcweir #include "osl/diagnose.h" 36cdf0e10cSrcweir #include "osl/interlck.h" 37cdf0e10cSrcweir #include "rtl/ustring.h" 38cdf0e10cSrcweir #include "sal/types.h" 39cdf0e10cSrcweir #include "typelib/typedescription.h" 40cdf0e10cSrcweir #include "uno/dispatcher.h" 41cdf0e10cSrcweir #include "uno/environment.h" 42cdf0e10cSrcweir #include "uno/mapping.h" 43cdf0e10cSrcweir 44cdf0e10cSrcweir namespace bridges { namespace cpp_uno { namespace shared { 45cdf0e10cSrcweir 46cdf0e10cSrcweir void freeMapping(uno_Mapping * pMapping) 47cdf0e10cSrcweir { 48cdf0e10cSrcweir delete static_cast< Bridge::Mapping * >( pMapping )->pBridge; 49cdf0e10cSrcweir } 50cdf0e10cSrcweir 51cdf0e10cSrcweir void acquireMapping(uno_Mapping * pMapping) 52cdf0e10cSrcweir { 53cdf0e10cSrcweir static_cast< Bridge::Mapping * >( pMapping )->pBridge->acquire(); 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir void releaseMapping(uno_Mapping * pMapping) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir static_cast< Bridge::Mapping * >( pMapping )->pBridge->release(); 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir void cpp2unoMapping( 62cdf0e10cSrcweir uno_Mapping * pMapping, void ** ppUnoI, void * pCppI, 63cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr) 64cdf0e10cSrcweir { 65cdf0e10cSrcweir OSL_ENSURE( ppUnoI && pTypeDescr, "### null ptr!" ); 66cdf0e10cSrcweir if (*ppUnoI) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir (*reinterpret_cast< uno_Interface * >( *ppUnoI )->release)( 69cdf0e10cSrcweir reinterpret_cast< uno_Interface * >( *ppUnoI ) ); 70cdf0e10cSrcweir *ppUnoI = 0; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir if (pCppI) 73cdf0e10cSrcweir { 74cdf0e10cSrcweir Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge; 75cdf0e10cSrcweir 76cdf0e10cSrcweir // get object id of interface to be wrapped 77cdf0e10cSrcweir rtl_uString * pOId = 0; 78cdf0e10cSrcweir (*pBridge->pCppEnv->getObjectIdentifier)( 79cdf0e10cSrcweir pBridge->pCppEnv, &pOId, pCppI ); 80cdf0e10cSrcweir OSL_ASSERT( pOId ); 81cdf0e10cSrcweir 82cdf0e10cSrcweir // try to get any known interface from target environment 83cdf0e10cSrcweir (*pBridge->pUnoEnv->getRegisteredInterface)( 84cdf0e10cSrcweir pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr ); 85cdf0e10cSrcweir 86cdf0e10cSrcweir if (! *ppUnoI) // no existing interface, register new proxy interface 87cdf0e10cSrcweir { 88cdf0e10cSrcweir // try to publish a new proxy (refcount initially 1) 89cdf0e10cSrcweir uno_Interface * pSurrogate 90cdf0e10cSrcweir = bridges::cpp_uno::shared::UnoInterfaceProxy::create( 91cdf0e10cSrcweir pBridge, 92cdf0e10cSrcweir static_cast< ::com::sun::star::uno::XInterface * >( pCppI ), 93cdf0e10cSrcweir pTypeDescr, pOId ); 94cdf0e10cSrcweir 95cdf0e10cSrcweir // proxy may be exchanged during registration 96cdf0e10cSrcweir (*pBridge->pUnoEnv->registerProxyInterface)( 97cdf0e10cSrcweir pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ), 98cdf0e10cSrcweir freeUnoInterfaceProxy, pOId, 99cdf0e10cSrcweir pTypeDescr ); 100cdf0e10cSrcweir 101cdf0e10cSrcweir *ppUnoI = pSurrogate; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir ::rtl_uString_release( pOId ); 104cdf0e10cSrcweir } 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 107cdf0e10cSrcweir void uno2cppMapping( 108cdf0e10cSrcweir uno_Mapping * pMapping, void ** ppCppI, void * pUnoI, 109cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir OSL_ASSERT( ppCppI && pTypeDescr ); 112cdf0e10cSrcweir if (*ppCppI) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir static_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )-> 115cdf0e10cSrcweir release(); 116cdf0e10cSrcweir *ppCppI = 0; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir if (pUnoI) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge; 121cdf0e10cSrcweir 122cdf0e10cSrcweir // get object id of uno interface to be wrapped 123cdf0e10cSrcweir rtl_uString * pOId = 0; 124cdf0e10cSrcweir (*pBridge->pUnoEnv->getObjectIdentifier)( 125cdf0e10cSrcweir pBridge->pUnoEnv, &pOId, pUnoI ); 126cdf0e10cSrcweir OSL_ASSERT( pOId ); 127cdf0e10cSrcweir 128cdf0e10cSrcweir // try to get any known interface from target environment 129cdf0e10cSrcweir (*pBridge->pCppEnv->getRegisteredInterface)( 130cdf0e10cSrcweir pBridge->pCppEnv, ppCppI, pOId, pTypeDescr ); 131cdf0e10cSrcweir 132cdf0e10cSrcweir if (! *ppCppI) // no existing interface, register new proxy interface 133cdf0e10cSrcweir { 134cdf0e10cSrcweir // try to publish a new proxy (ref count initially 1) 135cdf0e10cSrcweir com::sun::star::uno::XInterface * pProxy 136cdf0e10cSrcweir = bridges::cpp_uno::shared::CppInterfaceProxy::create( 137cdf0e10cSrcweir pBridge, static_cast< uno_Interface * >( pUnoI ), 138cdf0e10cSrcweir pTypeDescr, pOId ); 139cdf0e10cSrcweir 140cdf0e10cSrcweir // proxy may be exchanged during registration 141cdf0e10cSrcweir (*pBridge->pCppEnv->registerProxyInterface)( 142cdf0e10cSrcweir pBridge->pCppEnv, reinterpret_cast< void ** >( &pProxy ), 143cdf0e10cSrcweir freeCppInterfaceProxy, pOId, 144cdf0e10cSrcweir pTypeDescr ); 145cdf0e10cSrcweir 146cdf0e10cSrcweir *ppCppI = pProxy; 147cdf0e10cSrcweir } 148cdf0e10cSrcweir ::rtl_uString_release( pOId ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir uno_Mapping * Bridge::createMapping( 153cdf0e10cSrcweir uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv, 154cdf0e10cSrcweir bool bExportCpp2Uno) SAL_THROW(()) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir Bridge * bridge = new Bridge(pCppEnv, pUnoEnv, bExportCpp2Uno); 157cdf0e10cSrcweir return bExportCpp2Uno ? &bridge->aCpp2Uno : &bridge->aUno2Cpp; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir void Bridge::acquire() SAL_THROW(()) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir if (1 == osl_incrementInterlockedCount( &nRef )) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir if (bExportCpp2Uno) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir uno_Mapping * pMapping = &aCpp2Uno; 167cdf0e10cSrcweir ::uno_registerMapping( 168cdf0e10cSrcweir &pMapping, freeMapping, (uno_Environment *)pCppEnv, 169cdf0e10cSrcweir (uno_Environment *)pUnoEnv, 0 ); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir else 172cdf0e10cSrcweir { 173cdf0e10cSrcweir uno_Mapping * pMapping = &aUno2Cpp; 174cdf0e10cSrcweir ::uno_registerMapping( 175cdf0e10cSrcweir &pMapping, freeMapping, (uno_Environment *)pUnoEnv, 176cdf0e10cSrcweir (uno_Environment *)pCppEnv, 0 ); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir } 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir void Bridge::release() SAL_THROW(()) 182cdf0e10cSrcweir { 183cdf0e10cSrcweir if (! osl_decrementInterlockedCount( &nRef )) 184cdf0e10cSrcweir { 185cdf0e10cSrcweir ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp ); 186cdf0e10cSrcweir } 187cdf0e10cSrcweir } 188cdf0e10cSrcweir 189cdf0e10cSrcweir Bridge::Bridge( 190cdf0e10cSrcweir uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_, 191cdf0e10cSrcweir bool bExportCpp2Uno_) SAL_THROW(()) 192cdf0e10cSrcweir : nRef( 1 ) 193cdf0e10cSrcweir , pCppEnv( pCppEnv_ ) 194cdf0e10cSrcweir , pUnoEnv( pUnoEnv_ ) 195cdf0e10cSrcweir , bExportCpp2Uno( bExportCpp2Uno_ ) 196cdf0e10cSrcweir { 197cdf0e10cSrcweir bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire( 198cdf0e10cSrcweir &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 199cdf0e10cSrcweir 200cdf0e10cSrcweir aCpp2Uno.pBridge = this; 201cdf0e10cSrcweir aCpp2Uno.acquire = acquireMapping; 202cdf0e10cSrcweir aCpp2Uno.release = releaseMapping; 203cdf0e10cSrcweir aCpp2Uno.mapInterface = cpp2unoMapping; 204cdf0e10cSrcweir 205cdf0e10cSrcweir aUno2Cpp.pBridge = this; 206cdf0e10cSrcweir aUno2Cpp.acquire = acquireMapping; 207cdf0e10cSrcweir aUno2Cpp.release = releaseMapping; 208cdf0e10cSrcweir aUno2Cpp.mapInterface = uno2cppMapping; 209cdf0e10cSrcweir 210cdf0e10cSrcweir (*((uno_Environment *)pCppEnv)->acquire)( (uno_Environment *)pCppEnv ); 211cdf0e10cSrcweir (*((uno_Environment *)pUnoEnv)->acquire)( (uno_Environment *)pUnoEnv ); 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 214cdf0e10cSrcweir Bridge::~Bridge() SAL_THROW(()) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir (*((uno_Environment *)pUnoEnv)->release)( (uno_Environment *)pUnoEnv ); 217cdf0e10cSrcweir (*((uno_Environment *)pCppEnv)->release)( (uno_Environment *)pCppEnv ); 218cdf0e10cSrcweir bridges::cpp_uno::shared::g_moduleCount.modCnt.release( 219cdf0e10cSrcweir &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir } } } 223