1*37adc4f0SAndrew Rist /**************************************************************
2*37adc4f0SAndrew Rist *
3*37adc4f0SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*37adc4f0SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*37adc4f0SAndrew Rist * distributed with this work for additional information
6*37adc4f0SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*37adc4f0SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*37adc4f0SAndrew Rist * "License"); you may not use this file except in compliance
9*37adc4f0SAndrew Rist * with the License. You may obtain a copy of the License at
10*37adc4f0SAndrew Rist *
11*37adc4f0SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*37adc4f0SAndrew Rist *
13*37adc4f0SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*37adc4f0SAndrew Rist * software distributed under the License is distributed on an
15*37adc4f0SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*37adc4f0SAndrew Rist * KIND, either express or implied. See the License for the
17*37adc4f0SAndrew Rist * specific language governing permissions and limitations
18*37adc4f0SAndrew Rist * under the License.
19*37adc4f0SAndrew Rist *
20*37adc4f0SAndrew Rist *************************************************************/
21*37adc4f0SAndrew Rist
22*37adc4f0SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "sal/config.h"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include <exception>
27cdf0e10cSrcweir #include <vector>
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
30cdf0e10cSrcweir #include "osl/diagnose.h"
31cdf0e10cSrcweir #include "rtl/ref.hxx"
32cdf0e10cSrcweir #include "rtl/ustring.hxx"
33cdf0e10cSrcweir #include "sal/types.h"
34cdf0e10cSrcweir #include "typelib/typedescription.h"
35cdf0e10cSrcweir #include "typelib/typedescription.hxx"
36cdf0e10cSrcweir #include "uno/any2.h"
37cdf0e10cSrcweir #include "uno/dispatcher.h"
38cdf0e10cSrcweir #include "uno/dispatcher.hxx"
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include "binaryany.hxx"
41cdf0e10cSrcweir #include "bridge.hxx"
42cdf0e10cSrcweir #include "proxy.hxx"
43cdf0e10cSrcweir
44cdf0e10cSrcweir namespace binaryurp {
45cdf0e10cSrcweir
46cdf0e10cSrcweir namespace {
47cdf0e10cSrcweir
48cdf0e10cSrcweir namespace css = com::sun::star;
49cdf0e10cSrcweir
proxy_acquireInterface(uno_Interface * pInterface)50cdf0e10cSrcweir extern "C" void SAL_CALL proxy_acquireInterface(uno_Interface * pInterface) {
51cdf0e10cSrcweir OSL_ASSERT(pInterface != 0);
52cdf0e10cSrcweir static_cast< Proxy * >(pInterface)->do_acquire();
53cdf0e10cSrcweir }
54cdf0e10cSrcweir
proxy_releaseInterface(uno_Interface * pInterface)55cdf0e10cSrcweir extern "C" void SAL_CALL proxy_releaseInterface(uno_Interface * pInterface) {
56cdf0e10cSrcweir OSL_ASSERT(pInterface != 0);
57cdf0e10cSrcweir static_cast< Proxy * >(pInterface)->do_release();
58cdf0e10cSrcweir }
59cdf0e10cSrcweir
proxy_dispatchInterface(uno_Interface * pUnoI,typelib_TypeDescription const * pMemberType,void * pReturn,void ** pArgs,uno_Any ** ppException)60cdf0e10cSrcweir extern "C" void SAL_CALL proxy_dispatchInterface(
61cdf0e10cSrcweir uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
62cdf0e10cSrcweir void * pReturn, void ** pArgs, uno_Any ** ppException)
63cdf0e10cSrcweir {
64cdf0e10cSrcweir OSL_ASSERT(pUnoI != 0);
65cdf0e10cSrcweir static_cast< Proxy * >(pUnoI)->do_dispatch(
66cdf0e10cSrcweir pMemberType, pReturn, pArgs, ppException);
67cdf0e10cSrcweir }
68cdf0e10cSrcweir
69cdf0e10cSrcweir }
70cdf0e10cSrcweir
Proxy(rtl::Reference<Bridge> const & bridge,rtl::OUString const & oid,css::uno::TypeDescription const & type)71cdf0e10cSrcweir Proxy::Proxy(
72cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, rtl::OUString const & oid,
73cdf0e10cSrcweir css::uno::TypeDescription const & type):
74cdf0e10cSrcweir bridge_(bridge), oid_(oid), type_(type), references_(1)
75cdf0e10cSrcweir {
76cdf0e10cSrcweir OSL_ASSERT(bridge.is());
77cdf0e10cSrcweir acquire = &proxy_acquireInterface;
78cdf0e10cSrcweir release = &proxy_releaseInterface;
79cdf0e10cSrcweir pDispatcher = &proxy_dispatchInterface;
80cdf0e10cSrcweir }
81cdf0e10cSrcweir
getOid() const82cdf0e10cSrcweir rtl::OUString Proxy::getOid() const {
83cdf0e10cSrcweir return oid_;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir
getType() const86cdf0e10cSrcweir css::uno::TypeDescription Proxy::getType() const {
87cdf0e10cSrcweir return type_;
88cdf0e10cSrcweir }
89cdf0e10cSrcweir
do_acquire()90cdf0e10cSrcweir void Proxy::do_acquire() {
91cdf0e10cSrcweir if (osl_incrementInterlockedCount(&references_) == 1) {
92cdf0e10cSrcweir bridge_->resurrectProxy(*this);
93cdf0e10cSrcweir }
94cdf0e10cSrcweir }
95cdf0e10cSrcweir
do_release()96cdf0e10cSrcweir void Proxy::do_release() {
97cdf0e10cSrcweir if (osl_decrementInterlockedCount(&references_) == 0) {
98cdf0e10cSrcweir bridge_->revokeProxy(*this);
99cdf0e10cSrcweir }
100cdf0e10cSrcweir }
101cdf0e10cSrcweir
do_free()102cdf0e10cSrcweir void Proxy::do_free() {
103cdf0e10cSrcweir bridge_->freeProxy(*this);
104cdf0e10cSrcweir delete this;
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
do_dispatch(typelib_TypeDescription const * member,void * returnValue,void ** arguments,uno_Any ** exception) const107cdf0e10cSrcweir void Proxy::do_dispatch(
108cdf0e10cSrcweir typelib_TypeDescription const * member, void * returnValue,
109cdf0e10cSrcweir void ** arguments, uno_Any ** exception) const
110cdf0e10cSrcweir {
111cdf0e10cSrcweir try {
112cdf0e10cSrcweir try {
113cdf0e10cSrcweir do_dispatch_throw(member, returnValue, arguments, exception);
114cdf0e10cSrcweir } catch (std::exception & e) {
115cdf0e10cSrcweir throw css::uno::RuntimeException(
116cdf0e10cSrcweir (rtl::OUString(
117cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
118cdf0e10cSrcweir rtl::OStringToOUString(
119cdf0e10cSrcweir rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)),
120cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
121cdf0e10cSrcweir // best-effort string conversion
122cdf0e10cSrcweir }
123cdf0e10cSrcweir } catch (css::uno::RuntimeException &) {
124cdf0e10cSrcweir css::uno::Any exc(cppu::getCaughtException());
125cdf0e10cSrcweir uno_copyAndConvertData(
126cdf0e10cSrcweir *exception, &exc,
127cdf0e10cSrcweir (css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()).
128cdf0e10cSrcweir get()),
129cdf0e10cSrcweir bridge_->getCppToBinaryMapping().get());
130cdf0e10cSrcweir }
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
isProxy(rtl::Reference<Bridge> const & bridge,css::uno::UnoInterfaceReference const & object,rtl::OUString * oid)133cdf0e10cSrcweir bool Proxy::isProxy(
134cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge,
135cdf0e10cSrcweir css::uno::UnoInterfaceReference const & object, rtl::OUString * oid)
136cdf0e10cSrcweir {
137cdf0e10cSrcweir OSL_ASSERT(object.is());
138cdf0e10cSrcweir return object.m_pUnoI->acquire == &proxy_acquireInterface &&
139cdf0e10cSrcweir static_cast< Proxy * >(object.m_pUnoI)->isProxy(bridge, oid);
140cdf0e10cSrcweir }
141cdf0e10cSrcweir
~Proxy()142cdf0e10cSrcweir Proxy::~Proxy() {}
143cdf0e10cSrcweir
do_dispatch_throw(typelib_TypeDescription const * member,void * returnValue,void ** arguments,uno_Any ** exception) const144cdf0e10cSrcweir void Proxy::do_dispatch_throw(
145cdf0e10cSrcweir typelib_TypeDescription const * member, void * returnValue,
146cdf0e10cSrcweir void ** arguments, uno_Any ** exception) const
147cdf0e10cSrcweir {
148cdf0e10cSrcweir //TODO: Optimize queryInterface:
149cdf0e10cSrcweir OSL_ASSERT(member != 0);
150cdf0e10cSrcweir bool setter = false;
151cdf0e10cSrcweir std::vector< BinaryAny > inArgs;
152cdf0e10cSrcweir switch (member->eTypeClass) {
153cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE:
154cdf0e10cSrcweir setter = returnValue == 0;
155cdf0e10cSrcweir if (setter) {
156cdf0e10cSrcweir inArgs.push_back(
157cdf0e10cSrcweir BinaryAny(
158cdf0e10cSrcweir css::uno::TypeDescription(
159cdf0e10cSrcweir reinterpret_cast<
160cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >(
161cdf0e10cSrcweir member)->
162cdf0e10cSrcweir pAttributeTypeRef),
163cdf0e10cSrcweir arguments[0]));
164cdf0e10cSrcweir }
165cdf0e10cSrcweir break;
166cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD:
167cdf0e10cSrcweir {
168cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * mtd =
169cdf0e10cSrcweir reinterpret_cast<
170cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >(member);
171cdf0e10cSrcweir for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
172cdf0e10cSrcweir if (mtd->pParams[i].bIn) {
173cdf0e10cSrcweir inArgs.push_back(
174cdf0e10cSrcweir BinaryAny(
175cdf0e10cSrcweir css::uno::TypeDescription(mtd->pParams[i].pTypeRef),
176cdf0e10cSrcweir arguments[i]));
177cdf0e10cSrcweir }
178cdf0e10cSrcweir }
179cdf0e10cSrcweir break;
180cdf0e10cSrcweir }
181cdf0e10cSrcweir default:
182cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen
183cdf0e10cSrcweir break;
184cdf0e10cSrcweir }
185cdf0e10cSrcweir BinaryAny ret;
186cdf0e10cSrcweir std::vector< BinaryAny > outArgs;
187cdf0e10cSrcweir if (bridge_->makeCall(
188cdf0e10cSrcweir oid_,
189cdf0e10cSrcweir css::uno::TypeDescription(
190cdf0e10cSrcweir const_cast< typelib_TypeDescription * >(member)),
191cdf0e10cSrcweir setter, inArgs, &ret, &outArgs))
192cdf0e10cSrcweir {
193cdf0e10cSrcweir OSL_ASSERT(
194cdf0e10cSrcweir ret.getType().get()->eTypeClass == typelib_TypeClass_EXCEPTION);
195cdf0e10cSrcweir uno_any_construct(
196cdf0e10cSrcweir *exception, ret.getValue(ret.getType()), ret.getType().get(), 0);
197cdf0e10cSrcweir } else {
198cdf0e10cSrcweir switch (member->eTypeClass) {
199cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE:
200cdf0e10cSrcweir if (!setter) {
201cdf0e10cSrcweir css::uno::TypeDescription t(
202cdf0e10cSrcweir reinterpret_cast<
203cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >(
204cdf0e10cSrcweir member)->
205cdf0e10cSrcweir pAttributeTypeRef);
206cdf0e10cSrcweir uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
207cdf0e10cSrcweir }
208cdf0e10cSrcweir break;
209cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD:
210cdf0e10cSrcweir {
211cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * mtd =
212cdf0e10cSrcweir reinterpret_cast<
213cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >(
214cdf0e10cSrcweir member);
215cdf0e10cSrcweir css::uno::TypeDescription t(mtd->pReturnTypeRef);
216cdf0e10cSrcweir if (t.get()->eTypeClass != typelib_TypeClass_VOID) {
217cdf0e10cSrcweir uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
218cdf0e10cSrcweir }
219cdf0e10cSrcweir std::vector< BinaryAny >::iterator i(outArgs.begin());
220cdf0e10cSrcweir for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
221cdf0e10cSrcweir if (mtd->pParams[j].bOut) {
222cdf0e10cSrcweir css::uno::TypeDescription pt(mtd->pParams[j].pTypeRef);
223cdf0e10cSrcweir if (mtd->pParams[j].bIn) {
224cdf0e10cSrcweir uno_assignData(
225cdf0e10cSrcweir arguments[j], pt.get(), i++->getValue(pt),
226cdf0e10cSrcweir pt.get(), 0, 0, 0);
227cdf0e10cSrcweir } else {
228cdf0e10cSrcweir uno_copyData(
229cdf0e10cSrcweir arguments[j], i++->getValue(pt), pt.get(), 0);
230cdf0e10cSrcweir }
231cdf0e10cSrcweir }
232cdf0e10cSrcweir }
233cdf0e10cSrcweir OSL_ASSERT(i == outArgs.end());
234cdf0e10cSrcweir break;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir default:
237cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen
238cdf0e10cSrcweir break;
239cdf0e10cSrcweir }
240cdf0e10cSrcweir *exception = 0;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir
isProxy(rtl::Reference<Bridge> const & bridge,rtl::OUString * oid) const244cdf0e10cSrcweir bool Proxy::isProxy(
245cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, rtl::OUString * oid) const
246cdf0e10cSrcweir {
247cdf0e10cSrcweir OSL_ASSERT(oid != 0);
248cdf0e10cSrcweir if (bridge == bridge_) {
249cdf0e10cSrcweir *oid = oid_;
250cdf0e10cSrcweir return true;
251cdf0e10cSrcweir } else {
252cdf0e10cSrcweir return false;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir }
255cdf0e10cSrcweir
256cdf0e10cSrcweir }
257