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