LibreOffice Module cppu (master) 1
helper_purpenv_Environment.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22
23#include <osl/diagnose.h>
24#include <sal/log.hxx>
25#include <uno/lbnames.h>
26#include <cppu/Enterable.hxx>
27
28#include <typelib/typedescription.h>
29#include <osl/interlck.h>
30#include <memory>
31
32extern "C" {
33typedef void EnvFun_P (uno_Environment *);
34typedef void EnvFun_PP_P(uno_Environment ** ppHardEnv, uno_Environment *);
35typedef void ExtEnv_registerProxyInterface (uno_ExtEnvironment *,
36 void ** ppProxy,
37 uno_freeProxyFunc freeProxy,
38 rtl_uString * pOId,
39 typelib_InterfaceTypeDescription * pTypeDescr);
40typedef void ExtEnv_revokeInterface (uno_ExtEnvironment *,
41 void * pInterface);
42typedef void ExtEnv_getObjectIdentifier (uno_ExtEnvironment *,
43 rtl_uString **,
44 void *);
45typedef void ExtEnv_getRegisteredInterface (uno_ExtEnvironment *,
46 void **,
47 rtl_uString *,
48 typelib_InterfaceTypeDescription *);
49typedef void ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment *,
50 void *** pppInterfaces,
51 sal_Int32 * pnLen,
52 uno_memAlloc memAlloc);
53typedef void ExtEnv_computeObjectIdentifier(uno_ExtEnvironment *,
54 rtl_uString ** ppOId,
55 void * pInterface);
56typedef void ExtEnv_acquireInterface (uno_ExtEnvironment *,
57 void * pInterface);
58typedef void ExtEnv_releaseInterface (uno_ExtEnvironment *,
59 void * pInterface);
60}
61
62namespace {
63
64class Base : public cppu::Enterable
65{
66public:
67 explicit Base(uno_Environment * pEnv, cppu::Enterable * pEnterable);
68
69 void acquireWeak();
70 void releaseWeak();
71 void harden (uno_Environment ** ppHardEnv);
72 void acquire();
73 void release();
74
75 void registerProxyInterface (void ** ppProxy,
76 uno_freeProxyFunc freeProxy,
77 OUString const & oid,
78 typelib_InterfaceTypeDescription * pTypeDescr);
79 void revokeInterface (void * pInterface);
80 void getObjectIdentifier (void * pInterface,
81 OUString * pOid);
82 void getRegisteredInterface (void **,
83 OUString const & oid,
84 typelib_InterfaceTypeDescription *);
85 void getRegisteredInterfaces(void ***,
86 sal_Int32 * pnLen,
87 uno_memAlloc memAlloc);
88 void computeObjectIdentifier(void * pInterface,
89 OUString * pOid);
90 void acquireInterface (void * pInterface);
91 void releaseInterface (void * pInterface);
92
93 virtual void v_enter() override;
94 virtual void v_leave() override;
95 virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) override;
96 virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam) override;
97 virtual bool v_isValid (OUString * pReason) override;
98
99protected:
100 oslInterlockedCount m_nRef;
101 uno_Environment * m_pEnv;
102 std::unique_ptr<cppu::Enterable> m_pEnterable;
103
104 EnvFun_P * m_env_acquire;
105 EnvFun_P * m_env_release;
106 EnvFun_PP_P * m_env_harden;
107 EnvFun_P * m_env_acquireWeak;
108 EnvFun_P * m_env_releaseWeak;
109
110 ExtEnv_registerProxyInterface * m_env_registerProxyInterface;
111 ExtEnv_revokeInterface * m_env_revokeInterface;
112 ExtEnv_getObjectIdentifier * m_env_getObjectIdentifier;
113 ExtEnv_getRegisteredInterface * m_env_getRegisteredInterface;
114 ExtEnv_getRegisteredInterfaces * m_env_getRegisteredInterfaces;
115 ExtEnv_computeObjectIdentifier * m_env_computeObjectIdentifier;
116 ExtEnv_acquireInterface * m_env_acquireInterface;
117 ExtEnv_releaseInterface * m_env_releaseInterface;
118
119 virtual ~Base() override;
120};
121
122}
123
124extern "C" {
125static void s_acquire(uno_Environment * pEnv) //SAL_THROW_EXTERN_C()
126{
127 Base * pBase = static_cast<Base *>(pEnv->pReserved);
128 pBase->acquire();
129}
130
132{
133 Base * pBase = static_cast<Base *>(pEnv->pReserved);
134 pBase->release();
135}
136
138{
139 Base * pBase = static_cast<Base *>(pEnv->pReserved);
140 pBase->harden(ppHardEnv);
141}
142
144{
145 Base * pBase = static_cast<Base *>(pEnv->pReserved);
146 pBase->acquireWeak();
147}
148
150{
151 Base * pBase = static_cast<Base *>(pEnv->pReserved);
152 pBase->releaseWeak();
153}
154
155
156static void s_registerProxyInterface(uno_ExtEnvironment * pExtEnv,
157 void ** ppProxy,
158 uno_freeProxyFunc freeProxy,
159 rtl_uString * pOId,
160 typelib_InterfaceTypeDescription * pTypeDescr)
161{
162 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
163 pBase->registerProxyInterface(ppProxy, freeProxy, pOId, pTypeDescr);
164}
165
166static void s_revokeInterface(uno_ExtEnvironment * pExtEnv, void * pInterface)
167{
168 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
169 pBase->revokeInterface(pInterface);
170}
171
172static void s_getObjectIdentifier(uno_ExtEnvironment * pExtEnv,
173 rtl_uString ** ppOId,
174 void * pInterface)
175{
176 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
177 pBase->getObjectIdentifier(pInterface, reinterpret_cast<OUString *>(ppOId));
178}
179
180static void s_getRegisteredInterface(uno_ExtEnvironment * pExtEnv,
181 void ** ppInterface,
182 rtl_uString * pOId,
183 typelib_InterfaceTypeDescription * pTypeDescr)
184{
185 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
186 pBase->getRegisteredInterface(ppInterface, pOId, pTypeDescr);
187}
188
189static void s_getRegisteredInterfaces(uno_ExtEnvironment * pExtEnv,
190 void *** pppInterface,
191 sal_Int32 * pnLen,
192 uno_memAlloc memAlloc)
193{
194 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
195 pBase->getRegisteredInterfaces(pppInterface, pnLen, memAlloc);
196}
197
198static void s_computeObjectIdentifier(uno_ExtEnvironment * pExtEnv,
199 rtl_uString ** ppOId,
200 void * pInterface)
201{
202 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
203 pBase->computeObjectIdentifier(pInterface, reinterpret_cast<OUString *>(ppOId));
204}
205
206static void s_acquireInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
207 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
208 pBase->acquireInterface(pInterface);
209}
210
211static void s_releaseInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
212 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
213 pBase->releaseInterface(pInterface);
214}
215
216}
217
218Base::Base(uno_Environment * pEnv, cppu::Enterable * pEnterable)
219 :m_nRef(1),
220 m_pEnv(pEnv),
221 m_pEnterable (pEnterable),
222 m_env_acquire (pEnv->acquire),
223 m_env_release (pEnv->release),
224 m_env_harden (pEnv->harden),
225 m_env_acquireWeak(pEnv->acquireWeak),
226 m_env_releaseWeak(pEnv->releaseWeak),
227 m_env_registerProxyInterface (pEnv->pExtEnv->registerProxyInterface),
228 m_env_revokeInterface (pEnv->pExtEnv->revokeInterface),
229 m_env_getObjectIdentifier (pEnv->pExtEnv->getObjectIdentifier),
230 m_env_getRegisteredInterface (pEnv->pExtEnv->getRegisteredInterface),
231 m_env_getRegisteredInterfaces(pEnv->pExtEnv->getRegisteredInterfaces),
232 m_env_computeObjectIdentifier(pEnv->pExtEnv->computeObjectIdentifier),
233 m_env_acquireInterface (pEnv->pExtEnv->acquireInterface),
234 m_env_releaseInterface (pEnv->pExtEnv->releaseInterface)
235{
236 SAL_INFO("cppu.purpenv", "LIFE: cppu::helper::purpenv::Base::Base(uno_Environment * pEnv) -> " << this);
237 OSL_ENSURE(
238 rtl_ustr_ascii_compare_WithLength(pEnv->pTypeName->buffer, rtl_str_getLength(UNO_LB_UNO), UNO_LB_UNO)
239 == 0,
240 "### wrong environment type!");
241
242 pEnv->acquire = s_acquire;
243 pEnv->release = s_release;
244 pEnv->harden = s_harden;
245 pEnv->acquireWeak = s_acquireWeak;
246 pEnv->releaseWeak = s_releaseWeak;
247
248 pEnv->pExtEnv->registerProxyInterface = s_registerProxyInterface;
249 pEnv->pExtEnv->revokeInterface = s_revokeInterface;
250 pEnv->pExtEnv->getObjectIdentifier = s_getObjectIdentifier;
251 pEnv->pExtEnv->getRegisteredInterface = s_getRegisteredInterface;
252 pEnv->pExtEnv->getRegisteredInterfaces = s_getRegisteredInterfaces;
253 pEnv->pExtEnv->computeObjectIdentifier = s_computeObjectIdentifier;
254 pEnv->pExtEnv->acquireInterface = s_acquireInterface;
255 pEnv->pExtEnv->releaseInterface = s_releaseInterface;
256
257 pEnv->pReserved = this;
258}
259
260Base::~Base()
261{
262 SAL_INFO("cppu.purpenv", "LIFE: cppu::helper::purpenv::Base::~Base() -> " << this);
263
264 m_pEnv->acquire = m_env_acquire;
265 m_pEnv->release = m_env_release;
266 m_pEnv->harden = m_env_harden;
267 m_pEnv->acquireWeak = m_env_acquireWeak;
268 m_pEnv->releaseWeak = m_env_releaseWeak;
269
270 m_pEnv->pReserved = nullptr;
271
272 m_pEnterable.reset();
273 m_pEnv->release(m_pEnv);
274}
275
276void Base::acquire()
277{
278 m_env_acquire(m_pEnv);
279
280 osl_atomic_increment(&m_nRef);
281}
282
283void Base::release()
284{
285 if (osl_atomic_decrement(&m_nRef) == 0)
286 delete this;
287
288 else
289 m_env_release(m_pEnv);
290}
291
292void Base::harden(uno_Environment ** ppHardEnv)
293{
294 m_env_harden(ppHardEnv, m_pEnv);
295 osl_atomic_increment(&m_nRef);
296}
297
298void Base::acquireWeak()
299{
300 m_env_acquireWeak(m_pEnv);
301}
302
303void Base::releaseWeak()
304{
305 m_env_releaseWeak(m_pEnv);
306}
307
308
309extern "C" { static void s_registerProxyInterface_v(va_list * pParam)
310{
311 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
312 void ** ppProxy = va_arg(*pParam, void **);
313 uno_freeProxyFunc freeProxy = va_arg(*pParam, uno_freeProxyFunc);
314 rtl_uString * pOId = va_arg(*pParam, rtl_uString *);
315 typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
316 ExtEnv_registerProxyInterface * pRegisterProxyInterface
317 = va_arg(*pParam, ExtEnv_registerProxyInterface *);
318
319 pRegisterProxyInterface(pExtEnv, ppProxy, freeProxy, pOId, pTypeDescr);
320}}
321
322void Base::registerProxyInterface(void ** ppProxy,
323 uno_freeProxyFunc freeProxy,
324 OUString const & oid,
325 typelib_InterfaceTypeDescription * pTypeDescr)
326{
329 m_pEnv->pExtEnv,
330 ppProxy,
331 freeProxy,
332 oid.pData,
333 pTypeDescr,
334 m_env_registerProxyInterface);
335}
336
337
338extern "C" { static void s_revokeInterface_v(va_list * pParam)
339{
340 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
341 void * pInterface = va_arg(*pParam, void *);
342 ExtEnv_revokeInterface * pRevokeInterface = va_arg(*pParam, ExtEnv_revokeInterface *);
343
344 pRevokeInterface(pExtEnv, pInterface);
345}}
346
347void Base::revokeInterface(void * pInterface)
348{
351 m_pEnv->pExtEnv,
352 pInterface,
353 m_env_revokeInterface);
354}
355
356
357extern "C" { static void s_getObjectIdentifier_v(va_list * pParam)
358{
359 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
360 void * pInterface = va_arg(*pParam, void *);
361 OUString * pOId = va_arg(*pParam, OUString *);
362 ExtEnv_getObjectIdentifier * pGetObjectIdentifier
363 = va_arg(*pParam, ExtEnv_getObjectIdentifier *);
364
365 pGetObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
366}}
367
368void Base::getObjectIdentifier(void * pInterface, OUString * pOid)
369{
372 m_pEnv->pExtEnv,
373 pInterface,
374 pOid,
375 m_env_getObjectIdentifier);
376}
377
378
379extern "C" { static void s_getRegisteredInterface_v(va_list * pParam)
380{
381 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
382 void ** ppInterface = va_arg(*pParam, void **);
383 rtl_uString * pOId = va_arg(*pParam, rtl_uString *);
384 typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
385 ExtEnv_getRegisteredInterface * pGetRegisteredInterface
386 = va_arg(*pParam, ExtEnv_getRegisteredInterface *);
387
388 pGetRegisteredInterface(pExtEnv, ppInterface, pOId, pTypeDescr);
389}}
390
391void Base::getRegisteredInterface(void ** ppInterface,
392 OUString const & oid,
393 typelib_InterfaceTypeDescription * pTypeDescr)
394{
397 m_pEnv->pExtEnv,
398 ppInterface,
399 oid.pData,
400 pTypeDescr,
401 m_env_getRegisteredInterface);
402}
403
404
405extern "C" { static void s_getRegisteredInterfaces_v(va_list * pParam)
406{
407 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
408 void *** pppInterface = va_arg(*pParam, void ***);
409 sal_Int32 * pnLen = va_arg(*pParam, sal_Int32 *);
410 uno_memAlloc memAlloc = va_arg(*pParam, uno_memAlloc);
411 ExtEnv_getRegisteredInterfaces * pGetRegisteredInterfaces
412 = va_arg(*pParam, ExtEnv_getRegisteredInterfaces *);
413
414 pGetRegisteredInterfaces(pExtEnv, pppInterface, pnLen, memAlloc);
415}}
416
417void Base::getRegisteredInterfaces(void *** pppInterface,
418 sal_Int32 * pnLen,
419 uno_memAlloc memAlloc)
420{
423 m_pEnv->pExtEnv,
424 pppInterface,
425 pnLen,
426 memAlloc,
427 m_env_getRegisteredInterfaces);
428}
429
430
431extern "C" { static void s_computeObjectIdentifier_v(va_list * pParam)
432{
433 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
434 void * pInterface = va_arg(*pParam, void *);
435 OUString * pOId = va_arg(*pParam, OUString *);
436 ExtEnv_computeObjectIdentifier * pComputeObjectIdentifier
437 = va_arg(*pParam, ExtEnv_computeObjectIdentifier *);
438
439 pComputeObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
440}}
441
442void Base::computeObjectIdentifier(void * pInterface, OUString * pOid)
443{
446 m_pEnv->pExtEnv,
447 pInterface,
448 pOid,
449 m_env_computeObjectIdentifier);
450}
451
452
453extern "C" { static void s_acquireInterface_v(va_list * pParam)
454{
455 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
456 void * pInterface = va_arg(*pParam, void *);
457 ExtEnv_acquireInterface * pAcquireInterface
458 = va_arg(*pParam, ExtEnv_acquireInterface *);
459
460 pAcquireInterface(pExtEnv, pInterface);
461}}
462
463void Base::acquireInterface(void * pInterface)
464{
465 uno_Environment_invoke(m_pEnv, s_acquireInterface_v, m_pEnv->pExtEnv, pInterface, m_env_acquireInterface);
466}
467
468
469extern "C" { static void s_releaseInterface_v(va_list * pParam)
470{
471 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
472 void * pInterface = va_arg(*pParam, void *);
473 ExtEnv_releaseInterface * pReleaseInterface
474 = va_arg(*pParam, ExtEnv_releaseInterface *);
475
476 pReleaseInterface(pExtEnv, pInterface);
477}}
478
479void Base::releaseInterface(void * pInterface)
480{
483 m_pEnv->pExtEnv,
484 pInterface,
485 m_env_releaseInterface);
486}
487
488void Base::v_enter()
489{
490 m_pEnterable->enter();
491}
492
493void Base::v_leave()
494{
495 m_pEnterable->leave();
496}
497
498void Base::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
499{
500 m_pEnterable->callInto_v(pCallee, pParam);
501}
502
503void Base::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
504{
505 m_pEnterable->callOut_v(pCallee, pParam);
506}
507
508bool Base::v_isValid(OUString * pReason)
509{
510 return m_pEnterable->isValid(pReason);
511}
512
514
516{
517 new Base(pEnvironment, pEnterable);
518}
519
520}
521
522/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SAL_CALL uno_Environment_invoke(uno_Environment *pEnv, uno_EnvCallee *pCallee,...) SAL_THROW_EXTERN_C()
Definition: EnvStack.cxx:315
C++ wrapper for binary C Enterable (http://wiki.openoffice.org/wiki/Uno/Cpp/Spec/Environment_Stack)
Definition: Enterable.hxx:39
virtual void v_enter()=0
virtual bool v_isValid(rtl::OUString *pReason)=0
virtual void v_callOut_v(uno_EnvCallee *pCallee, va_list *pParam)=0
virtual void v_leave()=0
virtual void v_callInto_v(uno_EnvCallee *pCallee, va_list *pParam)=0
struct _uno_Environment uno_Environment
static void s_registerProxyInterface_v(va_list *pParam)
static void s_computeObjectIdentifier_v(va_list *pParam)
static void s_acquireInterface(uno_ExtEnvironment *pExtEnv, void *pInterface)
static void s_harden(uno_Environment **ppHardEnv, uno_Environment *pEnv) SAL_THROW_EXTERN_C()
void ExtEnv_acquireInterface(uno_ExtEnvironment *, void *pInterface)
static void s_acquire(uno_Environment *pEnv)
static void s_revokeInterface(uno_ExtEnvironment *pExtEnv, void *pInterface)
static void s_computeObjectIdentifier(uno_ExtEnvironment *pExtEnv, rtl_uString **ppOId, void *pInterface)
void ExtEnv_getRegisteredInterface(uno_ExtEnvironment *, void **, rtl_uString *, typelib_InterfaceTypeDescription *)
static void s_releaseInterface(uno_ExtEnvironment *pExtEnv, void *pInterface)
static void s_getRegisteredInterfaces(uno_ExtEnvironment *pExtEnv, void ***pppInterface, sal_Int32 *pnLen, uno_memAlloc memAlloc)
static void s_getRegisteredInterface_v(va_list *pParam)
void ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment *, void ***pppInterfaces, sal_Int32 *pnLen, uno_memAlloc memAlloc)
static void s_acquireInterface_v(va_list *pParam)
static void s_getRegisteredInterfaces_v(va_list *pParam)
void ExtEnv_revokeInterface(uno_ExtEnvironment *, void *pInterface)
static void s_registerProxyInterface(uno_ExtEnvironment *pExtEnv, void **ppProxy, uno_freeProxyFunc freeProxy, rtl_uString *pOId, typelib_InterfaceTypeDescription *pTypeDescr)
static void s_getRegisteredInterface(uno_ExtEnvironment *pExtEnv, void **ppInterface, rtl_uString *pOId, typelib_InterfaceTypeDescription *pTypeDescr)
void ExtEnv_releaseInterface(uno_ExtEnvironment *, void *pInterface)
void ExtEnv_getObjectIdentifier(uno_ExtEnvironment *, rtl_uString **, void *)
static void s_release(uno_Environment *pEnv) SAL_THROW_EXTERN_C()
static void s_revokeInterface_v(va_list *pParam)
static void s_getObjectIdentifier(uno_ExtEnvironment *pExtEnv, rtl_uString **ppOId, void *pInterface)
static void s_acquireWeak(uno_Environment *pEnv) SAL_THROW_EXTERN_C()
void EnvFun_PP_P(uno_Environment **ppHardEnv, uno_Environment *)
void ExtEnv_registerProxyInterface(uno_ExtEnvironment *, void **ppProxy, uno_freeProxyFunc freeProxy, rtl_uString *pOId, typelib_InterfaceTypeDescription *pTypeDescr)
static void s_releaseWeak(uno_Environment *pEnv) SAL_THROW_EXTERN_C()
static void s_getObjectIdentifier_v(va_list *pParam)
static void s_releaseInterface_v(va_list *pParam)
void ExtEnv_computeObjectIdentifier(uno_ExtEnvironment *, rtl_uString **ppOId, void *pInterface)
void EnvFun_P(uno_Environment *)
oslInterlockedCount m_nRef
#define SAL_INFO(area, stream)
void Environment_initWithEnterable(uno_Environment *pEnvironment, cppu::Enterable *pEnterable)
C++ helper for implementing Purpose Environments.
#define SAL_THROW_EXTERN_C()
Base