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_testtools.hxx"
30*cdf0e10cSrcweir #include <osl/diagnose.h>
31*cdf0e10cSrcweir #include <osl/interlck.h>
32*cdf0e10cSrcweir #include <rtl/ustring.hxx>
33*cdf0e10cSrcweir #include <typelib/typedescription.h>
34*cdf0e10cSrcweir #include <uno/dispatcher.h>
35*cdf0e10cSrcweir #include <uno/environment.h>
36*cdf0e10cSrcweir #include <uno/mapping.h>
37*cdf0e10cSrcweir #include <uno/lbnames.h>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir using namespace rtl;
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir namespace pseudo_uno
43*cdf0e10cSrcweir {
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir //==================================================================================================
46*cdf0e10cSrcweir struct pseudo_Mapping : public uno_Mapping
47*cdf0e10cSrcweir {
48*cdf0e10cSrcweir 	oslInterlockedCount		nRef;
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir 	uno_ExtEnvironment *	pFrom;
51*cdf0e10cSrcweir 	uno_ExtEnvironment *	pTo;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir 	pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ );
54*cdf0e10cSrcweir 	~pseudo_Mapping();
55*cdf0e10cSrcweir };
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir //==== a uno pseudo proxy =============================================================================
58*cdf0e10cSrcweir struct pseudo_unoInterfaceProxy : public uno_Interface
59*cdf0e10cSrcweir {
60*cdf0e10cSrcweir 	oslInterlockedCount					nRef;
61*cdf0e10cSrcweir 	pseudo_Mapping *					pPseudoMapping;
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 	// mapping information
64*cdf0e10cSrcweir 	uno_Interface *						pUnoI; // wrapped interface
65*cdf0e10cSrcweir 	typelib_InterfaceTypeDescription *	pTypeDescr;
66*cdf0e10cSrcweir 	OUString							oid;
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 	// ctor
69*cdf0e10cSrcweir 	inline pseudo_unoInterfaceProxy( pseudo_Mapping * pPseudoMapping_,
70*cdf0e10cSrcweir 									 uno_Interface * pUnoI_,
71*cdf0e10cSrcweir 									 typelib_InterfaceTypeDescription * pTypeDescr_,
72*cdf0e10cSrcweir 									 const OUString & rOId_ );
73*cdf0e10cSrcweir };
74*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
75*cdf0e10cSrcweir static void SAL_CALL pseudo_unoInterfaceProxy_dispatch(
76*cdf0e10cSrcweir 	uno_Interface * pUnoI,
77*cdf0e10cSrcweir 	const typelib_TypeDescription * pMemberType,
78*cdf0e10cSrcweir 	void * pReturn,
79*cdf0e10cSrcweir 	void * pArgs[],
80*cdf0e10cSrcweir 	uno_Any ** ppException )
81*cdf0e10cSrcweir {
82*cdf0e10cSrcweir 	pseudo_unoInterfaceProxy * pThis = static_cast< pseudo_unoInterfaceProxy * >( pUnoI );
83*cdf0e10cSrcweir 	(*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberType, pReturn, pArgs, ppException );
84*cdf0e10cSrcweir }
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
87*cdf0e10cSrcweir static void SAL_CALL pseudo_unoInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy )
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir 	pseudo_unoInterfaceProxy * pThis =
90*cdf0e10cSrcweir 		static_cast< pseudo_unoInterfaceProxy * >(
91*cdf0e10cSrcweir 			reinterpret_cast< uno_Interface * >( pProxy ) );
92*cdf0e10cSrcweir 	OSL_ASSERT( pEnv == pThis->pPseudoMapping->pTo );
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 	(*pThis->pPseudoMapping->pFrom->revokeInterface)( pThis->pPseudoMapping->pFrom, pThis->pUnoI );
95*cdf0e10cSrcweir 	(*pThis->pUnoI->release)( pThis->pUnoI );
96*cdf0e10cSrcweir 	typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr );
97*cdf0e10cSrcweir 	(*pThis->pPseudoMapping->release)( pThis->pPseudoMapping );
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
100*cdf0e10cSrcweir 	*(int *)pProxy = 0xdeadbabe;
101*cdf0e10cSrcweir #endif
102*cdf0e10cSrcweir 	delete pThis;
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
105*cdf0e10cSrcweir static void SAL_CALL pseudo_unoInterfaceProxy_acquire( uno_Interface * pUnoI )
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir 	if (1 == osl_incrementInterlockedCount( &static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef ))
108*cdf0e10cSrcweir 	{
109*cdf0e10cSrcweir 		// rebirth of proxy zombie
110*cdf0e10cSrcweir 		// register at uno env
111*cdf0e10cSrcweir 		void * pThis = static_cast< uno_Interface * >( pUnoI );
112*cdf0e10cSrcweir 		(*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->registerProxyInterface)(
113*cdf0e10cSrcweir 			static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo,
114*cdf0e10cSrcweir 			&pThis, pseudo_unoInterfaceProxy_free,
115*cdf0e10cSrcweir 			static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->oid.pData,
116*cdf0e10cSrcweir 			static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pTypeDescr );
117*cdf0e10cSrcweir 		OSL_ASSERT( pThis == static_cast< uno_Interface * >( pUnoI ) );
118*cdf0e10cSrcweir 	}
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
121*cdf0e10cSrcweir static void SAL_CALL pseudo_unoInterfaceProxy_release( uno_Interface * pUnoI )
122*cdf0e10cSrcweir {
123*cdf0e10cSrcweir 	if (! osl_decrementInterlockedCount( & static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->nRef ))
124*cdf0e10cSrcweir 	{
125*cdf0e10cSrcweir 		// revoke from uno env on last release
126*cdf0e10cSrcweir 		(*static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo->revokeInterface)(
127*cdf0e10cSrcweir 			static_cast< pseudo_unoInterfaceProxy * >( pUnoI )->pPseudoMapping->pTo, pUnoI );
128*cdf0e10cSrcweir 	}
129*cdf0e10cSrcweir }
130*cdf0e10cSrcweir //__________________________________________________________________________________________________
131*cdf0e10cSrcweir inline pseudo_unoInterfaceProxy::pseudo_unoInterfaceProxy(
132*cdf0e10cSrcweir 	pseudo_Mapping * pPseudoMapping_, uno_Interface * pUnoI_,
133*cdf0e10cSrcweir 	typelib_InterfaceTypeDescription * pTypeDescr_, const OUString & rOId_ )
134*cdf0e10cSrcweir 	: nRef( 1 )
135*cdf0e10cSrcweir 	, pPseudoMapping( pPseudoMapping_ )
136*cdf0e10cSrcweir 	, pUnoI( pUnoI_ )
137*cdf0e10cSrcweir 	, pTypeDescr( pTypeDescr_ )
138*cdf0e10cSrcweir 	, oid( rOId_ )
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir 	(*pPseudoMapping->acquire)( pPseudoMapping );
141*cdf0e10cSrcweir 	typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
142*cdf0e10cSrcweir 	(*pPseudoMapping->pFrom->registerInterface)(
143*cdf0e10cSrcweir 		pPseudoMapping->pFrom, reinterpret_cast< void ** >( &pUnoI ), oid.pData, pTypeDescr );
144*cdf0e10cSrcweir 	(*pUnoI->acquire)( pUnoI );
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 	// uno_Interface
147*cdf0e10cSrcweir 	uno_Interface::acquire = pseudo_unoInterfaceProxy_acquire;
148*cdf0e10cSrcweir 	uno_Interface::release = pseudo_unoInterfaceProxy_release;
149*cdf0e10cSrcweir 	uno_Interface::pDispatcher = pseudo_unoInterfaceProxy_dispatch;
150*cdf0e10cSrcweir }
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
153*cdf0e10cSrcweir static void SAL_CALL pseudo_Mapping_mapInterface(
154*cdf0e10cSrcweir 	uno_Mapping * pMapping, void ** ppOut,
155*cdf0e10cSrcweir 	void * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr )
156*cdf0e10cSrcweir {
157*cdf0e10cSrcweir 	OSL_ASSERT( ppOut && pTypeDescr );
158*cdf0e10cSrcweir 	if (*ppOut)
159*cdf0e10cSrcweir 	{
160*cdf0e10cSrcweir 		(*reinterpret_cast< uno_Interface * >( *ppOut )->release)(
161*cdf0e10cSrcweir 			reinterpret_cast< uno_Interface * >( *ppOut ) );
162*cdf0e10cSrcweir 		*ppOut = 0;
163*cdf0e10cSrcweir 	}
164*cdf0e10cSrcweir 	if (pUnoI && pTypeDescr)
165*cdf0e10cSrcweir 	{
166*cdf0e10cSrcweir 		// get object id of uno interface to be wrapped
167*cdf0e10cSrcweir 		rtl_uString * pOId = 0;
168*cdf0e10cSrcweir 		(*static_cast< pseudo_Mapping * >( pMapping )->pFrom->getObjectIdentifier)(
169*cdf0e10cSrcweir 			static_cast< pseudo_Mapping * >( pMapping )->pFrom, &pOId, pUnoI );
170*cdf0e10cSrcweir 		OSL_ASSERT( pOId );
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 		if (pOId)
173*cdf0e10cSrcweir 		{
174*cdf0e10cSrcweir 			// try to get any known interface from target environment
175*cdf0e10cSrcweir 			(*static_cast< pseudo_Mapping * >( pMapping )->pTo->getRegisteredInterface)(
176*cdf0e10cSrcweir 				static_cast< pseudo_Mapping * >( pMapping )->pTo, ppOut, pOId, pTypeDescr );
177*cdf0e10cSrcweir 			if (! *ppOut) // no existing interface, register new proxy interface
178*cdf0e10cSrcweir 			{
179*cdf0e10cSrcweir 				// try to publish a new proxy (ref count initially 1)
180*cdf0e10cSrcweir 				void * pProxy = new pseudo_unoInterfaceProxy(
181*cdf0e10cSrcweir 					static_cast< pseudo_Mapping * >( pMapping ),
182*cdf0e10cSrcweir 					reinterpret_cast< uno_Interface * >( pUnoI ), pTypeDescr, pOId );
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir 				// proxy may be exchanged during registration
185*cdf0e10cSrcweir 				(*static_cast< pseudo_Mapping * >( pMapping )->pTo->registerProxyInterface)(
186*cdf0e10cSrcweir 					static_cast< pseudo_Mapping * >( pMapping )->pTo,
187*cdf0e10cSrcweir 					&pProxy, pseudo_unoInterfaceProxy_free, pOId, pTypeDescr );
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 				*ppOut = pProxy;
190*cdf0e10cSrcweir 			}
191*cdf0e10cSrcweir 			rtl_uString_release( pOId );
192*cdf0e10cSrcweir 		}
193*cdf0e10cSrcweir 	}
194*cdf0e10cSrcweir }
195*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
196*cdf0e10cSrcweir static void SAL_CALL pseudo_Mapping_free( uno_Mapping * pMapping )
197*cdf0e10cSrcweir {
198*cdf0e10cSrcweir 	delete static_cast< pseudo_Mapping * >( pMapping );
199*cdf0e10cSrcweir }
200*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
201*cdf0e10cSrcweir static void SAL_CALL pseudo_Mapping_acquire( uno_Mapping * pMapping )
202*cdf0e10cSrcweir {
203*cdf0e10cSrcweir 	if (1 == osl_incrementInterlockedCount( & static_cast< pseudo_Mapping * >( pMapping )->nRef ))
204*cdf0e10cSrcweir 	{
205*cdf0e10cSrcweir 		OUString aMappingPurpose( RTL_CONSTASCII_USTRINGPARAM("pseudo") );
206*cdf0e10cSrcweir 		uno_registerMapping( &pMapping,
207*cdf0e10cSrcweir 							 pseudo_Mapping_free,
208*cdf0e10cSrcweir 							 (uno_Environment *)((pseudo_Mapping *)pMapping)->pFrom,
209*cdf0e10cSrcweir 							 (uno_Environment *)((pseudo_Mapping *)pMapping)->pTo,
210*cdf0e10cSrcweir 							 aMappingPurpose.pData );
211*cdf0e10cSrcweir 	}
212*cdf0e10cSrcweir }
213*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
214*cdf0e10cSrcweir static void SAL_CALL pseudo_Mapping_release( uno_Mapping * pMapping )
215*cdf0e10cSrcweir {
216*cdf0e10cSrcweir 	if (! osl_decrementInterlockedCount( & static_cast< pseudo_Mapping * >( pMapping )->nRef ))
217*cdf0e10cSrcweir 	{
218*cdf0e10cSrcweir 		uno_revokeMapping( pMapping );
219*cdf0e10cSrcweir 	}
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir //__________________________________________________________________________________________________
223*cdf0e10cSrcweir pseudo_Mapping::pseudo_Mapping( uno_ExtEnvironment * pFrom_, uno_ExtEnvironment * pTo_ )
224*cdf0e10cSrcweir 	: nRef( 1 )
225*cdf0e10cSrcweir 	, pFrom( pFrom_ )
226*cdf0e10cSrcweir 	, pTo( pTo_ )
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir 	(*((uno_Environment *)pFrom)->acquire)( (uno_Environment *)pFrom );
229*cdf0e10cSrcweir 	(*((uno_Environment *)pTo)->acquire)( (uno_Environment *)pTo );
230*cdf0e10cSrcweir 	//
231*cdf0e10cSrcweir 	uno_Mapping::acquire = pseudo_Mapping_acquire;
232*cdf0e10cSrcweir 	uno_Mapping::release = pseudo_Mapping_release;
233*cdf0e10cSrcweir 	uno_Mapping::mapInterface = pseudo_Mapping_mapInterface;
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir //__________________________________________________________________________________________________
236*cdf0e10cSrcweir pseudo_Mapping::~pseudo_Mapping()
237*cdf0e10cSrcweir {
238*cdf0e10cSrcweir 	(*((uno_Environment *)pTo)->release)( (uno_Environment *)pTo );
239*cdf0e10cSrcweir 	(*((uno_Environment *)pFrom)->release)( (uno_Environment *)pFrom );
240*cdf0e10cSrcweir }
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir //##################################################################################################
245*cdf0e10cSrcweir extern "C" void SAL_CALL uno_initEnvironment( uno_Environment * pUnoEnv )
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir 	OSL_ENSURE( sal_False, "### no impl: unexpected call!" );
248*cdf0e10cSrcweir }
249*cdf0e10cSrcweir //##################################################################################################
250*cdf0e10cSrcweir extern "C" void SAL_CALL uno_ext_getMapping(
251*cdf0e10cSrcweir 	uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir 	OSL_ASSERT( ppMapping && pFrom && pTo );
254*cdf0e10cSrcweir 	if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
255*cdf0e10cSrcweir 	{
256*cdf0e10cSrcweir 		uno_Mapping * pMapping = 0;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 		if (0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, UNO_LB_UNO ) &&
259*cdf0e10cSrcweir 			0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, UNO_LB_UNO ))
260*cdf0e10cSrcweir 		{
261*cdf0e10cSrcweir 			OUString aMappingPurpose( RTL_CONSTASCII_USTRINGPARAM("pseudo") );
262*cdf0e10cSrcweir 			// ref count is initially 1
263*cdf0e10cSrcweir 			pMapping = new pseudo_uno::pseudo_Mapping( pFrom->pExtEnv, pTo->pExtEnv );
264*cdf0e10cSrcweir 			uno_registerMapping( &pMapping, pseudo_uno::pseudo_Mapping_free,
265*cdf0e10cSrcweir 								 (uno_Environment *)pFrom->pExtEnv,
266*cdf0e10cSrcweir 								 (uno_Environment *)pTo->pExtEnv,
267*cdf0e10cSrcweir 								 aMappingPurpose.pData );
268*cdf0e10cSrcweir 		}
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir 		if (*ppMapping)
271*cdf0e10cSrcweir 			(*(*ppMapping)->release)( *ppMapping );
272*cdf0e10cSrcweir 		*ppMapping = pMapping;
273*cdf0e10cSrcweir 	}
274*cdf0e10cSrcweir }
275