xref: /trunk/main/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppu.hxx"
30 
31 #include "cppu/helper/purpenv/Environment.hxx"
32 
33 #include "osl/diagnose.h"
34 #include "uno/lbnames.h"
35 
36 #include "typelib/typedescription.h"
37 #include "osl/interlck.h"
38 
39 #ifdef debug
40 # define LOG_LIFECYCLE_cppu_helper_purpenv_Base
41 #endif
42 
43 #ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Base
44 #  include <iostream>
45 #  define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) x
46 
47 #else
48 #  define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x)
49 
50 #endif
51 
52 
53 extern "C" {
54 typedef void SAL_CALL EnvFun_P   (uno_Environment *);
55 typedef void SAL_CALL EnvFun_PP_P(uno_Environment ** ppHardEnv, uno_Environment *);
56 typedef void SAL_CALL ExtEnv_registerProxyInterface (uno_ExtEnvironment                 *,
57                                                      void                              ** ppProxy,
58                                                      uno_freeProxyFunc                    freeProxy,
59                                                      rtl_uString * pOId,
60                                                      typelib_InterfaceTypeDescription   * pTypeDescr);
61 typedef void SAL_CALL ExtEnv_revokeInterface        (uno_ExtEnvironment                 *,
62                                                      void                               * pInterface);
63 typedef void SAL_CALL ExtEnv_getObjectIdentifier    (uno_ExtEnvironment                 *,
64                                                      rtl_uString                       **,
65                                                      void                               *);
66 typedef void SAL_CALL ExtEnv_getRegisteredInterface (uno_ExtEnvironment                 *,
67                                                      void                              **,
68                                                      rtl_uString                        *,
69                                                      typelib_InterfaceTypeDescription   *);
70 typedef void SAL_CALL ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment                 *,
71                                                      void                             *** pppInterfaces,
72                                                      sal_Int32                          * pnLen,
73                                                      uno_memAlloc                         memAlloc);
74 typedef void SAL_CALL ExtEnv_computeObjectIdentifier(uno_ExtEnvironment                 *,
75                                                      rtl_uString                       ** ppOId,
76                                                      void                               * pInterface);
77 typedef void SAL_CALL ExtEnv_acquireInterface       (uno_ExtEnvironment                 *,
78                                                      void                               * pInterface);
79 typedef void SAL_CALL ExtEnv_releaseInterface       (uno_ExtEnvironment                 *,
80                                                      void                               * pInterface);
81 }
82 
83 class Base : public cppu::Enterable
84 {
85 public:
86     explicit Base(uno_Environment * pEnv, cppu::Enterable * pEnterable);
87 
88     void acquireWeak(void);
89     void releaseWeak(void);
90     void harden     (uno_Environment ** ppHardEnv);
91     void acquire    (void);
92     void release    (void);
93 
94     void registerProxyInterface (void                                  ** ppProxy,
95                                  uno_freeProxyFunc                        freeProxy,
96                                  rtl::OUString                    const & oid,
97                                  typelib_InterfaceTypeDescription       * pTypeDescr);
98     void revokeInterface        (void                                   * pInterface);
99     void getObjectIdentifier    (void                                   * pInterface,
100                                  rtl::OUString                          * pOid);
101     void getRegisteredInterface (void                                  **,
102                                  rtl::OUString                    const & oid,
103                                  typelib_InterfaceTypeDescription       *);
104     void getRegisteredInterfaces(void                                 ***,
105                                  sal_Int32                              * pnLen,
106                                  uno_memAlloc                             memAlloc);
107     void computeObjectIdentifier(void                                   * pInterface,
108                                  rtl::OUString                          * pOid);
109     void acquireInterface       (void                                   * pInterface);
110     void releaseInterface       (void                                   * pInterface);
111 
112     virtual void v_enter     (void);
113     virtual void v_leave     (void);
114     virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
115     virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);
116     virtual int  v_isValid   (rtl::OUString * pReason);
117 
118 protected:
119     oslInterlockedCount    m_nRef;
120     uno_Environment      * m_pEnv;
121     cppu::Enterable      * m_pEnterable;
122 
123     EnvFun_P    * m_env_acquire;
124     EnvFun_P    * m_env_release;
125     EnvFun_PP_P * m_env_harden;
126     EnvFun_P    * m_env_acquireWeak;
127     EnvFun_P    * m_env_releaseWeak;
128 
129     ExtEnv_registerProxyInterface  * m_env_registerProxyInterface;
130     ExtEnv_revokeInterface         * m_env_revokeInterface;
131     ExtEnv_getObjectIdentifier     * m_env_getObjectIdentifier;
132     ExtEnv_getRegisteredInterface  * m_env_getRegisteredInterface;
133     ExtEnv_getRegisteredInterfaces * m_env_getRegisteredInterfaces;
134     ExtEnv_computeObjectIdentifier * m_env_computeObjectIdentifier;
135     ExtEnv_acquireInterface        * m_env_acquireInterface;
136     ExtEnv_releaseInterface        * m_env_releaseInterface;
137 
138     virtual  ~Base();
139 };
140 
141 extern "C" {
142 static void SAL_CALL s_acquire(uno_Environment * pEnv) //SAL_THROW_EXTERN_C()
143 {
144     Base * pBase = static_cast<Base *>(pEnv->pReserved);
145     pBase->acquire();
146 }
147 
148 static void SAL_CALL s_release(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
149 {
150     Base * pBase = static_cast<Base *>(pEnv->pReserved);
151     pBase->release();
152 }
153 
154 static void SAL_CALL s_harden(uno_Environment ** ppHardEnv, uno_Environment * pEnv) SAL_THROW_EXTERN_C()
155 {
156     Base * pBase = static_cast<Base *>(pEnv->pReserved);
157     pBase->harden(ppHardEnv);
158 }
159 
160 static void SAL_CALL s_acquireWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
161 {
162     Base * pBase = static_cast<Base *>(pEnv->pReserved);
163     pBase->acquireWeak();
164 }
165 
166 static void SAL_CALL s_releaseWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
167 {
168     Base * pBase = static_cast<Base *>(pEnv->pReserved);
169     pBase->releaseWeak();
170 }
171 
172 
173 static void SAL_CALL s_registerProxyInterface(uno_ExtEnvironment                * pExtEnv,
174                                                          void                             ** ppProxy,
175                                                          uno_freeProxyFunc                   freeProxy,
176                                                          rtl_uString                       * pOId,
177                                                          typelib_InterfaceTypeDescription  * pTypeDescr)
178 {
179     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
180     pBase->registerProxyInterface(ppProxy, freeProxy, pOId, pTypeDescr);
181 }
182 
183 static void SAL_CALL s_revokeInterface(uno_ExtEnvironment * pExtEnv, void * pInterface)
184 {
185     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
186     pBase->revokeInterface(pInterface);
187 }
188 
189 static void SAL_CALL s_getObjectIdentifier(uno_ExtEnvironment *  pExtEnv,
190                                                       rtl_uString        ** ppOId,
191                                                       void               *  pInterface)
192 {
193     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
194     pBase->getObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId));
195 }
196 
197 static void SAL_CALL s_getRegisteredInterface(uno_ExtEnvironment *  pExtEnv,
198                                                          void               ** ppInterface,
199                                                          rtl_uString        *  pOId,
200                                                          typelib_InterfaceTypeDescription * pTypeDescr)
201 {
202     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
203     pBase->getRegisteredInterface(ppInterface, pOId, pTypeDescr);
204 }
205 
206 static void SAL_CALL s_getRegisteredInterfaces(uno_ExtEnvironment   * pExtEnv,
207                                                           void               *** pppInterface,
208                                                           sal_Int32            * pnLen,
209                                                           uno_memAlloc           memAlloc)
210 {
211     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
212     pBase->getRegisteredInterfaces(pppInterface, pnLen, memAlloc);
213 }
214 
215 static void SAL_CALL s_computeObjectIdentifier(uno_ExtEnvironment *  pExtEnv,
216                                                           rtl_uString        ** ppOId,
217                                                           void               *  pInterface)
218 {
219     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
220     pBase->computeObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId));
221 }
222 
223 static void SAL_CALL s_acquireInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
224     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
225     pBase->acquireInterface(pInterface);
226 }
227 
228 static void SAL_CALL s_releaseInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
229     Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
230     pBase->releaseInterface(pInterface);
231 }
232 
233 }
234 
235 Base::Base(uno_Environment * pEnv, cppu::Enterable * pEnterable)
236     :m_nRef(1),
237      m_pEnv(pEnv),
238      m_pEnterable     (pEnterable),
239      m_env_acquire    (pEnv->acquire),
240      m_env_release    (pEnv->release),
241      m_env_harden     (pEnv->harden),
242      m_env_acquireWeak(pEnv->acquireWeak),
243      m_env_releaseWeak(pEnv->releaseWeak),
244      m_env_registerProxyInterface (pEnv->pExtEnv->registerProxyInterface),
245      m_env_revokeInterface        (pEnv->pExtEnv->revokeInterface),
246      m_env_getObjectIdentifier    (pEnv->pExtEnv->getObjectIdentifier),
247      m_env_getRegisteredInterface (pEnv->pExtEnv->getRegisteredInterface),
248      m_env_getRegisteredInterfaces(pEnv->pExtEnv->getRegisteredInterfaces),
249      m_env_computeObjectIdentifier(pEnv->pExtEnv->computeObjectIdentifier),
250      m_env_acquireInterface       (pEnv->pExtEnv->acquireInterface),
251      m_env_releaseInterface       (pEnv->pExtEnv->releaseInterface)
252 {
253     LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::Base(uno_Environment * pEnv)", this));
254     OSL_ENSURE(
255         rtl_ustr_ascii_compare_WithLength(pEnv->pTypeName->buffer, rtl_str_getLength(UNO_LB_UNO), UNO_LB_UNO)
256             == 0,
257             "### wrong environment type!");
258 
259     pEnv->acquire     = s_acquire;
260     pEnv->release     = s_release;
261     pEnv->harden      = s_harden;
262     pEnv->acquireWeak = s_acquireWeak;
263     pEnv->releaseWeak = s_releaseWeak;
264 
265     pEnv->pExtEnv->registerProxyInterface  = s_registerProxyInterface;
266     pEnv->pExtEnv->revokeInterface         = s_revokeInterface;
267     pEnv->pExtEnv->getObjectIdentifier     = s_getObjectIdentifier;
268     pEnv->pExtEnv->getRegisteredInterface  = s_getRegisteredInterface;
269     pEnv->pExtEnv->getRegisteredInterfaces = s_getRegisteredInterfaces;
270     pEnv->pExtEnv->computeObjectIdentifier = s_computeObjectIdentifier;
271     pEnv->pExtEnv->acquireInterface        = s_acquireInterface;
272     pEnv->pExtEnv->releaseInterface        = s_releaseInterface;
273 
274     pEnv->pReserved = this;
275 }
276 
277 Base::~Base()
278 {
279     LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::~Base()", this));
280 
281     m_pEnv->acquire     = m_env_acquire;
282     m_pEnv->release     = m_env_release;
283     m_pEnv->harden      = m_env_harden;
284     m_pEnv->acquireWeak = m_env_acquireWeak;
285     m_pEnv->releaseWeak = m_env_releaseWeak;
286 
287     m_pEnv->pReserved = NULL;
288 
289     delete m_pEnterable;
290     m_pEnv->release(m_pEnv);
291 }
292 
293 void Base::acquire(void)
294 {
295     m_env_acquire(m_pEnv);
296 
297     osl_incrementInterlockedCount(&m_nRef);
298 }
299 
300 void Base::release(void)
301 {
302     if (osl_decrementInterlockedCount(&m_nRef) == 0)
303         delete this;
304 
305     else
306         m_env_release(m_pEnv);
307 }
308 
309 void Base::harden(uno_Environment ** ppHardEnv)
310 {
311     m_env_harden(ppHardEnv, m_pEnv);
312     osl_incrementInterlockedCount(&m_nRef);
313 }
314 
315 void Base::acquireWeak(void)
316 {
317     m_env_acquireWeak(m_pEnv);
318 }
319 
320 void Base::releaseWeak(void)
321 {
322     m_env_releaseWeak(m_pEnv);
323 }
324 
325 
326 extern "C" { static void s_registerProxyInterface_v(va_list * pParam)
327 {
328     uno_ExtEnvironment                   * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
329     void                                ** ppProxy    = va_arg(*pParam, void **);
330     uno_freeProxyFunc                      freeProxy  = va_arg(*pParam, uno_freeProxyFunc);
331     rtl_uString                          * pOId       = va_arg(*pParam, rtl_uString *);
332     typelib_InterfaceTypeDescription     * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
333     ExtEnv_registerProxyInterface  * pRegisterProxyInterface
334         = va_arg(*pParam, ExtEnv_registerProxyInterface *);
335 
336     pRegisterProxyInterface(pExtEnv, ppProxy, freeProxy, pOId, pTypeDescr);
337 }}
338 
339 void Base::registerProxyInterface(void                                  ** ppProxy,
340                                   uno_freeProxyFunc                        freeProxy,
341                                   rtl::OUString                    const & oid,
342                                   typelib_InterfaceTypeDescription       * pTypeDescr)
343 {
344     uno_Environment_invoke(m_pEnv,
345                            s_registerProxyInterface_v,
346                            m_pEnv->pExtEnv,
347                            ppProxy,
348                            freeProxy,
349                            oid.pData,
350                            pTypeDescr,
351                            m_env_registerProxyInterface);
352 }
353 
354 
355 extern "C" { static void s_revokeInterface_v(va_list * pParam)
356 {
357     uno_ExtEnvironment * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
358     void               * pInterface = va_arg(*pParam, void *);
359     ExtEnv_revokeInterface * pRevokeInterface = va_arg(*pParam, ExtEnv_revokeInterface *);
360 
361     pRevokeInterface(pExtEnv, pInterface);
362 }}
363 
364 void Base::revokeInterface(void * pInterface)
365 {
366     uno_Environment_invoke(m_pEnv,
367                            s_revokeInterface_v,
368                            m_pEnv->pExtEnv,
369                            pInterface,
370                            m_env_revokeInterface);
371 }
372 
373 
374 extern "C" { static void s_getObjectIdentifier_v(va_list * pParam)
375 {
376     uno_ExtEnvironment * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
377     void               * pInterface = va_arg(*pParam, void *);
378     rtl::OUString      * pOId       = va_arg(*pParam, rtl::OUString *);
379     ExtEnv_getObjectIdentifier * pGetObjectIdentifier
380         = va_arg(*pParam, ExtEnv_getObjectIdentifier *);
381 
382     pGetObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
383 }}
384 
385 void Base::getObjectIdentifier(void * pInterface, rtl::OUString * pOid)
386 {
387     uno_Environment_invoke(m_pEnv,
388                            s_getObjectIdentifier_v,
389                            m_pEnv->pExtEnv,
390                            pInterface,
391                            pOid,
392                            m_env_getObjectIdentifier);
393 }
394 
395 
396 extern "C" { static void s_getRegisteredInterface_v(va_list * pParam)
397 {
398     uno_ExtEnvironment                   * pExtEnv     = va_arg(*pParam, uno_ExtEnvironment *);
399     void                                ** ppInterface = va_arg(*pParam, void **);
400     rtl_uString                          * pOId        = va_arg(*pParam, rtl_uString *);
401     typelib_InterfaceTypeDescription     * pTypeDescr  = va_arg(*pParam, typelib_InterfaceTypeDescription *);
402     ExtEnv_getRegisteredInterface  * pGetRegisteredInterface
403         = va_arg(*pParam, ExtEnv_getRegisteredInterface *);
404 
405     pGetRegisteredInterface(pExtEnv, ppInterface, pOId, pTypeDescr);
406 }}
407 
408 void Base::getRegisteredInterface(void ** ppInterface,
409                                   rtl::OUString const & oid,
410                                   typelib_InterfaceTypeDescription * pTypeDescr)
411 {
412     uno_Environment_invoke(m_pEnv,
413                            s_getRegisteredInterface_v,
414                            m_pEnv->pExtEnv,
415                            ppInterface,
416                            oid.pData,
417                            pTypeDescr,
418                            m_env_getRegisteredInterface);
419 }
420 
421 
422 extern "C" { static void s_getRegisteredInterfaces_v(va_list * pParam)
423 {
424     uno_ExtEnvironment   * pExtEnv      = va_arg(*pParam, uno_ExtEnvironment *);
425     void               *** pppInterface = va_arg(*pParam, void ***);
426     sal_Int32            * pnLen        = va_arg(*pParam, sal_Int32 *);
427     uno_memAlloc           memAlloc     = va_arg(*pParam, uno_memAlloc);
428     ExtEnv_getRegisteredInterfaces * pGetRegisteredInterfaces
429         = va_arg(*pParam, ExtEnv_getRegisteredInterfaces *);
430 
431     pGetRegisteredInterfaces(pExtEnv, pppInterface, pnLen, memAlloc);
432 }}
433 
434 void Base::getRegisteredInterfaces(void         *** pppInterface,
435                                    sal_Int32      * pnLen,
436                                    uno_memAlloc     memAlloc)
437 {
438     uno_Environment_invoke(m_pEnv,
439                            s_getRegisteredInterfaces_v,
440                            m_pEnv->pExtEnv,
441                            pppInterface,
442                            pnLen,
443                            memAlloc,
444                            m_env_getRegisteredInterfaces);
445 }
446 
447 
448 extern "C" { static void s_computeObjectIdentifier_v(va_list * pParam)
449 {
450     uno_ExtEnvironment * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
451     void               * pInterface = va_arg(*pParam, void *);
452     rtl::OUString      * pOId       = va_arg(*pParam, rtl::OUString *);
453     ExtEnv_computeObjectIdentifier * pComputeObjectIdentifier
454         = va_arg(*pParam, ExtEnv_computeObjectIdentifier *);
455 
456     pComputeObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
457 }}
458 
459 void Base::computeObjectIdentifier(void * pInterface, rtl::OUString * pOid)
460 {
461     uno_Environment_invoke(m_pEnv,
462                            s_computeObjectIdentifier_v,
463                            m_pEnv->pExtEnv,
464                            pInterface,
465                            pOid,
466                            m_env_computeObjectIdentifier);
467 }
468 
469 
470 extern "C" { static void s_acquireInterface_v(va_list * pParam)
471 {
472     uno_ExtEnvironment * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
473     void               * pInterface = va_arg(*pParam, void *);
474     ExtEnv_acquireInterface * pAcquireInterface
475         = va_arg(*pParam, ExtEnv_acquireInterface *);
476 
477     pAcquireInterface(pExtEnv, pInterface);
478 }}
479 
480 void Base::acquireInterface(void * pInterface)
481 {
482     uno_Environment_invoke(m_pEnv, s_acquireInterface_v, m_pEnv->pExtEnv, pInterface, m_env_acquireInterface);
483 }
484 
485 
486 extern "C" { static void s_releaseInterface_v(va_list * pParam)
487 {
488     uno_ExtEnvironment * pExtEnv    = va_arg(*pParam, uno_ExtEnvironment *);
489     void               * pInterface = va_arg(*pParam, void *);
490     ExtEnv_releaseInterface * pReleaseInterface
491         = va_arg(*pParam, ExtEnv_releaseInterface *);
492 
493     pReleaseInterface(pExtEnv, pInterface);
494 }}
495 
496 void Base::releaseInterface(void * pInterface)
497 {
498     uno_Environment_invoke(m_pEnv,
499                            s_releaseInterface_v,
500                            m_pEnv->pExtEnv,
501                            pInterface,
502                            m_env_releaseInterface);
503 }
504 
505 void Base::v_enter(void)
506 {
507     m_pEnterable->enter();
508 }
509 
510 void Base::v_leave(void)
511 {
512     m_pEnterable->leave();
513 }
514 
515 void Base::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
516 {
517     m_pEnterable->callInto_v(pCallee, pParam);
518 }
519 
520 void Base::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
521 {
522     m_pEnterable->callOut_v(pCallee, pParam);
523 }
524 
525 int Base::v_isValid(rtl::OUString * pReason)
526 {
527     return m_pEnterable->isValid(pReason);
528 }
529 
530 namespace cppu { namespace helper { namespace purpenv {
531 
532 void Environment_initWithEnterable(uno_Environment * pEnvironment, cppu::Enterable * pEnterable)
533 {
534     new Base(pEnvironment, pEnterable);
535 }
536 
537 }}}
538