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