fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / cppu / source / uno / cascade_mapping.cxx
blob596205a6be4e65269737ebc5ec94513c205f0684
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
27 #include "cppu/EnvDcp.hxx"
29 #include "cascade_mapping.hxx"
31 #ifdef LOG_LIFECYLE_MediatorMapping
32 # include <iostream>
33 # define LOG_LIFECYLE_MediatorMapping_emit(x) x
35 #else
36 # define LOG_LIFECYLE_MediatorMapping_emit(x)
38 #endif
41 using namespace com::sun::star;
43 class MediatorMapping : public uno_Mapping
45 oslInterlockedCount m_refCount;
47 uno::Mapping m_from2uno;
48 uno::Mapping m_uno2to;
50 uno::Environment m_from;
51 uno::Environment m_interm;
52 uno::Environment m_to;
54 public:
55 void acquire();
56 void release();
58 void mapInterface(void ** ppOut,
59 void * pInterface,
60 typelib_InterfaceTypeDescription * pInterfaceTypeDescr);
61 MediatorMapping(uno_Environment * pFrom,
62 uno_Environment * pInterm,
63 uno_Environment * pTo);
64 ~MediatorMapping();
67 extern "C" {
68 static void SAL_CALL s_acquire(uno_Mapping * mapping)
70 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
71 pMediatorMapping->acquire();
74 static void SAL_CALL s_release(uno_Mapping * mapping)
76 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
77 pMediatorMapping->release();
80 static void SAL_CALL s_mapInterface(
81 uno_Mapping * mapping,
82 void ** ppOut,
83 void * pInterface,
84 typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
86 MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
87 pMediatorMapping->mapInterface(ppOut, pInterface, pInterfaceTypeDescr);
91 MediatorMapping::MediatorMapping(uno_Environment * pFrom,
92 uno_Environment * pInterm,
93 uno_Environment * pTo)
94 : m_refCount(0),
95 m_from2uno(pFrom, pInterm),
96 m_uno2to (pInterm, pTo),
97 m_from (pFrom),
98 m_interm (pInterm),
99 m_to (pTo)
101 LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
103 if (!m_from2uno.get() || !m_uno2to.get())
104 abort();
106 uno_Mapping::acquire = s_acquire;
107 uno_Mapping::release = s_release;
108 uno_Mapping::mapInterface = s_mapInterface;
111 MediatorMapping::~MediatorMapping()
113 LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
116 void MediatorMapping::acquire()
118 LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
120 osl_atomic_increment(&m_refCount);
123 void MediatorMapping::release()
125 LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
127 if (osl_atomic_decrement(&m_refCount) == 0)
129 ::uno_revokeMapping(this);
133 extern "C" { static void s_mapInterface_v(va_list * pParam)
135 void ** ppOut = va_arg(*pParam, void **);
136 void * pInterface = va_arg(*pParam, void *);
137 typelib_InterfaceTypeDescription * pInterfaceTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
138 uno_Mapping * pMapping = va_arg(*pParam, uno_Mapping *);
140 pMapping->mapInterface(pMapping, ppOut, pInterface, pInterfaceTypeDescr);
143 void MediatorMapping::mapInterface(
144 void ** ppOut,
145 void * pInterface,
146 typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
148 if (*ppOut != 0)
150 uno_ExtEnvironment * env = m_to.get()->pExtEnv;
151 OSL_ASSERT( env != 0 );
152 env->releaseInterface( env, *ppOut );
153 *ppOut = NULL;
156 void * ret = 0;
157 uno_Interface * pUnoI = 0;
159 m_from.invoke(s_mapInterface_v, &pUnoI, pInterface, pInterfaceTypeDescr, m_from2uno.get());
161 m_uno2to.mapInterface(&ret, pUnoI, pInterfaceTypeDescr);
163 if (pUnoI)
164 m_interm.get()->pExtEnv->releaseInterface(m_interm.get()->pExtEnv, pUnoI);
166 *ppOut = ret;
169 extern "C" { static void SAL_CALL s_MediatorMapping_free(uno_Mapping * pMapping)
170 SAL_THROW_EXTERN_C()
172 delete static_cast<MediatorMapping *>(pMapping);
177 static rtl::OUString getPrefix(rtl::OUString const & str1, rtl::OUString const & str2)
179 sal_Int32 nIndex1 = 0;
180 sal_Int32 nIndex2 = 0;
181 sal_Int32 sim = 0;
183 rtl::OUString token1;
184 rtl::OUString token2;
188 token1 = str1.getToken(0, ':', nIndex1);
189 token2 = str2.getToken(0, ':', nIndex2);
191 if (token1.equals(token2))
192 sim += token1.getLength() + 1;
194 while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1.equals(token2));
196 rtl::OUString result;
198 if (sim)
199 result = str1.copy(0, sim - 1);
201 return result;
204 // rtl::OUString str1("abc:def:ghi");
205 // rtl::OUString str2("abc:def");
206 // rtl::OUString str3("abc");
207 // rtl::OUString str4("");
209 // rtl::OUString pref;
211 // pref = getPrefix(str1, str1);
212 // pref = getPrefix(str1, str2);
213 // pref = getPrefix(str1, str3);
214 // pref = getPrefix(str1, str4);
216 // pref = getPrefix(str2, str1);
217 // pref = getPrefix(str3, str1);
218 // pref = getPrefix(str4, str1);
221 void getCascadeMapping(uno_Mapping ** ppMapping,
222 uno_Environment * pFrom,
223 uno_Environment * pTo,
224 rtl_uString * pAddPurpose)
226 if (pAddPurpose && pAddPurpose->length)
227 return;
229 rtl::OUString uno_envType(UNO_LB_UNO);
231 rtl::OUString from_envType = cppu::EnvDcp::getTypeName(pFrom->pTypeName);
232 rtl::OUString to_envType = cppu::EnvDcp::getTypeName(pTo->pTypeName);
233 rtl::OUString from_envPurpose = cppu::EnvDcp::getPurpose(pFrom->pTypeName);
234 rtl::OUString to_envPurpose = cppu::EnvDcp::getPurpose(pTo->pTypeName);
236 #ifdef LOG_CALLING_named_purpose_getMapping
237 rtl::OString s_from_name = rtl::OUStringToOString(pFrom->pTypeName, RTL_TEXTENCODING_ASCII_US);
238 rtl::OString s_to_name = rtl::OUStringToOString(pTo->pTypeName, RTL_TEXTENCODING_ASCII_US);
240 std::cerr << __FUNCTION__ << " - creating mediation ";
241 std::cerr << "pFrom: " << s_from_name.getStr();
242 std::cerr <<" pTo: " << s_to_name.getStr() << std::endl;
243 #endif
245 if (from_envPurpose == to_envPurpose) // gcc:bla => uno:bla
246 return;
248 // reaching this point means, we need a mediated mapping!!!
249 // we generall mediate via uno[:free]
250 uno_Environment * pInterm = NULL;
252 // chained uno -> uno
253 if (from_envType == uno_envType && to_envType == uno_envType)
255 rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
257 rtl::OUString uno_envDcp = uno_envType;
258 uno_envDcp += purpose;
260 // direct mapping possible?
261 // uno:bla-->uno:bla:blubb
262 if (from_envPurpose.equals(purpose))
264 rtl::OUString rest = to_envPurpose.copy(purpose.getLength());
266 sal_Int32 index = rest.indexOf(':', 1);
267 if (index == -1)
269 uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
270 return;
273 uno_envDcp += rest.copy(0, index);
275 else if (to_envPurpose.equals(purpose))
277 rtl::OUString rest = from_envPurpose.copy(purpose.getLength());
279 sal_Int32 index = rest.indexOf(':', 1);
280 if (index == -1)
282 uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
283 return;
286 uno_envDcp += rest.copy(0, index);
289 uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL);
291 else if (from_envType != uno_envType && to_envType == uno_envType) // <ANY> -> UNO ?
292 // mediate via uno:purpose(fromEnv)
294 rtl::OUString envDcp = uno_envType;
296 envDcp += from_envPurpose;
297 uno_getEnvironment(&pInterm, envDcp.pData, NULL);
299 else if (from_envType == uno_envType && to_envType != uno_envType) // UNO -> <ANY>?
300 // mediate via uno(context)
302 rtl::OUString envDcp = uno_envType;
304 envDcp += to_envPurpose;
305 uno_getEnvironment(&pInterm, envDcp.pData, NULL);
307 else // everything else
308 // mediate via uno:purpose
310 rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
312 rtl::OUString uno_envDcp = uno_envType;
313 uno_envDcp += purpose;
315 uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL);
318 uno_Mapping * pMapping = new MediatorMapping(pFrom, pInterm, pTo);
319 pInterm->release(pInterm);
322 pMapping->acquire(pMapping);
324 ::uno_registerMapping(&pMapping, s_MediatorMapping_free, pFrom, pTo, pAddPurpose);
326 if (*ppMapping)
327 (*ppMapping)->release(*ppMapping);
329 *ppMapping = pMapping;
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */