1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <cppinterfaceproxy.hxx>
24 #include <vtablefactory.hxx>
26 #include <com/sun/star/uno/XInterface.hpp>
27 #include <typelib/typedescription.h>
33 namespace bridges::cpp_uno::shared
{
35 void freeCppInterfaceProxy(uno_ExtEnvironment
* pEnv
, void * pInterface
)
37 CppInterfaceProxy
* pThis
= CppInterfaceProxy::castInterfaceToProxy(
39 if (pEnv
!= pThis
->pBridge
->getCppEnv()) {
43 (*pThis
->pBridge
->getUnoEnv()->revokeInterface
)(
44 pThis
->pBridge
->getUnoEnv(), pThis
->pUnoI
);
45 (*pThis
->pUnoI
->release
)( pThis
->pUnoI
);
46 ::typelib_typedescription_release(
47 &pThis
->pTypeDescr
->aBase
);
48 pThis
->pBridge
->release();
50 #if OSL_DEBUG_LEVEL > 1
51 *(int *)pInterface
= 0xdeadbabe;
53 pThis
->~CppInterfaceProxy();
54 delete[] reinterpret_cast< char * >(pThis
);
57 css::uno::XInterface
* CppInterfaceProxy::create(
58 bridges::cpp_uno::shared::Bridge
* pBridge
, uno_Interface
* pUnoI
,
59 typelib_InterfaceTypeDescription
* pTypeDescr
, OUString
const & rOId
)
61 typelib_typedescription_complete(
62 reinterpret_cast< typelib_TypeDescription
** >(&pTypeDescr
));
63 static bridges::cpp_uno::shared::VtableFactory factory
;
64 const bridges::cpp_uno::shared::VtableFactory::Vtables
& rVtables(
65 factory
.getVtables(pTypeDescr
));
66 std::unique_ptr
< char[] > pMemory(
68 sizeof (CppInterfaceProxy
)
69 + (rVtables
.count
- 1) * sizeof (void **)]);
70 new(pMemory
.get()) CppInterfaceProxy(pBridge
, pUnoI
, pTypeDescr
, rOId
);
71 CppInterfaceProxy
* pProxy
= reinterpret_cast< CppInterfaceProxy
* >(
73 for (sal_Int32 i
= 0; i
< rVtables
.count
; ++i
) {
74 pProxy
->vtables
[i
] = VtableFactory::mapBlockToVtable(
75 rVtables
.blocks
[i
].start
);
77 // coverity[leaked_storage : FALSE] - see freeCppInterfaceProxy
78 return castProxyToInterface(pProxy
);
81 void CppInterfaceProxy::acquireProxy()
85 // rebirth of proxy zombie
86 // register at cpp env
87 void * pThis
= castProxyToInterface( this );
88 (*pBridge
->getCppEnv()->registerProxyInterface
)(
89 pBridge
->getCppEnv(), &pThis
, freeCppInterfaceProxy
, oid
.pData
,
91 assert(pThis
== castProxyToInterface(this));
95 void CppInterfaceProxy::releaseProxy()
97 if (! --nRef
) // last release
99 // revoke from cpp env
100 (*pBridge
->getCppEnv()->revokeInterface
)(
101 pBridge
->getCppEnv(), castProxyToInterface( this ) );
105 CppInterfaceProxy::CppInterfaceProxy(
106 bridges::cpp_uno::shared::Bridge
* pBridge_
, uno_Interface
* pUnoI_
,
107 typelib_InterfaceTypeDescription
* pTypeDescr_
, OUString aOId_
)
109 , pBridge( pBridge_
)
111 , pTypeDescr( pTypeDescr_
)
112 , oid(std::move( aOId_
))
115 ::typelib_typedescription_acquire( &pTypeDescr
->aBase
);
116 (*pUnoI
->acquire
)( pUnoI
);
117 (*pBridge
->getUnoEnv()->registerInterface
)(
118 pBridge
->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI
), oid
.pData
,
122 CppInterfaceProxy::~CppInterfaceProxy()
125 css::uno::XInterface
* CppInterfaceProxy::castProxyToInterface(
126 CppInterfaceProxy
* pProxy
)
128 return reinterpret_cast< css::uno::XInterface
* >(
132 CppInterfaceProxy
* CppInterfaceProxy::castInterfaceToProxy(void * pInterface
)
134 // pInterface == &pProxy->vtables (this emulated offsetof is not truly
136 char const * const base
= reinterpret_cast< char const * >(16);
137 std::ptrdiff_t const offset
= reinterpret_cast< char const * >(
138 &reinterpret_cast< CppInterfaceProxy
const * >(base
)->vtables
) - base
;
139 return reinterpret_cast< CppInterfaceProxy
* >(
140 static_cast< char * >(pInterface
) - offset
);
145 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */