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_testtools.hxx" 26 #include <osl/diagnose.h> 27 #include <osl/interlck.h> 28 #include <rtl/ustring.hxx> 29 #include <typelib/typedescription.h> 30 #include <uno/dispatcher.h> 31 #include <uno/environment.h> 32 #include <uno/mapping.h> 33 #include <uno/lbnames.h> 34 35 using namespace rtl; 36 37 38 namespace pseudo_uno 39 { 40 41 //================================================================================================== 42 struct pseudo_Mapping : public uno_Mapping 43 { 44 oslInterlockedCount nRef; 45 46 uno_ExtEnvironment * pFrom; 47 uno_ExtEnvironment * pTo; 48 49 pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ ); 50 ~pseudo_Mapping(); 51 }; 52 53 //==== a uno pseudo proxy ============================================================================= 54 struct pseudo_unoInterfaceProxy : public uno_Interface 55 { 56 oslInterlockedCount nRef; 57 pseudo_Mapping * pPseudoMapping; 58 59 // mapping information 60 uno_Interface * pUnoI; // wrapped interface 61 typelib_InterfaceTypeDescription * pTypeDescr; 62 OUString oid; 63 64 // ctor 65 inline pseudo_unoInterfaceProxy( pseudo_Mapping * pPseudoMapping_, 66 uno_Interface * pUnoI_, 67 typelib_InterfaceTypeDescription * pTypeDescr_, 68 const OUString & rOId_ ); 69 }; 70 //-------------------------------------------------------------------------------------------------- 71 static void SAL_CALL pseudo_unoInterfaceProxy_dispatch( 72 uno_Interface * pUnoI, 73 const typelib_TypeDescription * pMemberType, 74 void * pReturn, 75 void * pArgs[], 76 uno_Any ** ppException ) 77 { 78 pseudo_unoInterfaceProxy * pThis = static_cast< pseudo_unoInterfaceProxy * >( pUnoI ); 79 (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberType, pReturn, pArgs, ppException ); 80 } 81 82 //-------------------------------------------------------------------------------------------------- 83 static void SAL_CALL pseudo_unoInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy ) 84 { 85 pseudo_unoInterfaceProxy * pThis = 86 static_cast< pseudo_unoInterfaceProxy * >( 87 reinterpret_cast< uno_Interface * >( pProxy ) ); 88 OSL_ASSERT( pEnv == pThis->pPseudoMapping->pTo ); 89 90 (*pThis->pPseudoMapping->pFrom->revokeInterface)( pThis->pPseudoMapping->pFrom, pThis->pUnoI ); 91 (*pThis->pUnoI->release)( pThis->pUnoI ); 92 typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr ); 93 (*pThis->pPseudoMapping->release)( pThis->pPseudoMapping ); 94 95 #if OSL_DEBUG_LEVEL > 1 96 *(int *)pProxy = 0xdeadbabe; 97 #endif 98 delete pThis; 99 } 100 //-------------------------------------------------------------------------------------------------- 101 static void SAL_CALL pseudo_unoInterfaceProxy_acquire( uno_Interface * pUnoI ) 102 { 103 if (1 == osl_incrementInterlockedCount( &static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef )) 104 { 105 // rebirth of proxy zombie 106 // register at uno env 107 void * pThis = static_cast< uno_Interface * >( pUnoI ); 108 (*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->registerProxyInterface)( 109 static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo, 110 &pThis, pseudo_unoInterfaceProxy_free, 111 static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->oid.pData, 112 static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pTypeDescr ); 113 OSL_ASSERT( pThis == static_cast< uno_Interface * >( pUnoI ) ); 114 } 115 } 116 //-------------------------------------------------------------------------------------------------- 117 static void SAL_CALL pseudo_unoInterfaceProxy_release( uno_Interface * pUnoI ) 118 { 119 if (! osl_decrementInterlockedCount( & static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef )) 120 { 121 // revoke from uno env on last release 122 (*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->revokeInterface)( 123 static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo, pUnoI ); 124 } 125 } 126 //__________________________________________________________________________________________________ 127 inline pseudo_unoInterfaceProxy::pseudo_unoInterfaceProxy( 128 pseudo_Mapping * pPseudoMapping_, uno_Interface * pUnoI_, 129 typelib_InterfaceTypeDescription * pTypeDescr_, const OUString & rOId_ ) 130 : nRef( 1 ) 131 , pPseudoMapping( pPseudoMapping_ ) 132 , pUnoI( pUnoI_ ) 133 , pTypeDescr( pTypeDescr_ ) 134 , oid( rOId_ ) 135 { 136 (*pPseudoMapping->acquire)( pPseudoMapping ); 137 typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr ); 138 (*pPseudoMapping->pFrom->registerInterface)( 139 pPseudoMapping->pFrom, reinterpret_cast< void ** >( &pUnoI ), oid.pData, pTypeDescr ); 140 (*pUnoI->acquire)( pUnoI ); 141 142 // uno_Interface 143 uno_Interface::acquire = pseudo_unoInterfaceProxy_acquire; 144 uno_Interface::release = pseudo_unoInterfaceProxy_release; 145 uno_Interface::pDispatcher = pseudo_unoInterfaceProxy_dispatch; 146 } 147 148 //-------------------------------------------------------------------------------------------------- 149 static void SAL_CALL pseudo_Mapping_mapInterface( 150 uno_Mapping * pMapping, void ** ppOut, 151 void * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr ) 152 { 153 OSL_ASSERT( ppOut && pTypeDescr ); 154 if (*ppOut) 155 { 156 (*reinterpret_cast< uno_Interface * >( *ppOut )->release)( 157 reinterpret_cast< uno_Interface * >( *ppOut ) ); 158 *ppOut = 0; 159 } 160 if (pUnoI && pTypeDescr) 161 { 162 // get object id of uno interface to be wrapped 163 rtl_uString * pOId = 0; 164 (*static_cast< pseudo_Mapping * >( pMapping )->pFrom->getObjectIdentifier)( 165 static_cast< pseudo_Mapping * >( pMapping )->pFrom, &pOId, pUnoI ); 166 OSL_ASSERT( pOId ); 167 168 if (pOId) 169 { 170 // try to get any known interface from target environment 171 (*static_cast< pseudo_Mapping * >( pMapping )->pTo->getRegisteredInterface)( 172 static_cast< pseudo_Mapping * >( pMapping )->pTo, ppOut, pOId, pTypeDescr ); 173 if (! *ppOut) // no existing interface, register new proxy interface 174 { 175 // try to publish a new proxy (ref count initially 1) 176 void * pProxy = new pseudo_unoInterfaceProxy( 177 static_cast< pseudo_Mapping * >( pMapping ), 178 reinterpret_cast< uno_Interface * >( pUnoI ), pTypeDescr, pOId ); 179 180 // proxy may be exchanged during registration 181 (*static_cast< pseudo_Mapping * >( pMapping )->pTo->registerProxyInterface)( 182 static_cast< pseudo_Mapping * >( pMapping )->pTo, 183 &pProxy, pseudo_unoInterfaceProxy_free, pOId, pTypeDescr ); 184 185 *ppOut = pProxy; 186 } 187 rtl_uString_release( pOId ); 188 } 189 } 190 } 191 //-------------------------------------------------------------------------------------------------- 192 static void SAL_CALL pseudo_Mapping_free( uno_Mapping * pMapping ) 193 { 194 delete static_cast< pseudo_Mapping * >( pMapping ); 195 } 196 //-------------------------------------------------------------------------------------------------- 197 static void SAL_CALL pseudo_Mapping_acquire( uno_Mapping * pMapping ) 198 { 199 if (1 == osl_incrementInterlockedCount( & static_cast< pseudo_Mapping * >( pMapping )->nRef )) 200 { 201 OUString aMappingPurpose( RTL_CONSTASCII_USTRINGPARAM("pseudo") ); 202 uno_registerMapping( &pMapping, 203 pseudo_Mapping_free, 204 (uno_Environment *)((pseudo_Mapping *)pMapping)->pFrom, 205 (uno_Environment *)((pseudo_Mapping *)pMapping)->pTo, 206 aMappingPurpose.pData ); 207 } 208 } 209 //-------------------------------------------------------------------------------------------------- 210 static void SAL_CALL pseudo_Mapping_release( uno_Mapping * pMapping ) 211 { 212 if (! osl_decrementInterlockedCount( & static_cast< pseudo_Mapping * >( pMapping )->nRef )) 213 { 214 uno_revokeMapping( pMapping ); 215 } 216 } 217 218 //__________________________________________________________________________________________________ 219 pseudo_Mapping::pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ ) 220 : nRef( 1 ) 221 , pFrom( pFrom_ ) 222 , pTo( pTo_ ) 223 { 224 (*((uno_Environment *)pFrom)->acquire)( (uno_Environment *)pFrom ); 225 (*((uno_Environment *)pTo)->acquire)( (uno_Environment *)pTo ); 226 // 227 uno_Mapping::acquire = pseudo_Mapping_acquire; 228 uno_Mapping::release = pseudo_Mapping_release; 229 uno_Mapping::mapInterface = pseudo_Mapping_mapInterface; 230 } 231 //__________________________________________________________________________________________________ 232 pseudo_Mapping::~pseudo_Mapping() 233 { 234 (*((uno_Environment *)pTo)->release)( (uno_Environment *)pTo ); 235 (*((uno_Environment *)pFrom)->release)( (uno_Environment *)pFrom ); 236 } 237 238 } 239 240 //################################################################################################## 241 extern "C" void SAL_CALL uno_initEnvironment( uno_Environment * pUnoEnv ) 242 { 243 OSL_ENSURE( sal_False, "### no impl: unexpected call!" ); 244 } 245 //################################################################################################## 246 extern "C" void SAL_CALL uno_ext_getMapping( 247 uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) 248 { 249 OSL_ASSERT( ppMapping && pFrom && pTo ); 250 if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv) 251 { 252 uno_Mapping * pMapping = 0; 253 254 if (0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, UNO_LB_UNO ) && 255 0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, UNO_LB_UNO )) 256 { 257 OUString aMappingPurpose( RTL_CONSTASCII_USTRINGPARAM("pseudo") ); 258 // ref count is initially 1 259 pMapping = new pseudo_uno::pseudo_Mapping( pFrom->pExtEnv, pTo->pExtEnv ); 260 uno_registerMapping( &pMapping, pseudo_uno::pseudo_Mapping_free, 261 (uno_Environment *)pFrom->pExtEnv, 262 (uno_Environment *)pTo->pExtEnv, 263 aMappingPurpose.pData ); 264 } 265 266 if (*ppMapping) 267 (*(*ppMapping)->release)( *ppMapping ); 268 *ppMapping = pMapping; 269 } 270 } 271