xref: /aoo42x/main/cppu/source/uno/lbmap.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_cppu.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "IdentityMapping.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <hash_map>
34*cdf0e10cSrcweir #include <set>
35*cdf0e10cSrcweir #include <algorithm>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include "rtl/unload.h"
38*cdf0e10cSrcweir #include "rtl/ustring.hxx"
39*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
40*cdf0e10cSrcweir #include "osl/module.h"
41*cdf0e10cSrcweir #include "osl/diagnose.h"
42*cdf0e10cSrcweir #include "osl/mutex.hxx"
43*cdf0e10cSrcweir #include "osl/interlck.h"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include "uno/dispatcher.h"
46*cdf0e10cSrcweir #include "uno/mapping.h"
47*cdf0e10cSrcweir #include "uno/lbnames.h"
48*cdf0e10cSrcweir #include "uno/environment.hxx"
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include "typelib/typedescription.h"
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include "cppu/EnvDcp.hxx"
53*cdf0e10cSrcweir #include "cascade_mapping.hxx"
54*cdf0e10cSrcweir #include "IdentityMapping.hxx"
55*cdf0e10cSrcweir #include "loadmodule.hxx"
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir using namespace std;
58*cdf0e10cSrcweir using namespace osl;
59*cdf0e10cSrcweir using namespace rtl;
60*cdf0e10cSrcweir using namespace com::sun::star::uno;
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir namespace cppu
64*cdf0e10cSrcweir {
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir class Mapping
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir 	uno_Mapping * _pMapping;
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir public:
71*cdf0e10cSrcweir 	inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () );
72*cdf0e10cSrcweir 	inline Mapping( const Mapping & rMapping ) SAL_THROW( () );
73*cdf0e10cSrcweir 	inline ~Mapping() SAL_THROW( () );
74*cdf0e10cSrcweir 	inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () );
75*cdf0e10cSrcweir 	inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () )
76*cdf0e10cSrcweir 		{ return operator = ( rMapping._pMapping ); }
77*cdf0e10cSrcweir 	inline uno_Mapping * SAL_CALL get() const SAL_THROW( () )
78*cdf0e10cSrcweir 		{ return _pMapping; }
79*cdf0e10cSrcweir 	inline sal_Bool SAL_CALL is() const SAL_THROW( () )
80*cdf0e10cSrcweir 		{ return (_pMapping != 0); }
81*cdf0e10cSrcweir };
82*cdf0e10cSrcweir //__________________________________________________________________________________________________
83*cdf0e10cSrcweir inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () )
84*cdf0e10cSrcweir 	: _pMapping( pMapping )
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir 	if (_pMapping)
87*cdf0e10cSrcweir 		(*_pMapping->acquire)( _pMapping );
88*cdf0e10cSrcweir }
89*cdf0e10cSrcweir //__________________________________________________________________________________________________
90*cdf0e10cSrcweir inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () )
91*cdf0e10cSrcweir 	: _pMapping( rMapping._pMapping )
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir 	if (_pMapping)
94*cdf0e10cSrcweir 		(*_pMapping->acquire)( _pMapping );
95*cdf0e10cSrcweir }
96*cdf0e10cSrcweir //__________________________________________________________________________________________________
97*cdf0e10cSrcweir inline Mapping::~Mapping() SAL_THROW( () )
98*cdf0e10cSrcweir {
99*cdf0e10cSrcweir 	if (_pMapping)
100*cdf0e10cSrcweir 		(*_pMapping->release)( _pMapping );
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir //__________________________________________________________________________________________________
103*cdf0e10cSrcweir inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () )
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir 	if (pMapping)
106*cdf0e10cSrcweir 		(*pMapping->acquire)( pMapping );
107*cdf0e10cSrcweir 	if (_pMapping)
108*cdf0e10cSrcweir 		(*_pMapping->release)( _pMapping );
109*cdf0e10cSrcweir 	_pMapping = pMapping;
110*cdf0e10cSrcweir 	return *this;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir //==================================================================================================
114*cdf0e10cSrcweir struct MappingEntry
115*cdf0e10cSrcweir {
116*cdf0e10cSrcweir 	sal_Int32			nRef;
117*cdf0e10cSrcweir 	uno_Mapping *		pMapping;
118*cdf0e10cSrcweir 	uno_freeMappingFunc	freeMapping;
119*cdf0e10cSrcweir 	OUString			aMappingName;
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 	MappingEntry(
122*cdf0e10cSrcweir 		uno_Mapping * pMapping_, uno_freeMappingFunc freeMapping_,
123*cdf0e10cSrcweir 		const OUString & rMappingName_ )
124*cdf0e10cSrcweir 		SAL_THROW( () )
125*cdf0e10cSrcweir 		: nRef( 1 )
126*cdf0e10cSrcweir 		, pMapping( pMapping_ )
127*cdf0e10cSrcweir 		, freeMapping( freeMapping_ )
128*cdf0e10cSrcweir 		, aMappingName( rMappingName_ )
129*cdf0e10cSrcweir 		{}
130*cdf0e10cSrcweir };
131*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
132*cdf0e10cSrcweir struct FctOUStringHash : public unary_function< const OUString &, size_t >
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir 	size_t operator()( const OUString & rKey ) const SAL_THROW( () )
135*cdf0e10cSrcweir 		{ return (size_t)rKey.hashCode(); }
136*cdf0e10cSrcweir };
137*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
138*cdf0e10cSrcweir struct FctPtrHash : public unary_function< uno_Mapping *, size_t >
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir 	size_t operator()( uno_Mapping * pKey ) const SAL_THROW( () )
141*cdf0e10cSrcweir 		{ return (size_t)pKey; }
142*cdf0e10cSrcweir };
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir typedef hash_map<
145*cdf0e10cSrcweir     OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry;
146*cdf0e10cSrcweir typedef hash_map<
147*cdf0e10cSrcweir     uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry;
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir typedef set< uno_getMappingFunc > t_CallbackSet;
150*cdf0e10cSrcweir typedef set< OUString > t_OUStringSet;
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir //==================================================================================================
153*cdf0e10cSrcweir struct MappingsData
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir 	Mutex				aMappingsMutex;
156*cdf0e10cSrcweir 	t_OUString2Entry	aName2Entry;
157*cdf0e10cSrcweir 	t_Mapping2Entry		aMapping2Entry;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 	Mutex				aCallbacksMutex;
160*cdf0e10cSrcweir 	t_CallbackSet		aCallbacks;
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	Mutex				aNegativeLibsMutex;
163*cdf0e10cSrcweir 	t_OUStringSet		aNegativeLibs;
164*cdf0e10cSrcweir };
165*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
166*cdf0e10cSrcweir static MappingsData & getMappingsData() SAL_THROW( () )
167*cdf0e10cSrcweir {
168*cdf0e10cSrcweir 	static MappingsData * s_p = 0;
169*cdf0e10cSrcweir 	if (! s_p)
170*cdf0e10cSrcweir 	{
171*cdf0e10cSrcweir 		MutexGuard aGuard( Mutex::getGlobalMutex() );
172*cdf0e10cSrcweir 		if (! s_p)
173*cdf0e10cSrcweir 		{
174*cdf0e10cSrcweir 			//TODO  This memory is leaked; see #i63473# for when this should be
175*cdf0e10cSrcweir             // changed again:
176*cdf0e10cSrcweir 			s_p = new MappingsData;
177*cdf0e10cSrcweir 		}
178*cdf0e10cSrcweir 	}
179*cdf0e10cSrcweir 	return *s_p;
180*cdf0e10cSrcweir }
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir /**
183*cdf0e10cSrcweir  * This class mediates two different mapping via uno, e.g. form any language to uno,
184*cdf0e10cSrcweir  * then from uno to any other language.
185*cdf0e10cSrcweir  */
186*cdf0e10cSrcweir struct uno_Mediate_Mapping : public uno_Mapping
187*cdf0e10cSrcweir {
188*cdf0e10cSrcweir 	sal_Int32	nRef;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 	Environment aFrom;
191*cdf0e10cSrcweir 	Environment aTo;
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 	Mapping		aFrom2Uno;
194*cdf0e10cSrcweir 	Mapping		aUno2To;
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir 	OUString	aAddPurpose;
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir 	uno_Mediate_Mapping(
199*cdf0e10cSrcweir 		const Environment & rFrom_, const Environment & rTo_,
200*cdf0e10cSrcweir 		const Mapping & rFrom2Uno_, const Mapping & rUno2To_,
201*cdf0e10cSrcweir 		const OUString & rAddPurpose )
202*cdf0e10cSrcweir 		SAL_THROW( () );
203*cdf0e10cSrcweir };
204*cdf0e10cSrcweir extern "C"
205*cdf0e10cSrcweir {
206*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
207*cdf0e10cSrcweir static void SAL_CALL mediate_free( uno_Mapping * pMapping )
208*cdf0e10cSrcweir 	SAL_THROW( () )
209*cdf0e10cSrcweir {
210*cdf0e10cSrcweir 	delete static_cast< uno_Mediate_Mapping * >( pMapping );
211*cdf0e10cSrcweir }
212*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
213*cdf0e10cSrcweir static void SAL_CALL mediate_acquire( uno_Mapping * pMapping )
214*cdf0e10cSrcweir 	SAL_THROW( () )
215*cdf0e10cSrcweir {
216*cdf0e10cSrcweir 	if (1 == ::osl_incrementInterlockedCount(
217*cdf0e10cSrcweir 		& static_cast< uno_Mediate_Mapping * >( pMapping )->nRef ))
218*cdf0e10cSrcweir 	{
219*cdf0e10cSrcweir 		uno_registerMapping(
220*cdf0e10cSrcweir 			&pMapping, mediate_free,
221*cdf0e10cSrcweir 			static_cast< uno_Mediate_Mapping * >( pMapping )->aFrom.get(),
222*cdf0e10cSrcweir 			static_cast< uno_Mediate_Mapping * >( pMapping )->aTo.get(),
223*cdf0e10cSrcweir 			static_cast< uno_Mediate_Mapping * >( pMapping )->aAddPurpose.pData );
224*cdf0e10cSrcweir 	}
225*cdf0e10cSrcweir }
226*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
227*cdf0e10cSrcweir static void SAL_CALL mediate_release( uno_Mapping * pMapping )
228*cdf0e10cSrcweir 	SAL_THROW( () )
229*cdf0e10cSrcweir {
230*cdf0e10cSrcweir 	if (! ::osl_decrementInterlockedCount(
231*cdf0e10cSrcweir 		& static_cast< uno_Mediate_Mapping * >( pMapping )->nRef ))
232*cdf0e10cSrcweir 	{
233*cdf0e10cSrcweir 		uno_revokeMapping( pMapping );
234*cdf0e10cSrcweir 	}
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
237*cdf0e10cSrcweir static void SAL_CALL mediate_mapInterface(
238*cdf0e10cSrcweir 	uno_Mapping * pMapping,
239*cdf0e10cSrcweir 	void ** ppOut, void * pInterface,
240*cdf0e10cSrcweir 	typelib_InterfaceTypeDescription * pInterfaceTypeDescr )
241*cdf0e10cSrcweir 	SAL_THROW( () )
242*cdf0e10cSrcweir {
243*cdf0e10cSrcweir 	OSL_ENSURE( pMapping && ppOut, "### null ptr!" );
244*cdf0e10cSrcweir 	if (pMapping && ppOut)
245*cdf0e10cSrcweir 	{
246*cdf0e10cSrcweir         uno_Mediate_Mapping * that = static_cast< uno_Mediate_Mapping * >( pMapping );
247*cdf0e10cSrcweir 		uno_Mapping * pFrom2Uno = that->aFrom2Uno.get();
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 		uno_Interface * pUnoI = 0;
250*cdf0e10cSrcweir 		(*pFrom2Uno->mapInterface)( pFrom2Uno, (void **) &pUnoI, pInterface, pInterfaceTypeDescr );
251*cdf0e10cSrcweir 		if (0 == pUnoI)
252*cdf0e10cSrcweir         {
253*cdf0e10cSrcweir             void * pOut = *ppOut;
254*cdf0e10cSrcweir             if (0 != pOut)
255*cdf0e10cSrcweir             {
256*cdf0e10cSrcweir                 uno_ExtEnvironment * pTo = that->aTo.get()->pExtEnv;
257*cdf0e10cSrcweir                 OSL_ENSURE( 0 != pTo, "### cannot release out interface: leaking!" );
258*cdf0e10cSrcweir                 if (0 != pTo)
259*cdf0e10cSrcweir                     (*pTo->releaseInterface)( pTo, pOut );
260*cdf0e10cSrcweir                 *ppOut = 0; // set to 0 anyway, because mapping was not successfull!
261*cdf0e10cSrcweir             }
262*cdf0e10cSrcweir         }
263*cdf0e10cSrcweir         else
264*cdf0e10cSrcweir 		{
265*cdf0e10cSrcweir             uno_Mapping * pUno2To = that->aUno2To.get();
266*cdf0e10cSrcweir 			(*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr );
267*cdf0e10cSrcweir 			(*pUnoI->release)( pUnoI );
268*cdf0e10cSrcweir 		}
269*cdf0e10cSrcweir 	}
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir }
272*cdf0e10cSrcweir //__________________________________________________________________________________________________
273*cdf0e10cSrcweir uno_Mediate_Mapping::uno_Mediate_Mapping(
274*cdf0e10cSrcweir 	const Environment & rFrom_, const Environment & rTo_,
275*cdf0e10cSrcweir 	const Mapping & rFrom2Uno_, const Mapping & rUno2To_,
276*cdf0e10cSrcweir 	const OUString & rAddPurpose_ )
277*cdf0e10cSrcweir 	SAL_THROW( () )
278*cdf0e10cSrcweir 	: nRef( 1 )
279*cdf0e10cSrcweir 	, aFrom( rFrom_ )
280*cdf0e10cSrcweir 	, aTo( rTo_ )
281*cdf0e10cSrcweir 	, aFrom2Uno( rFrom2Uno_ )
282*cdf0e10cSrcweir 	, aUno2To( rUno2To_ )
283*cdf0e10cSrcweir 	, aAddPurpose( rAddPurpose_ )
284*cdf0e10cSrcweir {
285*cdf0e10cSrcweir 	uno_Mapping::acquire		= mediate_acquire;
286*cdf0e10cSrcweir 	uno_Mapping::release		= mediate_release;
287*cdf0e10cSrcweir 	uno_Mapping::mapInterface	= mediate_mapInterface;
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir //==================================================================================================
291*cdf0e10cSrcweir static inline OUString getMappingName(
292*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
293*cdf0e10cSrcweir 	SAL_THROW( () )
294*cdf0e10cSrcweir {
295*cdf0e10cSrcweir 	OUStringBuffer aKey( 64 );
296*cdf0e10cSrcweir 	aKey.append( rAddPurpose );
297*cdf0e10cSrcweir 	aKey.append( (sal_Unicode)';' );
298*cdf0e10cSrcweir 	aKey.append( rFrom.getTypeName() );
299*cdf0e10cSrcweir 	aKey.append( (sal_Unicode)'[' );
300*cdf0e10cSrcweir 	aKey.append( reinterpret_cast< sal_IntPtr >(rFrom.get()), 16 );
301*cdf0e10cSrcweir 	aKey.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
302*cdf0e10cSrcweir 	aKey.append( rTo.getTypeName() );
303*cdf0e10cSrcweir 	aKey.append( (sal_Unicode)'[' );
304*cdf0e10cSrcweir 	aKey.append( reinterpret_cast< sal_IntPtr >(rTo.get()), 16 );
305*cdf0e10cSrcweir 	aKey.append( (sal_Unicode)']' );
306*cdf0e10cSrcweir 	return aKey.makeStringAndClear();
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir //==================================================================================================
309*cdf0e10cSrcweir static inline OUString getBridgeName(
310*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
311*cdf0e10cSrcweir 	SAL_THROW( () )
312*cdf0e10cSrcweir {
313*cdf0e10cSrcweir 	OUStringBuffer aBridgeName( 16 );
314*cdf0e10cSrcweir 	if (rAddPurpose.getLength())
315*cdf0e10cSrcweir 	{
316*cdf0e10cSrcweir 		aBridgeName.append( rAddPurpose );
317*cdf0e10cSrcweir 		aBridgeName.append( (sal_Unicode)'_' );
318*cdf0e10cSrcweir 	}
319*cdf0e10cSrcweir 	aBridgeName.append( EnvDcp::getTypeName(rFrom.getTypeName()) );
320*cdf0e10cSrcweir 	aBridgeName.append( (sal_Unicode)'_' );
321*cdf0e10cSrcweir 	aBridgeName.append( EnvDcp::getTypeName(rTo.getTypeName()) );
322*cdf0e10cSrcweir 	return aBridgeName.makeStringAndClear();
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir //==================================================================================================
325*cdf0e10cSrcweir static inline void setNegativeBridge( const OUString & rBridgeName )
326*cdf0e10cSrcweir 	SAL_THROW( () )
327*cdf0e10cSrcweir {
328*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
329*cdf0e10cSrcweir 	MutexGuard aGuard( rData.aNegativeLibsMutex );
330*cdf0e10cSrcweir 	rData.aNegativeLibs.insert( rBridgeName );
331*cdf0e10cSrcweir }
332*cdf0e10cSrcweir //==================================================================================================
333*cdf0e10cSrcweir static inline oslModule loadModule( const OUString & rBridgeName )
334*cdf0e10cSrcweir 	SAL_THROW( () )
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir 	sal_Bool bNeg;
337*cdf0e10cSrcweir 	{
338*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
339*cdf0e10cSrcweir 	MutexGuard aGuard( rData.aNegativeLibsMutex );
340*cdf0e10cSrcweir 	const t_OUStringSet::const_iterator iFind( rData.aNegativeLibs.find( rBridgeName ) );
341*cdf0e10cSrcweir 	bNeg = (iFind != rData.aNegativeLibs.end());
342*cdf0e10cSrcweir 	}
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir 	if (! bNeg)
345*cdf0e10cSrcweir 	{
346*cdf0e10cSrcweir 		oslModule hModule = cppu::detail::loadModule( rBridgeName );
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 		if (hModule)
349*cdf0e10cSrcweir 			return hModule;
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 		setNegativeBridge( rBridgeName ); // no load again
352*cdf0e10cSrcweir 	}
353*cdf0e10cSrcweir 	return 0;
354*cdf0e10cSrcweir }
355*cdf0e10cSrcweir //==================================================================================================
356*cdf0e10cSrcweir static Mapping loadExternalMapping(
357*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
358*cdf0e10cSrcweir 	SAL_THROW( () )
359*cdf0e10cSrcweir {
360*cdf0e10cSrcweir 	OSL_ASSERT( rFrom.is() && rTo.is() );
361*cdf0e10cSrcweir 	if (rFrom.is() && rTo.is())
362*cdf0e10cSrcweir 	{
363*cdf0e10cSrcweir 		// find proper lib
364*cdf0e10cSrcweir 		oslModule hModule = 0;
365*cdf0e10cSrcweir 		OUString aName;
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir 		if (EnvDcp::getTypeName(rFrom.getTypeName()).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
368*cdf0e10cSrcweir 			hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) );
369*cdf0e10cSrcweir 		if (! hModule)
370*cdf0e10cSrcweir 			hModule = loadModule( aName = getBridgeName( rFrom, rTo, rAddPurpose ) );
371*cdf0e10cSrcweir 		if (! hModule)
372*cdf0e10cSrcweir 			hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) );
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 		if (hModule)
375*cdf0e10cSrcweir 		{
376*cdf0e10cSrcweir 			OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM(UNO_EXT_GETMAPPING) );
377*cdf0e10cSrcweir 			uno_ext_getMappingFunc fpGetMapFunc =
378*cdf0e10cSrcweir 				(uno_ext_getMappingFunc)::osl_getFunctionSymbol(
379*cdf0e10cSrcweir                     hModule, aSymbolName.pData );
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir 			if (fpGetMapFunc)
382*cdf0e10cSrcweir 			{
383*cdf0e10cSrcweir 				Mapping aExt;
384*cdf0e10cSrcweir 				(*fpGetMapFunc)( (uno_Mapping **)&aExt, rFrom.get(), rTo.get() );
385*cdf0e10cSrcweir 				OSL_ASSERT( aExt.is() );
386*cdf0e10cSrcweir 				if (aExt.is())
387*cdf0e10cSrcweir                 {
388*cdf0e10cSrcweir                     ::rtl_registerModuleForUnloading( hModule );
389*cdf0e10cSrcweir 					return aExt;
390*cdf0e10cSrcweir                 }
391*cdf0e10cSrcweir 			}
392*cdf0e10cSrcweir 			::osl_unloadModule( hModule );
393*cdf0e10cSrcweir 			setNegativeBridge( aName );
394*cdf0e10cSrcweir 		}
395*cdf0e10cSrcweir 	}
396*cdf0e10cSrcweir 	return Mapping();
397*cdf0e10cSrcweir }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir //==================================================================================================
400*cdf0e10cSrcweir static Mapping getDirectMapping(
401*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose = OUString() )
402*cdf0e10cSrcweir 	SAL_THROW( () )
403*cdf0e10cSrcweir {
404*cdf0e10cSrcweir 	OSL_ASSERT( rFrom.is() && rTo.is() );
405*cdf0e10cSrcweir 	if (rFrom.is() && rTo.is())
406*cdf0e10cSrcweir 	{
407*cdf0e10cSrcweir 		MappingsData & rData = getMappingsData();
408*cdf0e10cSrcweir 		ClearableMutexGuard aGuard( rData.aMappingsMutex );
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 		// try to find registered mapping
411*cdf0e10cSrcweir 		const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find(
412*cdf0e10cSrcweir 			getMappingName( rFrom, rTo, rAddPurpose ) ) );
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir 		if (iFind == rData.aName2Entry.end())
415*cdf0e10cSrcweir 		{
416*cdf0e10cSrcweir 			aGuard.clear();
417*cdf0e10cSrcweir 			return loadExternalMapping( rFrom, rTo, rAddPurpose );
418*cdf0e10cSrcweir 		}
419*cdf0e10cSrcweir 		else
420*cdf0e10cSrcweir 		{
421*cdf0e10cSrcweir 			return Mapping( (*iFind).second->pMapping );
422*cdf0e10cSrcweir 		}
423*cdf0e10cSrcweir 	}
424*cdf0e10cSrcweir 	return Mapping();
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
428*cdf0e10cSrcweir static inline Mapping createMediateMapping(
429*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo,
430*cdf0e10cSrcweir 	const Mapping & rFrom2Uno, const Mapping & rUno2To,
431*cdf0e10cSrcweir 	const OUString & rAddPurpose )
432*cdf0e10cSrcweir 	SAL_THROW( () )
433*cdf0e10cSrcweir {
434*cdf0e10cSrcweir 	uno_Mapping * pRet = new uno_Mediate_Mapping(
435*cdf0e10cSrcweir 		rFrom, rTo, rFrom2Uno, rUno2To, rAddPurpose ); // ref count initially 1
436*cdf0e10cSrcweir 	uno_registerMapping(
437*cdf0e10cSrcweir 		&pRet, mediate_free, rFrom.get(), rTo.get(), rAddPurpose.pData );
438*cdf0e10cSrcweir 	Mapping aRet( pRet );
439*cdf0e10cSrcweir 	(*pRet->release)( pRet );
440*cdf0e10cSrcweir 	return aRet;
441*cdf0e10cSrcweir }
442*cdf0e10cSrcweir //==================================================================================================
443*cdf0e10cSrcweir static Mapping getMediateMapping(
444*cdf0e10cSrcweir 	const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
445*cdf0e10cSrcweir 	SAL_THROW( () )
446*cdf0e10cSrcweir {
447*cdf0e10cSrcweir 	Environment aUno;
448*cdf0e10cSrcweir 	Mapping aUno2To;
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir 	// backwards: from dest to source of mapping chain
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir 	// connect to uno
453*cdf0e10cSrcweir 	OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
454*cdf0e10cSrcweir 	if (rTo.getTypeName() == aUnoEnvTypeName) // to is uno
455*cdf0e10cSrcweir 	{
456*cdf0e10cSrcweir 		aUno = rTo;
457*cdf0e10cSrcweir 		// no Uno2To mapping necessary
458*cdf0e10cSrcweir 	}
459*cdf0e10cSrcweir 	else
460*cdf0e10cSrcweir 	{
461*cdf0e10cSrcweir 		// get registered uno env
462*cdf0e10cSrcweir 		::uno_getEnvironment( (uno_Environment **)&aUno, aUnoEnvTypeName.pData, 0 );
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 		aUno2To = getDirectMapping( aUno, rTo );
465*cdf0e10cSrcweir 		// : uno <-> to
466*cdf0e10cSrcweir 		if (! aUno2To.is())
467*cdf0e10cSrcweir 			return Mapping();
468*cdf0e10cSrcweir 	}
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir 	// connect to uno
471*cdf0e10cSrcweir 	if (rAddPurpose.getLength()) // insert purpose mapping between new ano_uno <-> uno
472*cdf0e10cSrcweir 	{
473*cdf0e10cSrcweir 		// create anonymous uno env
474*cdf0e10cSrcweir 		Environment aAnUno;
475*cdf0e10cSrcweir 		::uno_createEnvironment( (uno_Environment **)&aAnUno, aUnoEnvTypeName.pData, 0 );
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir 		Mapping aAnUno2Uno( getDirectMapping( aAnUno, aUno, rAddPurpose ) );
478*cdf0e10cSrcweir 		if (! aAnUno2Uno.is())
479*cdf0e10cSrcweir 			return Mapping();
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir 		if (aUno2To.is()) // to is not uno
482*cdf0e10cSrcweir 		{
483*cdf0e10cSrcweir 			// create another purposed mediate mapping
484*cdf0e10cSrcweir 			aUno2To = createMediateMapping( aAnUno, rTo, aAnUno2Uno, aUno2To, rAddPurpose );
485*cdf0e10cSrcweir 			// : ano_uno <-> uno <-> to
486*cdf0e10cSrcweir 		}
487*cdf0e10cSrcweir 		else
488*cdf0e10cSrcweir 		{
489*cdf0e10cSrcweir 			aUno2To = aAnUno2Uno;
490*cdf0e10cSrcweir 			// : ano_uno <-> to (i.e., uno)
491*cdf0e10cSrcweir 		}
492*cdf0e10cSrcweir 		aUno = aAnUno;
493*cdf0e10cSrcweir 	}
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 	Mapping aFrom2Uno( getDirectMapping( rFrom, aUno ) );
496*cdf0e10cSrcweir 	if (aFrom2Uno.is() && aUno2To.is())
497*cdf0e10cSrcweir 	{
498*cdf0e10cSrcweir 		return createMediateMapping( rFrom, rTo, aFrom2Uno, aUno2To, rAddPurpose );
499*cdf0e10cSrcweir 		// : from <-> some uno ...
500*cdf0e10cSrcweir 	}
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir 	return Mapping();
503*cdf0e10cSrcweir }
504*cdf0e10cSrcweir }
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir using namespace ::cppu;
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir extern "C"
509*cdf0e10cSrcweir {
510*cdf0e10cSrcweir //##################################################################################################
511*cdf0e10cSrcweir void SAL_CALL uno_getMapping(
512*cdf0e10cSrcweir 	uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo,
513*cdf0e10cSrcweir 	rtl_uString * pAddPurpose )
514*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
515*cdf0e10cSrcweir {
516*cdf0e10cSrcweir 	OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" );
517*cdf0e10cSrcweir 	if (*ppMapping)
518*cdf0e10cSrcweir 	{
519*cdf0e10cSrcweir 		(*(*ppMapping)->release)( *ppMapping );
520*cdf0e10cSrcweir 		*ppMapping = 0;
521*cdf0e10cSrcweir 	}
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir 	Mapping aRet;
524*cdf0e10cSrcweir 	Environment aFrom( pFrom ), aTo( pTo );
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir 	OUString aAddPurpose;
527*cdf0e10cSrcweir 	if (pAddPurpose)
528*cdf0e10cSrcweir 		aAddPurpose = pAddPurpose;
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 	// try registered mapping
533*cdf0e10cSrcweir 	{
534*cdf0e10cSrcweir 	MutexGuard aGuard( rData.aMappingsMutex );
535*cdf0e10cSrcweir 	const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find(
536*cdf0e10cSrcweir 		getMappingName( aFrom, aTo, aAddPurpose ) ) );
537*cdf0e10cSrcweir 	if (iFind != rData.aName2Entry.end())
538*cdf0e10cSrcweir 		aRet = (*iFind).second->pMapping;
539*cdf0e10cSrcweir 	}
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir 	// See if an identity mapping does fit.
542*cdf0e10cSrcweir 	if (!aRet.is() && pFrom == pTo && !aAddPurpose.getLength())
543*cdf0e10cSrcweir 		aRet = createIdentityMapping(pFrom);
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir 	if (!aRet.is())
546*cdf0e10cSrcweir 	{
547*cdf0e10cSrcweir 		getCascadeMapping(ppMapping, pFrom, pTo, pAddPurpose);
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir 		if (*ppMapping)
550*cdf0e10cSrcweir 			return;
551*cdf0e10cSrcweir 	}
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir 	if (! aRet.is()) // try callback chain
554*cdf0e10cSrcweir 	{
555*cdf0e10cSrcweir 		MutexGuard aGuard( rData.aCallbacksMutex );
556*cdf0e10cSrcweir 		for ( t_CallbackSet::const_iterator iPos( rData.aCallbacks.begin() );
557*cdf0e10cSrcweir 			  iPos != rData.aCallbacks.end(); ++iPos )
558*cdf0e10cSrcweir 		{
559*cdf0e10cSrcweir 			(**iPos)( ppMapping, pFrom, pTo, aAddPurpose.pData );
560*cdf0e10cSrcweir 			if (*ppMapping)
561*cdf0e10cSrcweir 				return;
562*cdf0e10cSrcweir 		}
563*cdf0e10cSrcweir 	}
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir 	if (! aRet.is())
566*cdf0e10cSrcweir 	{
567*cdf0e10cSrcweir 		aRet = loadExternalMapping( aFrom, aTo, aAddPurpose ); // direct try
568*cdf0e10cSrcweir 		if (! aRet.is())
569*cdf0e10cSrcweir 			aRet = getMediateMapping( aFrom, aTo, aAddPurpose ); // try via uno
570*cdf0e10cSrcweir 	}
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir 	if (aRet.is())
573*cdf0e10cSrcweir 	{
574*cdf0e10cSrcweir 		(*aRet.get()->acquire)( aRet.get() );
575*cdf0e10cSrcweir 		*ppMapping = aRet.get();
576*cdf0e10cSrcweir 	}
577*cdf0e10cSrcweir }
578*cdf0e10cSrcweir //##################################################################################################
579*cdf0e10cSrcweir void SAL_CALL uno_getMappingByName(
580*cdf0e10cSrcweir 	uno_Mapping ** ppMapping, rtl_uString * pFrom, rtl_uString * pTo,
581*cdf0e10cSrcweir 	rtl_uString * pAddPurpose )
582*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
583*cdf0e10cSrcweir {
584*cdf0e10cSrcweir 	OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" );
585*cdf0e10cSrcweir 	if (*ppMapping)
586*cdf0e10cSrcweir 	{
587*cdf0e10cSrcweir 		(*(*ppMapping)->release)( *ppMapping );
588*cdf0e10cSrcweir 		*ppMapping = 0;
589*cdf0e10cSrcweir 	}
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	uno_Environment * pEFrom = 0;
592*cdf0e10cSrcweir 	uno_getEnvironment( &pEFrom, pFrom, 0 );
593*cdf0e10cSrcweir 	OSL_ENSURE( pEFrom, "### cannot get source environment!" );
594*cdf0e10cSrcweir 	if (pEFrom)
595*cdf0e10cSrcweir 	{
596*cdf0e10cSrcweir 		uno_Environment * pETo = 0;
597*cdf0e10cSrcweir 		uno_getEnvironment( &pETo, pTo, 0 );
598*cdf0e10cSrcweir 		OSL_ENSURE( pETo, "### cannot get target environment!" );
599*cdf0e10cSrcweir 		if (pETo)
600*cdf0e10cSrcweir 		{
601*cdf0e10cSrcweir 			::uno_getMapping( ppMapping, pEFrom, pETo, pAddPurpose );
602*cdf0e10cSrcweir 			(*pETo->release)( pETo );
603*cdf0e10cSrcweir 		}
604*cdf0e10cSrcweir 		(*pEFrom->release)( pEFrom );
605*cdf0e10cSrcweir 	}
606*cdf0e10cSrcweir }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir //##################################################################################################
609*cdf0e10cSrcweir void SAL_CALL uno_registerMapping(
610*cdf0e10cSrcweir 	uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping,
611*cdf0e10cSrcweir 	uno_Environment * pFrom, uno_Environment * pTo, rtl_uString * pAddPurpose )
612*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
613*cdf0e10cSrcweir {
614*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
615*cdf0e10cSrcweir 	ClearableMutexGuard aGuard( rData.aMappingsMutex );
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir 	const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( *ppMapping ) );
618*cdf0e10cSrcweir 	if (iFind == rData.aMapping2Entry.end())
619*cdf0e10cSrcweir 	{
620*cdf0e10cSrcweir 		OUString aMappingName(
621*cdf0e10cSrcweir 			getMappingName( pFrom, pTo, pAddPurpose ? OUString(pAddPurpose) : OUString() ) );
622*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
623*cdf0e10cSrcweir 		OString cstr( OUStringToOString( aMappingName, RTL_TEXTENCODING_ASCII_US ) );
624*cdf0e10cSrcweir 		OSL_TRACE( "> inserting new mapping: %s", cstr.getStr() );
625*cdf0e10cSrcweir #endif
626*cdf0e10cSrcweir 		// count initially 1
627*cdf0e10cSrcweir 		MappingEntry * pEntry = new MappingEntry( *ppMapping, freeMapping, aMappingName );
628*cdf0e10cSrcweir 		rData.aName2Entry[ aMappingName ] = pEntry;
629*cdf0e10cSrcweir 		rData.aMapping2Entry[ *ppMapping ] = pEntry;
630*cdf0e10cSrcweir 	}
631*cdf0e10cSrcweir 	else
632*cdf0e10cSrcweir 	{
633*cdf0e10cSrcweir 		MappingEntry * pEntry = (*iFind).second;
634*cdf0e10cSrcweir 		++pEntry->nRef;
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir 		if (pEntry->pMapping != *ppMapping) // exchange mapping to be registered
637*cdf0e10cSrcweir 		{
638*cdf0e10cSrcweir 			(*pEntry->pMapping->acquire)( pEntry->pMapping );
639*cdf0e10cSrcweir 			--pEntry->nRef; // correct count; kill mapping to be registered
640*cdf0e10cSrcweir 			aGuard.clear();
641*cdf0e10cSrcweir 			(*freeMapping)( *ppMapping );
642*cdf0e10cSrcweir 			*ppMapping = pEntry->pMapping;
643*cdf0e10cSrcweir 		}
644*cdf0e10cSrcweir 	}
645*cdf0e10cSrcweir }
646*cdf0e10cSrcweir //##################################################################################################
647*cdf0e10cSrcweir void SAL_CALL uno_revokeMapping(
648*cdf0e10cSrcweir 	uno_Mapping * pMapping )
649*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
650*cdf0e10cSrcweir {
651*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
652*cdf0e10cSrcweir 	ClearableMutexGuard aGuard( rData.aMappingsMutex );
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir 	const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( pMapping ) );
655*cdf0e10cSrcweir 	OSL_ASSERT( iFind != rData.aMapping2Entry.end() );
656*cdf0e10cSrcweir 	MappingEntry * pEntry = (*iFind).second;
657*cdf0e10cSrcweir 	if (! --pEntry->nRef)
658*cdf0e10cSrcweir 	{
659*cdf0e10cSrcweir 		rData.aMapping2Entry.erase( pEntry->pMapping );
660*cdf0e10cSrcweir 		rData.aName2Entry.erase( pEntry->aMappingName );
661*cdf0e10cSrcweir 		aGuard.clear();
662*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
663*cdf0e10cSrcweir 		OString cstr( OUStringToOString( pEntry->aMappingName, RTL_TEXTENCODING_ASCII_US  ) );
664*cdf0e10cSrcweir 		OSL_TRACE( "> revoking mapping %s", cstr.getStr() );
665*cdf0e10cSrcweir #endif
666*cdf0e10cSrcweir 		(*pEntry->freeMapping)( pEntry->pMapping );
667*cdf0e10cSrcweir 		delete pEntry;
668*cdf0e10cSrcweir 	}
669*cdf0e10cSrcweir }
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir //##################################################################################################
672*cdf0e10cSrcweir void SAL_CALL uno_registerMappingCallback(
673*cdf0e10cSrcweir 	uno_getMappingFunc pCallback )
674*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
675*cdf0e10cSrcweir {
676*cdf0e10cSrcweir 	OSL_ENSURE( pCallback, "### null ptr!" );
677*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
678*cdf0e10cSrcweir 	MutexGuard aGuard( rData.aCallbacksMutex );
679*cdf0e10cSrcweir 	rData.aCallbacks.insert( pCallback );
680*cdf0e10cSrcweir }
681*cdf0e10cSrcweir //##################################################################################################
682*cdf0e10cSrcweir void SAL_CALL uno_revokeMappingCallback(
683*cdf0e10cSrcweir 	uno_getMappingFunc pCallback )
684*cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
685*cdf0e10cSrcweir {
686*cdf0e10cSrcweir 	OSL_ENSURE( pCallback, "### null ptr!" );
687*cdf0e10cSrcweir 	MappingsData & rData = getMappingsData();
688*cdf0e10cSrcweir 	MutexGuard aGuard( rData.aCallbacksMutex );
689*cdf0e10cSrcweir 	rData.aCallbacks.erase( pCallback );
690*cdf0e10cSrcweir }
691*cdf0e10cSrcweir } // extern "C"
692*cdf0e10cSrcweir 
693