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 "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
24 : #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
25 :
26 : #include "com/sun/star/uno/XInterface.hpp"
27 : #include "osl/interlck.h"
28 : #include "rtl/ustring.h"
29 : #include "sal/types.h"
30 : #include "typelib/typedescription.h"
31 : #include "uno/dispatcher.h"
32 : #include "uno/environment.h"
33 : #include "uno/mapping.h"
34 :
35 : namespace bridges { namespace cpp_uno { namespace shared {
36 :
37 11598 : void freeMapping(uno_Mapping * pMapping)
38 : {
39 11598 : delete static_cast< Bridge::Mapping * >( pMapping )->pBridge;
40 11598 : }
41 :
42 74343 : void acquireMapping(uno_Mapping * pMapping)
43 : {
44 74343 : static_cast< Bridge::Mapping * >( pMapping )->pBridge->acquire();
45 74343 : }
46 :
47 85929 : void releaseMapping(uno_Mapping * pMapping)
48 : {
49 85929 : static_cast< Bridge::Mapping * >( pMapping )->pBridge->release();
50 85929 : }
51 :
52 222822 : void cpp2unoMapping(
53 : uno_Mapping * pMapping, void ** ppUnoI, void * pCppI,
54 : typelib_InterfaceTypeDescription * pTypeDescr)
55 : {
56 : assert(ppUnoI && pTypeDescr);
57 222822 : if (*ppUnoI)
58 : {
59 : (*static_cast< uno_Interface * >( *ppUnoI )->release)(
60 0 : static_cast< uno_Interface * >( *ppUnoI ) );
61 0 : *ppUnoI = 0;
62 : }
63 222822 : if (pCppI)
64 : {
65 222820 : Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
66 :
67 : // get object id of interface to be wrapped
68 222820 : rtl_uString * pOId = 0;
69 : (*pBridge->pCppEnv->getObjectIdentifier)(
70 222820 : pBridge->pCppEnv, &pOId, pCppI );
71 : assert(pOId);
72 :
73 : // try to get any known interface from target environment
74 : (*pBridge->pUnoEnv->getRegisteredInterface)(
75 222820 : pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr );
76 :
77 222820 : if (! *ppUnoI) // no existing interface, register new proxy interface
78 : {
79 : // try to publish a new proxy (refcount initially 1)
80 : uno_Interface * pSurrogate
81 : = bridges::cpp_uno::shared::UnoInterfaceProxy::create(
82 : pBridge,
83 : static_cast< ::com::sun::star::uno::XInterface * >( pCppI ),
84 192495 : pTypeDescr, pOId );
85 :
86 : // proxy may be exchanged during registration
87 : (*pBridge->pUnoEnv->registerProxyInterface)(
88 : pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ),
89 : freeUnoInterfaceProxy, pOId,
90 192495 : pTypeDescr );
91 :
92 192495 : *ppUnoI = pSurrogate;
93 : }
94 222820 : ::rtl_uString_release( pOId );
95 : }
96 222822 : }
97 :
98 171984 : void uno2cppMapping(
99 : uno_Mapping * pMapping, void ** ppCppI, void * pUnoI,
100 : typelib_InterfaceTypeDescription * pTypeDescr)
101 : {
102 : assert(ppCppI && pTypeDescr);
103 171984 : if (*ppCppI)
104 : {
105 : static_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )->
106 0 : release();
107 0 : *ppCppI = 0;
108 : }
109 171984 : if (pUnoI)
110 : {
111 171984 : Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
112 :
113 : // get object id of uno interface to be wrapped
114 171984 : rtl_uString * pOId = 0;
115 : (*pBridge->pUnoEnv->getObjectIdentifier)(
116 171984 : pBridge->pUnoEnv, &pOId, pUnoI );
117 : assert(pOId);
118 :
119 : // try to get any known interface from target environment
120 : (*pBridge->pCppEnv->getRegisteredInterface)(
121 171984 : pBridge->pCppEnv, ppCppI, pOId, pTypeDescr );
122 :
123 171984 : if (! *ppCppI) // no existing interface, register new proxy interface
124 : {
125 : // try to publish a new proxy (ref count initially 1)
126 : com::sun::star::uno::XInterface * pProxy
127 : = bridges::cpp_uno::shared::CppInterfaceProxy::create(
128 : pBridge, static_cast< uno_Interface * >( pUnoI ),
129 128338 : pTypeDescr, pOId );
130 :
131 : // proxy may be exchanged during registration
132 : (*pBridge->pCppEnv->registerProxyInterface)(
133 : pBridge->pCppEnv, reinterpret_cast< void ** >( &pProxy ),
134 : freeCppInterfaceProxy, pOId,
135 128338 : pTypeDescr );
136 :
137 128338 : *ppCppI = pProxy;
138 : }
139 171984 : ::rtl_uString_release( pOId );
140 : }
141 171984 : }
142 :
143 11688 : uno_Mapping * Bridge::createMapping(
144 : uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv,
145 : bool bExportCpp2Uno)
146 : {
147 11688 : Bridge * bridge = new Bridge(pCppEnv, pUnoEnv, bExportCpp2Uno);
148 : //coverity[leaked_storage]
149 11688 : return bExportCpp2Uno ? &bridge->aCpp2Uno : &bridge->aUno2Cpp;
150 : }
151 :
152 395176 : void Bridge::acquire()
153 : {
154 395176 : if (1 == osl_atomic_increment( &nRef ))
155 : {
156 0 : if (bExportCpp2Uno)
157 : {
158 0 : uno_Mapping * pMapping = &aCpp2Uno;
159 : ::uno_registerMapping(
160 : &pMapping, freeMapping, &pCppEnv->aBase,
161 0 : &pUnoEnv->aBase, 0 );
162 : }
163 : else
164 : {
165 0 : uno_Mapping * pMapping = &aUno2Cpp;
166 : ::uno_registerMapping(
167 : &pMapping, freeMapping, &pUnoEnv->aBase,
168 0 : &pCppEnv->aBase, 0 );
169 : }
170 : }
171 395176 : }
172 :
173 405759 : void Bridge::release()
174 : {
175 405759 : if (! osl_atomic_decrement( &nRef ))
176 : {
177 11598 : ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp );
178 : }
179 405759 : }
180 :
181 11688 : Bridge::Bridge(
182 : uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_,
183 : bool bExportCpp2Uno_)
184 : : nRef( 1 )
185 : , pCppEnv( pCppEnv_ )
186 : , pUnoEnv( pUnoEnv_ )
187 11688 : , bExportCpp2Uno( bExportCpp2Uno_ )
188 : {
189 11688 : aCpp2Uno.pBridge = this;
190 11688 : aCpp2Uno.acquire = acquireMapping;
191 11688 : aCpp2Uno.release = releaseMapping;
192 11688 : aCpp2Uno.mapInterface = cpp2unoMapping;
193 :
194 11688 : aUno2Cpp.pBridge = this;
195 11688 : aUno2Cpp.acquire = acquireMapping;
196 11688 : aUno2Cpp.release = releaseMapping;
197 11688 : aUno2Cpp.mapInterface = uno2cppMapping;
198 :
199 11688 : (*pCppEnv->aBase.acquire)( &pCppEnv->aBase );
200 11688 : (*pUnoEnv->aBase.acquire)( &pUnoEnv->aBase );
201 11688 : }
202 :
203 11598 : Bridge::~Bridge()
204 : {
205 11598 : (*pUnoEnv->aBase.release)( &pUnoEnv->aBase );
206 11598 : (*pCppEnv->aBase.release)( &pCppEnv->aBase );
207 11598 : }
208 :
209 : } } }
210 :
211 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|