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