LibreOffice Module bridges (master)  1
cppinterfaceproxy.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 #include <cppinterfaceproxy.hxx>
21 
22 #include <bridge.hxx>
23 #include <vtablefactory.hxx>
24 
25 #include <com/sun/star/uno/XInterface.hpp>
26 #include <typelib/typedescription.h>
27 
28 #include <cstddef>
29 #include <memory>
30 #include <new>
31 
32 namespace bridges::cpp_uno::shared {
33 
34 void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
35 {
37  pInterface);
38  if (pEnv != pThis->pBridge->getCppEnv()) {
39  assert(false);
40  }
41 
42  (*pThis->pBridge->getUnoEnv()->revokeInterface)(
43  pThis->pBridge->getUnoEnv(), pThis->pUnoI );
44  (*pThis->pUnoI->release)( pThis->pUnoI );
45  ::typelib_typedescription_release(
46  &pThis->pTypeDescr->aBase );
47  pThis->pBridge->release();
48 
49 #if OSL_DEBUG_LEVEL > 1
50  *(int *)pInterface = 0xdeadbabe;
51 #endif
52  pThis->~CppInterfaceProxy();
53  delete[] reinterpret_cast< char * >(pThis);
54 }
55 
56 com::sun::star::uno::XInterface * CppInterfaceProxy::create(
57  bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI,
58  typelib_InterfaceTypeDescription * pTypeDescr, OUString const & rOId)
59 {
61  reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
64  factory.getVtables(pTypeDescr));
65  std::unique_ptr< char[] > pMemory(
66  new char[
67  sizeof (CppInterfaceProxy)
68  + (rVtables.count - 1) * sizeof (void **)]);
69  new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
70  CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
71  pMemory.release());
72  for (sal_Int32 i = 0; i < rVtables.count; ++i) {
74  rVtables.blocks[i].start);
75  }
76  return castProxyToInterface(pProxy);
77 }
78 
80 {
81  if (++nRef == 1)
82  {
83  // rebirth of proxy zombie
84  // register at cpp env
85  void * pThis = castProxyToInterface( this );
86  (*pBridge->getCppEnv()->registerProxyInterface)(
87  pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
88  pTypeDescr );
89  assert(pThis == castProxyToInterface(this));
90  }
91 }
92 
94 {
95  if (! --nRef ) // last release
96  {
97  // revoke from cpp env
98  (*pBridge->getCppEnv()->revokeInterface)(
100  }
101 }
102 
104  bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_,
105  typelib_InterfaceTypeDescription * pTypeDescr_, OUString const & rOId_)
106  : nRef( 1 )
107  , pBridge( pBridge_ )
108  , pUnoI( pUnoI_ )
109  , pTypeDescr( pTypeDescr_ )
110  , oid( rOId_ )
111 {
112  pBridge->acquire();
113  ::typelib_typedescription_acquire( &pTypeDescr->aBase );
114  (*pUnoI->acquire)( pUnoI );
115  (*pBridge->getUnoEnv()->registerInterface)(
116  pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
117  pTypeDescr );
118 }
119 
121 {}
122 
123 com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
124  CppInterfaceProxy * pProxy)
125 {
126  return reinterpret_cast< com::sun::star::uno::XInterface * >(
127  &pProxy->vtables);
128 }
129 
131 {
132  // pInterface == &pProxy->vtables (this emulated offsetof is not truly
133  // portable):
134  char const * const base = reinterpret_cast< char const * >(16);
135  std::ptrdiff_t const offset = reinterpret_cast< char const * >(
136  &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
137  return reinterpret_cast< CppInterfaceProxy * >(
138  static_cast< char * >(pInterface) - offset);
139 }
140 
141 }
142 
143 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
friend void freeCppInterfaceProxy(uno_ExtEnvironment *pEnv, void *pInterface)
CppInterfaceProxy(CppInterfaceProxy const &)=delete
static com::sun::star::uno::XInterface * castProxyToInterface(CppInterfaceProxy *pProxy)
Hand out vtable structures for interface type descriptions.
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_Bool SAL_CALL typelib_typedescription_complete(typelib_TypeDescription **ppTypeDescr) SAL_THROW_EXTERN_C()
uno_ExtEnvironment * getUnoEnv()
Definition: bridge.hxx:70
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
static com::sun::star::uno::XInterface * create(Bridge *pBridge, uno_Interface *pUnoI, typelib_InterfaceTypeDescription *pTypeDescr, OUString const &rOId)
uno_ExtEnvironment * getCppEnv()
Definition: bridge.hxx:69
sal_Int32 nRef
A cpp proxy wrapping a uno interface.
The vtable structure corresponding to an interface type.
int i
typelib_InterfaceTypeDescription * pTypeDescr
void const * base
void freeCppInterfaceProxy(uno_ExtEnvironment *pEnv, void *pInterface)
Holding environments and mappings.
Definition: bridge.hxx:54
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
const Vtables & getVtables(typelib_InterfaceTypeDescription *type)
Given an interface type description, return its corresponding vtable structure.