xref: /aoo41x/main/binaryurp/source/proxy.cxx (revision 37adc4f0)
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