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