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