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