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
10*61dff127SAndrew Rist *
11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*61dff127SAndrew Rist *
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.
19*61dff127SAndrew Rist *
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
freeMapping(uno_Mapping * pMapping)46cdf0e10cSrcweir void freeMapping(uno_Mapping * pMapping)
47cdf0e10cSrcweir {
48cdf0e10cSrcweir delete static_cast< Bridge::Mapping * >( pMapping )->pBridge;
49cdf0e10cSrcweir }
50cdf0e10cSrcweir
acquireMapping(uno_Mapping * pMapping)51cdf0e10cSrcweir void acquireMapping(uno_Mapping * pMapping)
52cdf0e10cSrcweir {
53cdf0e10cSrcweir static_cast< Bridge::Mapping * >( pMapping )->pBridge->acquire();
54cdf0e10cSrcweir }
55cdf0e10cSrcweir
releaseMapping(uno_Mapping * pMapping)56cdf0e10cSrcweir void releaseMapping(uno_Mapping * pMapping)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir static_cast< Bridge::Mapping * >( pMapping )->pBridge->release();
59cdf0e10cSrcweir }
60cdf0e10cSrcweir
cpp2unoMapping(uno_Mapping * pMapping,void ** ppUnoI,void * pCppI,typelib_InterfaceTypeDescription * pTypeDescr)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
uno2cppMapping(uno_Mapping * pMapping,void ** ppCppI,void * pUnoI,typelib_InterfaceTypeDescription * pTypeDescr)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
createMapping(uno_ExtEnvironment * pCppEnv,uno_ExtEnvironment * pUnoEnv,bool bExportCpp2Uno)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
acquire()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
release()181cdf0e10cSrcweir void Bridge::release() SAL_THROW(())
182cdf0e10cSrcweir {
183cdf0e10cSrcweir if (! osl_decrementInterlockedCount( &nRef ))
184cdf0e10cSrcweir {
185cdf0e10cSrcweir ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp );
186cdf0e10cSrcweir }
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
Bridge(uno_ExtEnvironment * pCppEnv_,uno_ExtEnvironment * pUnoEnv_,bool bExportCpp2Uno_)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
~Bridge()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