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