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_bridges.hxx"
26 
27 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
28 
29 #include "bridges/cpp_uno/shared/bridge.hxx"
30 
31 #include "com/sun/star/uno/XInterface.hpp"
32 #include "osl/diagnose.h"
33 #include "osl/interlck.h"
34 #include "typelib/typedescription.h"
35 #include "uno/dispatcher.h"
36 
37 namespace bridges { namespace cpp_uno { namespace shared {
38 
freeUnoInterfaceProxy(uno_ExtEnvironment * pEnv,void * pProxy)39 void freeUnoInterfaceProxy(uno_ExtEnvironment * pEnv, void * pProxy)
40 {
41     UnoInterfaceProxy * pThis =
42         static_cast< UnoInterfaceProxy * >(
43             reinterpret_cast< uno_Interface * >( pProxy ) );
44     if (pEnv != pThis->pBridge->getUnoEnv()) {
45         OSL_ASSERT(false);
46     }
47 
48     (*pThis->pBridge->getCppEnv()->revokeInterface)(
49         pThis->pBridge->getCppEnv(), pThis->pCppI );
50     pThis->pCppI->release();
51     ::typelib_typedescription_release(
52         (typelib_TypeDescription *)pThis->pTypeDescr );
53     pThis->pBridge->release();
54 
55 #if OSL_DEBUG_LEVEL > 1
56     *(int *)pProxy = 0xdeadbabe;
57 #endif
58     delete pThis;
59 }
60 
acquireProxy(uno_Interface * pUnoI)61 void acquireProxy(uno_Interface * pUnoI)
62 {
63     if (1 == osl_incrementInterlockedCount(
64             & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
65     {
66         // rebirth of proxy zombie
67         // register at uno env
68 #if OSL_DEBUG_LEVEL > 1
69         void * pThis = pUnoI;
70 #endif
71         (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
72          registerProxyInterface)(
73              static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
74              reinterpret_cast< void ** >( &pUnoI ), freeUnoInterfaceProxy,
75              static_cast< UnoInterfaceProxy * >( pUnoI )->oid.pData,
76              static_cast< UnoInterfaceProxy * >( pUnoI )->pTypeDescr );
77 #if OSL_DEBUG_LEVEL > 1
78         OSL_ASSERT( pThis == pUnoI );
79 #endif
80     }
81 }
82 
releaseProxy(uno_Interface * pUnoI)83 void releaseProxy(uno_Interface * pUnoI)
84 {
85     if (! osl_decrementInterlockedCount(
86             & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
87     {
88         // revoke from uno env on last release
89         (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
90          revokeInterface)(
91              static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
92              pUnoI );
93     }
94 }
95 
create(bridges::cpp_uno::shared::Bridge * pBridge,com::sun::star::uno::XInterface * pCppI,typelib_InterfaceTypeDescription * pTypeDescr,rtl::OUString const & rOId)96 UnoInterfaceProxy * UnoInterfaceProxy::create(
97     bridges::cpp_uno::shared::Bridge * pBridge,
98     com::sun::star::uno::XInterface * pCppI,
99     typelib_InterfaceTypeDescription * pTypeDescr,
100     rtl::OUString const & rOId) SAL_THROW(())
101 {
102     return new UnoInterfaceProxy(pBridge, pCppI, pTypeDescr, rOId);
103 }
104 
UnoInterfaceProxy(bridges::cpp_uno::shared::Bridge * pBridge_,com::sun::star::uno::XInterface * pCppI_,typelib_InterfaceTypeDescription * pTypeDescr_,rtl::OUString const & rOId_)105 UnoInterfaceProxy::UnoInterfaceProxy(
106     bridges::cpp_uno::shared::Bridge * pBridge_,
107     com::sun::star::uno::XInterface * pCppI_,
108     typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_)
109     SAL_THROW(())
110     : nRef( 1 )
111     , pBridge( pBridge_ )
112     , pCppI( pCppI_ )
113     , pTypeDescr( pTypeDescr_ )
114     , oid( rOId_ )
115 {
116     pBridge->acquire();
117     ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
118     if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete)
119         ::typelib_typedescription_complete(
120             (typelib_TypeDescription **)&pTypeDescr );
121     OSL_ENSURE(
122         ((typelib_TypeDescription *)pTypeDescr)->bComplete,
123         "### type is incomplete!" );
124     pCppI->acquire();
125     (*pBridge->getCppEnv()->registerInterface)(
126         pBridge->getCppEnv(), reinterpret_cast< void ** >( &pCppI ), oid.pData,
127         pTypeDescr );
128 
129     // uno_Interface
130     acquire = acquireProxy;
131     release = releaseProxy;
132     pDispatcher = unoInterfaceProxyDispatch;
133 }
134 
~UnoInterfaceProxy()135 UnoInterfaceProxy::~UnoInterfaceProxy()
136 {}
137 
138 } } }
139