LibreOffice Module cppu (master) 1
cascade_mapping.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#include <osl/interlck.h>
21#include <rtl/ustring.hxx>
22#include <uno/environment.hxx>
23#include <uno/lbnames.h>
24#include <uno/mapping.hxx>
25#include <uno/dispatcher.h>
26#include <o3tl/string_view.hxx>
27
28#include <cppu/EnvDcp.hxx>
29
30#include "cascade_mapping.hxx"
31
32using namespace com::sun::star;
33
34namespace {
35
36class MediatorMapping : public uno_Mapping
37{
38 oslInterlockedCount m_refCount;
39
40 uno::Mapping m_from2uno;
41 uno::Mapping m_uno2to;
42
43 uno::Environment m_from;
44 uno::Environment m_interm;
45 uno::Environment m_to;
46
47public:
48 void acquire();
49 void release();
50
51 void mapInterface(void ** ppOut,
52 void * pInterface,
53 typelib_InterfaceTypeDescription * pInterfaceTypeDescr);
54 MediatorMapping(uno_Environment * pFrom,
55 uno_Environment * pInterm,
56 uno_Environment * pTo);
57};
58
59}
60
61extern "C" {
62static void s_acquire(uno_Mapping * mapping)
63{
64 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
65 pMediatorMapping->acquire();
66}
67
68static void s_release(uno_Mapping * mapping)
69{
70 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
71 pMediatorMapping->release();
72}
73
74static void s_mapInterface(
75 uno_Mapping * mapping,
76 void ** ppOut,
77 void * pInterface,
78 typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
79{
80 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
81 pMediatorMapping->mapInterface(ppOut, pInterface, pInterfaceTypeDescr);
82}
83}
84
85MediatorMapping::MediatorMapping(uno_Environment * pFrom,
86 uno_Environment * pInterm,
87 uno_Environment * pTo)
88 : m_refCount(0),
89 m_from2uno(pFrom, pInterm),
90 m_uno2to (pInterm, pTo),
91 m_from (pFrom),
92 m_interm (pInterm),
93 m_to (pTo)
94{
95 if (!m_from2uno.get() || !m_uno2to.get())
96 abort();
97
98 uno_Mapping::acquire = s_acquire;
99 uno_Mapping::release = s_release;
100 uno_Mapping::mapInterface = s_mapInterface;
101}
102
103void MediatorMapping::acquire()
104{
105 osl_atomic_increment(&m_refCount);
106}
107
108void MediatorMapping::release()
109{
110 if (osl_atomic_decrement(&m_refCount) == 0)
111 {
113 }
114}
115
116extern "C" { static void s_mapInterface_v(va_list * pParam)
117{
118 void ** ppOut = va_arg(*pParam, void **);
119 void * pInterface = va_arg(*pParam, void *);
120 typelib_InterfaceTypeDescription * pInterfaceTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
121 uno_Mapping * pMapping = va_arg(*pParam, uno_Mapping *);
122
123 pMapping->mapInterface(pMapping, ppOut, pInterface, pInterfaceTypeDescr);
124}}
125
126void MediatorMapping::mapInterface(
127 void ** ppOut,
128 void * pInterface,
129 typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
130{
131 if (*ppOut != nullptr)
132 {
133 uno_ExtEnvironment * env = m_to.get()->pExtEnv;
134 OSL_ASSERT( env != nullptr );
135 env->releaseInterface( env, *ppOut );
136 *ppOut = nullptr;
137 }
138
139 void * ret = nullptr;
140 uno_Interface * pUnoI = nullptr;
141
142 m_from.invoke(s_mapInterface_v, &pUnoI, pInterface, pInterfaceTypeDescr, m_from2uno.get());
143
144 m_uno2to.mapInterface(&ret, pUnoI, pInterfaceTypeDescr);
145
146 if (pUnoI)
147 m_interm.get()->pExtEnv->releaseInterface(m_interm.get()->pExtEnv, pUnoI);
148
149 *ppOut = ret;
150}
151
152extern "C" { static void s_MediatorMapping_free(uno_Mapping * pMapping)
154{
155 delete static_cast<MediatorMapping *>(pMapping);
156}}
157
158
159static OUString getPrefix(std::u16string_view str1, std::u16string_view str2)
160{
161 sal_Int32 nIndex1 = 0;
162 sal_Int32 nIndex2 = 0;
163 sal_Int32 sim = 0;
164
165 std::u16string_view token1;
166 std::u16string_view token2;
167
168 do
169 {
170 token1 = o3tl::getToken(str1, 0, ':', nIndex1);
171 token2 = o3tl::getToken(str2, 0, ':', nIndex2);
172
173 if (token1 == token2)
174 sim += token1.size() + 1;
175 }
176 while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1 == token2);
177
178 OUString result;
179
180 if (sim)
181 result = str1.substr(0, sim - 1);
182
183 return result;
184}
185
186// OUString str1("abc:def:ghi");
187// OUString str2("abc:def");
188// OUString str3("abc");
189// OUString str4("");
190
191// OUString pref;
192
193// pref = getPrefix(str1, str1);
194// pref = getPrefix(str1, str2);
195// pref = getPrefix(str1, str3);
196// pref = getPrefix(str1, str4);
197
198// pref = getPrefix(str2, str1);
199// pref = getPrefix(str3, str1);
200// pref = getPrefix(str4, str1);
201
202
204 uno_Environment * pFrom,
205 uno_Environment * pTo,
206 rtl_uString * pAddPurpose)
207{
208 if (pAddPurpose && pAddPurpose->length)
209 return;
210
211 OUString uno_envType(UNO_LB_UNO);
212
213 OUString from_envType = cppu::EnvDcp::getTypeName(pFrom->pTypeName);
214 OUString to_envType = cppu::EnvDcp::getTypeName(pTo->pTypeName);
215 OUString from_envPurpose = cppu::EnvDcp::getPurpose(pFrom->pTypeName);
216 OUString to_envPurpose = cppu::EnvDcp::getPurpose(pTo->pTypeName);
217
218#ifdef LOG_CALLING_named_purpose_getMapping
219 OString s_from_name = OUStringToOString(pFrom->pTypeName, RTL_TEXTENCODING_ASCII_US);
220 OString s_to_name = OUStringToOString(pTo->pTypeName, RTL_TEXTENCODING_ASCII_US);
221
222 std::cerr << __FUNCTION__ << " - creating mediation ";
223 std::cerr << "pFrom: " << s_from_name.getStr();
224 std::cerr <<" pTo: " << s_to_name.getStr() << std::endl;
225#endif
226
227 if (from_envPurpose == to_envPurpose) // gcc:bla => uno:bla
228 return;
229
230 // reaching this point means, we need a mediated mapping!!!
231 // we generally mediate via uno[:free]
232 uno_Environment * pInterm = nullptr;
233
234 // chained uno -> uno
235 if (from_envType == uno_envType && to_envType == uno_envType)
236 {
237 OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
238
239 OUString uno_envDcp = uno_envType + purpose;
240
241 // direct mapping possible?
242 // uno:bla-->uno:bla:blubb
243 if (from_envPurpose == purpose)
244 {
245 OUString rest = to_envPurpose.copy(purpose.getLength());
246
247 sal_Int32 index = rest.indexOf(':', 1);
248 if (index == -1)
249 {
250 uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
251 return;
252 }
253
254 uno_envDcp += rest.subView(0, index);
255 }
256 else if (to_envPurpose == purpose)
257 {
258 OUString rest = from_envPurpose.copy(purpose.getLength());
259
260 sal_Int32 index = rest.indexOf(':', 1);
261 if (index == -1)
262 {
263 uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
264 return;
265 }
266
267 uno_envDcp += rest.subView(0, index);
268 }
269
270 uno_getEnvironment(&pInterm, uno_envDcp.pData, nullptr);
271 }
272 else if (from_envType != uno_envType && to_envType == uno_envType) // <ANY> -> UNO ?
273 // mediate via uno:purpose(fromEnv)
274 {
275 OUString envDcp = uno_envType + from_envPurpose;
276 uno_getEnvironment(&pInterm, envDcp.pData, nullptr);
277 }
278 else if (from_envType == uno_envType && to_envType != uno_envType) // UNO -> <ANY>?
279 // mediate via uno(context)
280 {
281 OUString envDcp = uno_envType + to_envPurpose;
282 uno_getEnvironment(&pInterm, envDcp.pData, nullptr);
283 }
284 else // everything else
285 // mediate via uno:purpose
286 {
287 OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
288
289 OUString uno_envDcp = uno_envType + purpose;
290
291 uno_getEnvironment(&pInterm, uno_envDcp.pData, nullptr);
292 }
293
294 uno_Mapping * pMapping = new MediatorMapping(pFrom, pInterm, pTo);
295 pInterm->release(pInterm);
296
297
298 pMapping->acquire(pMapping);
299
300 ::uno_registerMapping(&pMapping, s_MediatorMapping_free, pFrom, pTo, pAddPurpose);
301
302 if (*ppMapping)
303 (*ppMapping)->release(*ppMapping);
304
305 *ppMapping = pMapping;
306}
307
308/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void s_mapInterface_v(va_list *pParam)
static void s_MediatorMapping_free(uno_Mapping *pMapping) SAL_THROW_EXTERN_C()
static void s_acquire(uno_Mapping *mapping)
static void s_release(uno_Mapping *mapping)
static void s_mapInterface(uno_Mapping *mapping, void **ppOut, void *pInterface, typelib_InterfaceTypeDescription *pInterfaceTypeDescr)
static OUString getPrefix(std::u16string_view str1, std::u16string_view str2)
void getCascadeMapping(uno_Mapping **ppMapping, uno_Environment *pFrom, uno_Environment *pTo, rtl_uString *pAddPurpose)
ULONG m_refCount
struct _uno_Environment uno_Environment
void SAL_CALL uno_getEnvironment(uno_Environment **ppEnv, rtl_uString *pEnvDcp, void *pContext) SAL_THROW_EXTERN_C()
Definition: lbenv.cxx:1110
uno_Mapping * pMapping
Definition: lbmap.cxx:123
void SAL_CALL uno_getMapping(uno_Mapping **ppMapping, uno_Environment *pFrom, uno_Environment *pTo, rtl_uString *pAddPurpose) SAL_THROW_EXTERN_C()
Definition: lbmap.cxx:579
void SAL_CALL uno_registerMapping(uno_Mapping **ppMapping, uno_freeMappingFunc freeMapping, uno_Environment *pFrom, uno_Environment *pTo, rtl_uString *pAddPurpose) SAL_THROW_EXTERN_C()
Definition: lbmap.cxx:675
void SAL_CALL uno_revokeMapping(uno_Mapping *pMapping) SAL_THROW_EXTERN_C()
Definition: lbmap.cxx:710
const css::uno::Reference< css::xml::crypto::XSecurityEnvironment > & env
struct _uno_Mapping uno_Mapping
rtl::OUString getPurpose(rtl::OUString const &rEnvDcp)
Get the purpose part of an environment descriptor.
Definition: EnvDcp.hxx:57
rtl::OUString getTypeName(rtl::OUString const &rEnvDcp)
Get the OBI type part of an environment descriptor.
Definition: EnvDcp.hxx:41
index
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
#define SAL_THROW_EXTERN_C()
Any result