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