xref: /AOO41X/main/binaryurp/source/proxy.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir *
3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir *
5*cdf0e10cSrcweir * Copyright 2000, 2011 Oracle and/or its affiliates.
6*cdf0e10cSrcweir *
7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir *
9*cdf0e10cSrcweir * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir *
11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir *
15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir *
21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir *
26*cdf0e10cSrcweir ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "sal/config.h"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <exception>
31*cdf0e10cSrcweir #include <vector>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
34*cdf0e10cSrcweir #include "osl/diagnose.h"
35*cdf0e10cSrcweir #include "rtl/ref.hxx"
36*cdf0e10cSrcweir #include "rtl/ustring.hxx"
37*cdf0e10cSrcweir #include "sal/types.h"
38*cdf0e10cSrcweir #include "typelib/typedescription.h"
39*cdf0e10cSrcweir #include "typelib/typedescription.hxx"
40*cdf0e10cSrcweir #include "uno/any2.h"
41*cdf0e10cSrcweir #include "uno/dispatcher.h"
42*cdf0e10cSrcweir #include "uno/dispatcher.hxx"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include "binaryany.hxx"
45*cdf0e10cSrcweir #include "bridge.hxx"
46*cdf0e10cSrcweir #include "proxy.hxx"
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir namespace binaryurp {
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir namespace {
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir namespace css = com::sun::star;
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_acquireInterface(uno_Interface * pInterface) {
55*cdf0e10cSrcweir     OSL_ASSERT(pInterface != 0);
56*cdf0e10cSrcweir     static_cast< Proxy * >(pInterface)->do_acquire();
57*cdf0e10cSrcweir }
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_releaseInterface(uno_Interface * pInterface) {
60*cdf0e10cSrcweir     OSL_ASSERT(pInterface != 0);
61*cdf0e10cSrcweir     static_cast< Proxy * >(pInterface)->do_release();
62*cdf0e10cSrcweir }
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_dispatchInterface(
65*cdf0e10cSrcweir     uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
66*cdf0e10cSrcweir     void * pReturn, void ** pArgs, uno_Any ** ppException)
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir     OSL_ASSERT(pUnoI != 0);
69*cdf0e10cSrcweir     static_cast< Proxy * >(pUnoI)->do_dispatch(
70*cdf0e10cSrcweir         pMemberType, pReturn, pArgs, ppException);
71*cdf0e10cSrcweir }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir Proxy::Proxy(
76*cdf0e10cSrcweir     rtl::Reference< Bridge > const & bridge, rtl::OUString const & oid,
77*cdf0e10cSrcweir     css::uno::TypeDescription const & type):
78*cdf0e10cSrcweir     bridge_(bridge), oid_(oid), type_(type), references_(1)
79*cdf0e10cSrcweir {
80*cdf0e10cSrcweir     OSL_ASSERT(bridge.is());
81*cdf0e10cSrcweir     acquire = &proxy_acquireInterface;
82*cdf0e10cSrcweir     release = &proxy_releaseInterface;
83*cdf0e10cSrcweir     pDispatcher = &proxy_dispatchInterface;
84*cdf0e10cSrcweir }
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir rtl::OUString Proxy::getOid() const {
87*cdf0e10cSrcweir     return oid_;
88*cdf0e10cSrcweir }
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir css::uno::TypeDescription Proxy::getType() const {
91*cdf0e10cSrcweir     return type_;
92*cdf0e10cSrcweir }
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir void Proxy::do_acquire() {
95*cdf0e10cSrcweir     if (osl_incrementInterlockedCount(&references_) == 1) {
96*cdf0e10cSrcweir         bridge_->resurrectProxy(*this);
97*cdf0e10cSrcweir     }
98*cdf0e10cSrcweir }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir void Proxy::do_release() {
101*cdf0e10cSrcweir     if (osl_decrementInterlockedCount(&references_) == 0) {
102*cdf0e10cSrcweir         bridge_->revokeProxy(*this);
103*cdf0e10cSrcweir     }
104*cdf0e10cSrcweir }
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir void Proxy::do_free() {
107*cdf0e10cSrcweir     bridge_->freeProxy(*this);
108*cdf0e10cSrcweir     delete this;
109*cdf0e10cSrcweir }
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir void Proxy::do_dispatch(
112*cdf0e10cSrcweir     typelib_TypeDescription const * member, void * returnValue,
113*cdf0e10cSrcweir     void ** arguments, uno_Any ** exception) const
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     try {
116*cdf0e10cSrcweir         try {
117*cdf0e10cSrcweir             do_dispatch_throw(member, returnValue, arguments, exception);
118*cdf0e10cSrcweir         } catch (std::exception & e) {
119*cdf0e10cSrcweir             throw css::uno::RuntimeException(
120*cdf0e10cSrcweir                 (rtl::OUString(
121*cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
122*cdf0e10cSrcweir                  rtl::OStringToOUString(
123*cdf0e10cSrcweir                      rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)),
124*cdf0e10cSrcweir                 css::uno::Reference< css::uno::XInterface >());
125*cdf0e10cSrcweir                 // best-effort string conversion
126*cdf0e10cSrcweir         }
127*cdf0e10cSrcweir     } catch (css::uno::RuntimeException &) {
128*cdf0e10cSrcweir         css::uno::Any exc(cppu::getCaughtException());
129*cdf0e10cSrcweir         uno_copyAndConvertData(
130*cdf0e10cSrcweir             *exception, &exc,
131*cdf0e10cSrcweir             (css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()).
132*cdf0e10cSrcweir              get()),
133*cdf0e10cSrcweir             bridge_->getCppToBinaryMapping().get());
134*cdf0e10cSrcweir     }
135*cdf0e10cSrcweir }
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir bool Proxy::isProxy(
138*cdf0e10cSrcweir     rtl::Reference< Bridge > const & bridge,
139*cdf0e10cSrcweir     css::uno::UnoInterfaceReference const & object, rtl::OUString * oid)
140*cdf0e10cSrcweir {
141*cdf0e10cSrcweir     OSL_ASSERT(object.is());
142*cdf0e10cSrcweir     return object.m_pUnoI->acquire == &proxy_acquireInterface &&
143*cdf0e10cSrcweir         static_cast< Proxy * >(object.m_pUnoI)->isProxy(bridge, oid);
144*cdf0e10cSrcweir }
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir Proxy::~Proxy() {}
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir void Proxy::do_dispatch_throw(
149*cdf0e10cSrcweir     typelib_TypeDescription const * member, void * returnValue,
150*cdf0e10cSrcweir     void ** arguments, uno_Any ** exception) const
151*cdf0e10cSrcweir {
152*cdf0e10cSrcweir     //TODO: Optimize queryInterface:
153*cdf0e10cSrcweir     OSL_ASSERT(member != 0);
154*cdf0e10cSrcweir     bool setter = false;
155*cdf0e10cSrcweir     std::vector< BinaryAny > inArgs;
156*cdf0e10cSrcweir     switch (member->eTypeClass) {
157*cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
158*cdf0e10cSrcweir         setter = returnValue == 0;
159*cdf0e10cSrcweir         if (setter) {
160*cdf0e10cSrcweir             inArgs.push_back(
161*cdf0e10cSrcweir                 BinaryAny(
162*cdf0e10cSrcweir                     css::uno::TypeDescription(
163*cdf0e10cSrcweir                         reinterpret_cast<
164*cdf0e10cSrcweir                             typelib_InterfaceAttributeTypeDescription const * >(
165*cdf0e10cSrcweir                                 member)->
166*cdf0e10cSrcweir                         pAttributeTypeRef),
167*cdf0e10cSrcweir                     arguments[0]));
168*cdf0e10cSrcweir         }
169*cdf0e10cSrcweir         break;
170*cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE_METHOD:
171*cdf0e10cSrcweir         {
172*cdf0e10cSrcweir             typelib_InterfaceMethodTypeDescription const * mtd =
173*cdf0e10cSrcweir                 reinterpret_cast<
174*cdf0e10cSrcweir                     typelib_InterfaceMethodTypeDescription const * >(member);
175*cdf0e10cSrcweir             for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
176*cdf0e10cSrcweir                 if (mtd->pParams[i].bIn) {
177*cdf0e10cSrcweir                     inArgs.push_back(
178*cdf0e10cSrcweir                         BinaryAny(
179*cdf0e10cSrcweir                             css::uno::TypeDescription(mtd->pParams[i].pTypeRef),
180*cdf0e10cSrcweir                             arguments[i]));
181*cdf0e10cSrcweir                 }
182*cdf0e10cSrcweir             }
183*cdf0e10cSrcweir             break;
184*cdf0e10cSrcweir         }
185*cdf0e10cSrcweir     default:
186*cdf0e10cSrcweir         OSL_ASSERT(false); // this cannot happen
187*cdf0e10cSrcweir         break;
188*cdf0e10cSrcweir     }
189*cdf0e10cSrcweir     BinaryAny ret;
190*cdf0e10cSrcweir     std::vector< BinaryAny > outArgs;
191*cdf0e10cSrcweir     if (bridge_->makeCall(
192*cdf0e10cSrcweir             oid_,
193*cdf0e10cSrcweir             css::uno::TypeDescription(
194*cdf0e10cSrcweir                 const_cast< typelib_TypeDescription * >(member)),
195*cdf0e10cSrcweir             setter, inArgs, &ret, &outArgs))
196*cdf0e10cSrcweir     {
197*cdf0e10cSrcweir         OSL_ASSERT(
198*cdf0e10cSrcweir             ret.getType().get()->eTypeClass == typelib_TypeClass_EXCEPTION);
199*cdf0e10cSrcweir         uno_any_construct(
200*cdf0e10cSrcweir             *exception, ret.getValue(ret.getType()), ret.getType().get(), 0);
201*cdf0e10cSrcweir     } else {
202*cdf0e10cSrcweir         switch (member->eTypeClass) {
203*cdf0e10cSrcweir         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
204*cdf0e10cSrcweir             if (!setter) {
205*cdf0e10cSrcweir                 css::uno::TypeDescription t(
206*cdf0e10cSrcweir                     reinterpret_cast<
207*cdf0e10cSrcweir                         typelib_InterfaceAttributeTypeDescription const * >(
208*cdf0e10cSrcweir                             member)->
209*cdf0e10cSrcweir                     pAttributeTypeRef);
210*cdf0e10cSrcweir                 uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
211*cdf0e10cSrcweir             }
212*cdf0e10cSrcweir             break;
213*cdf0e10cSrcweir         case typelib_TypeClass_INTERFACE_METHOD:
214*cdf0e10cSrcweir             {
215*cdf0e10cSrcweir                 typelib_InterfaceMethodTypeDescription const * mtd =
216*cdf0e10cSrcweir                     reinterpret_cast<
217*cdf0e10cSrcweir                         typelib_InterfaceMethodTypeDescription const * >(
218*cdf0e10cSrcweir                             member);
219*cdf0e10cSrcweir                 css::uno::TypeDescription t(mtd->pReturnTypeRef);
220*cdf0e10cSrcweir                 if (t.get()->eTypeClass != typelib_TypeClass_VOID) {
221*cdf0e10cSrcweir                     uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
222*cdf0e10cSrcweir                 }
223*cdf0e10cSrcweir                 std::vector< BinaryAny >::iterator i(outArgs.begin());
224*cdf0e10cSrcweir                 for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
225*cdf0e10cSrcweir                     if (mtd->pParams[j].bOut) {
226*cdf0e10cSrcweir                         css::uno::TypeDescription pt(mtd->pParams[j].pTypeRef);
227*cdf0e10cSrcweir                         if (mtd->pParams[j].bIn) {
228*cdf0e10cSrcweir                             uno_assignData(
229*cdf0e10cSrcweir                                 arguments[j], pt.get(), i++->getValue(pt),
230*cdf0e10cSrcweir                                 pt.get(), 0, 0, 0);
231*cdf0e10cSrcweir                         } else {
232*cdf0e10cSrcweir                             uno_copyData(
233*cdf0e10cSrcweir                                 arguments[j], i++->getValue(pt), pt.get(), 0);
234*cdf0e10cSrcweir                         }
235*cdf0e10cSrcweir                     }
236*cdf0e10cSrcweir                 }
237*cdf0e10cSrcweir                 OSL_ASSERT(i == outArgs.end());
238*cdf0e10cSrcweir                 break;
239*cdf0e10cSrcweir             }
240*cdf0e10cSrcweir         default:
241*cdf0e10cSrcweir             OSL_ASSERT(false); // this cannot happen
242*cdf0e10cSrcweir             break;
243*cdf0e10cSrcweir         }
244*cdf0e10cSrcweir         *exception = 0;
245*cdf0e10cSrcweir     }
246*cdf0e10cSrcweir }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir bool Proxy::isProxy(
249*cdf0e10cSrcweir     rtl::Reference< Bridge > const & bridge, rtl::OUString * oid) const
250*cdf0e10cSrcweir {
251*cdf0e10cSrcweir     OSL_ASSERT(oid != 0);
252*cdf0e10cSrcweir     if (bridge == bridge_) {
253*cdf0e10cSrcweir         *oid = oid_;
254*cdf0e10cSrcweir         return true;
255*cdf0e10cSrcweir     } else {
256*cdf0e10cSrcweir         return false;
257*cdf0e10cSrcweir     }
258*cdf0e10cSrcweir }
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir }
261