1*129fa3d1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*129fa3d1SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*129fa3d1SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*129fa3d1SAndrew Rist  * distributed with this work for additional information
6*129fa3d1SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*129fa3d1SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*129fa3d1SAndrew Rist  * "License"); you may not use this file except in compliance
9*129fa3d1SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*129fa3d1SAndrew Rist  *
11*129fa3d1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*129fa3d1SAndrew Rist  *
13*129fa3d1SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*129fa3d1SAndrew Rist  * software distributed under the License is distributed on an
15*129fa3d1SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*129fa3d1SAndrew Rist  * KIND, either express or implied.  See the License for the
17*129fa3d1SAndrew Rist  * specific language governing permissions and limitations
18*129fa3d1SAndrew Rist  * under the License.
19*129fa3d1SAndrew Rist  *
20*129fa3d1SAndrew Rist  *************************************************************/
21*129fa3d1SAndrew Rist 
22*129fa3d1SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppu.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "cppu/helper/purpenv/Mapping.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "Proxy.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "osl/interlck.h"
32cdf0e10cSrcweir #include "uno/environment.hxx"
33cdf0e10cSrcweir #include "uno/dispatcher.h"
34cdf0e10cSrcweir #include "typelib/typedescription.h"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #ifdef debug
38cdf0e10cSrcweir # define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
39cdf0e10cSrcweir #endif
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
42cdf0e10cSrcweir #  include <iostream>
43cdf0e10cSrcweir #  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) x
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #else
46cdf0e10cSrcweir #  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x)
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 
51cdf0e10cSrcweir using namespace com::sun::star;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir 
54cdf0e10cSrcweir class Mapping : public uno_Mapping
55cdf0e10cSrcweir {
56cdf0e10cSrcweir     uno::Environment   m_from;
57cdf0e10cSrcweir     uno::Environment   m_to;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 	oslInterlockedCount m_nCount;
60cdf0e10cSrcweir 
61cdf0e10cSrcweir 	cppu::helper::purpenv::ProbeFun * m_probeFun;
62cdf0e10cSrcweir 	void                            * m_pContext;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir public:
65cdf0e10cSrcweir     explicit  Mapping(uno_Environment                 * pFrom,
66cdf0e10cSrcweir 					  uno_Environment                 * pTo,
67cdf0e10cSrcweir 					  cppu::helper::purpenv::ProbeFun * probeFun,
68cdf0e10cSrcweir 					  void                            * pProbeContext);
69cdf0e10cSrcweir 	virtual  ~Mapping(void);
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	void mapInterface(
72cdf0e10cSrcweir 		uno_Interface                    ** ppOut,
73cdf0e10cSrcweir 		uno_Interface                     * pUnoI,
74cdf0e10cSrcweir 		typelib_InterfaceTypeDescription  * pTypeDescr);
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	void acquire(void);
77cdf0e10cSrcweir 	void release(void);
78cdf0e10cSrcweir };
79cdf0e10cSrcweir 
s_mapInterface(uno_Mapping * puno_Mapping,uno_Interface ** ppOut,uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTypeDescr)80cdf0e10cSrcweir static void SAL_CALL s_mapInterface(
81cdf0e10cSrcweir 	uno_Mapping                       * puno_Mapping,
82cdf0e10cSrcweir 	uno_Interface                    ** ppOut,
83cdf0e10cSrcweir 	uno_Interface                     * pUnoI,
84cdf0e10cSrcweir 	typelib_InterfaceTypeDescription  * pTypeDescr )
85cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
86cdf0e10cSrcweir {
87cdf0e10cSrcweir 	Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
88cdf0e10cSrcweir 	pMapping->mapInterface(ppOut, pUnoI, pTypeDescr);
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir extern "C" {
s_acquire(uno_Mapping * puno_Mapping)92cdf0e10cSrcweir static void SAL_CALL s_acquire(uno_Mapping * puno_Mapping)
93cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
94cdf0e10cSrcweir {
95cdf0e10cSrcweir 	Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
96cdf0e10cSrcweir 	pMapping->acquire();
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
s_release(uno_Mapping * puno_Mapping)99cdf0e10cSrcweir static void SAL_CALL s_release(uno_Mapping * puno_Mapping)
100cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir 	Mapping * pMapping = static_cast<Mapping * >(puno_Mapping);
103cdf0e10cSrcweir 	pMapping->release();
104cdf0e10cSrcweir }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 
s_getIdentifier_v(va_list * pParam)107cdf0e10cSrcweir static void s_getIdentifier_v(va_list * pParam)
108cdf0e10cSrcweir {
109cdf0e10cSrcweir 	uno_ExtEnvironment *  pEnv  = va_arg(*pParam, uno_ExtEnvironment *);
110cdf0e10cSrcweir 	rtl_uString        ** ppOid = va_arg(*pParam, rtl_uString **);
111cdf0e10cSrcweir 	uno_Interface      *  pUnoI = va_arg(*pParam, uno_Interface *);
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 	pEnv->getObjectIdentifier(pEnv, ppOid, pUnoI);
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
s_free(uno_Mapping * puno_Mapping)116cdf0e10cSrcweir static void SAL_CALL s_free(uno_Mapping * puno_Mapping)
117cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
118cdf0e10cSrcweir {
119cdf0e10cSrcweir 	Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
120cdf0e10cSrcweir 	delete pMapping;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
Mapping(uno_Environment * pFrom,uno_Environment * pTo,cppu::helper::purpenv::ProbeFun * probeFun,void * pProbeContext)124cdf0e10cSrcweir Mapping::Mapping(uno_Environment                 * pFrom,
125cdf0e10cSrcweir 				 uno_Environment                 * pTo,
126cdf0e10cSrcweir 				 cppu::helper::purpenv::ProbeFun * probeFun,
127cdf0e10cSrcweir 				 void                            * pProbeContext
128cdf0e10cSrcweir ) SAL_THROW( () )
129cdf0e10cSrcweir 	: m_from    (pFrom),
130cdf0e10cSrcweir 	  m_to      (pTo),
131cdf0e10cSrcweir 	  m_nCount  (1),
132cdf0e10cSrcweir 	  m_probeFun(probeFun),
133cdf0e10cSrcweir 	  m_pContext(pProbeContext)
134cdf0e10cSrcweir {
135cdf0e10cSrcweir 	LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::Mapping(uno_Environment * pFrom, uno_Environment * pTo) SAL_THROW( () )", this));
136cdf0e10cSrcweir 
137cdf0e10cSrcweir     uno_Mapping::acquire      = s_acquire;
138cdf0e10cSrcweir     uno_Mapping::release      = s_release;
139cdf0e10cSrcweir     uno_Mapping::mapInterface = (uno_MapInterfaceFunc)s_mapInterface;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
~Mapping(void)142cdf0e10cSrcweir Mapping::~Mapping(void)
143cdf0e10cSrcweir {
144cdf0e10cSrcweir 	LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::~Mapping(void)", this));
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 
mapInterface(uno_Interface ** ppOut,uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTypeDescr)148cdf0e10cSrcweir void Mapping::mapInterface(
149cdf0e10cSrcweir 	uno_Interface                    ** ppOut,
150cdf0e10cSrcweir 	uno_Interface                     * pUnoI,
151cdf0e10cSrcweir 	typelib_InterfaceTypeDescription  * pTypeDescr)
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     OSL_ASSERT(ppOut && pTypeDescr);
154cdf0e10cSrcweir     if (*ppOut)
155cdf0e10cSrcweir     {
156cdf0e10cSrcweir         (*ppOut)->release(*ppOut);
157cdf0e10cSrcweir         *ppOut = 0;
158cdf0e10cSrcweir     }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	if (!pUnoI)
161cdf0e10cSrcweir 		return;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	// get object id of uno interface to be wrapped
164cdf0e10cSrcweir 	// need to enter environment because of potential "queryInterface" call
165cdf0e10cSrcweir 	rtl_uString * pOId = 0;
166cdf0e10cSrcweir 	uno_Environment_invoke(m_from.get(), s_getIdentifier_v, m_from.get(), &pOId, pUnoI);
167cdf0e10cSrcweir 	OSL_ASSERT(pOId);
168cdf0e10cSrcweir 
169cdf0e10cSrcweir  	// try to get any known interface from target environment
170cdf0e10cSrcweir 	m_to.get()->pExtEnv->getRegisteredInterface(m_to.get()->pExtEnv, (void **)ppOut, pOId, pTypeDescr);
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 	if (!*ppOut) // not yet there, register new proxy interface
173cdf0e10cSrcweir 	{
174cdf0e10cSrcweir 		// try to publish a new proxy (ref count initially 1)
175cdf0e10cSrcweir 		uno_Interface * pProxy = new Proxy(this,
176cdf0e10cSrcweir 										   m_from.get(),
177cdf0e10cSrcweir 										   m_to.get(),
178cdf0e10cSrcweir 										   pUnoI,
179cdf0e10cSrcweir 										   pTypeDescr,
180cdf0e10cSrcweir 										   pOId,
181cdf0e10cSrcweir 										   m_probeFun,
182cdf0e10cSrcweir 										   m_pContext);
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 		// proxy may be exchanged during registration
185cdf0e10cSrcweir 		m_to.get()->pExtEnv->registerProxyInterface(m_to.get()->pExtEnv,
186cdf0e10cSrcweir 													(void **)&pProxy,
187cdf0e10cSrcweir 													Proxy_free,
188cdf0e10cSrcweir 													pOId,
189cdf0e10cSrcweir 													pTypeDescr);
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 		*ppOut = pProxy;
192cdf0e10cSrcweir 	}
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 	rtl_uString_release(pOId);
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 
acquire()198cdf0e10cSrcweir void Mapping::acquire() SAL_THROW(())
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	if (osl_incrementInterlockedCount(&m_nCount) == 1)
201cdf0e10cSrcweir 	{
202cdf0e10cSrcweir 		uno_Mapping * pMapping = this;
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 		::uno_registerMapping(&pMapping, s_free, m_from.get(), m_to.get(), NULL);
205cdf0e10cSrcweir 	}
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
release()208cdf0e10cSrcweir void Mapping::release() SAL_THROW(())
209cdf0e10cSrcweir {
210cdf0e10cSrcweir 	if (osl_decrementInterlockedCount(&m_nCount) == 0)
211cdf0e10cSrcweir 		::uno_revokeMapping(this);
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 
215cdf0e10cSrcweir namespace cppu { namespace helper { namespace purpenv {
216cdf0e10cSrcweir 
createMapping(uno_Mapping ** ppMapping,uno_Environment * pFrom,uno_Environment * pTo,ProbeFun * probeFun,void * pContext)217cdf0e10cSrcweir void createMapping(uno_Mapping     ** ppMapping,
218cdf0e10cSrcweir 				   uno_Environment  * pFrom,
219cdf0e10cSrcweir 				   uno_Environment  * pTo,
220cdf0e10cSrcweir 				   ProbeFun         * probeFun,
221cdf0e10cSrcweir 				   void             * pContext
222cdf0e10cSrcweir  )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	*ppMapping = new Mapping(pFrom, pTo, probeFun, pContext);
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	::uno_registerMapping(ppMapping, s_free, pFrom, pTo, NULL);
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir }}}
230