1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
25 #include <com/sun/star/bridge/XInstanceProvider.hpp>
26 #include <com/sun/star/container/NoSuchElementException.hpp>
27 #include <cppuhelper/exc_hlp.hxx>
28 #include <o3tl/runtimetooustring.hxx>
29 #include <rtl/byteseq.hxx>
30 #include <rtl/ref.hxx>
31 #include <rtl/ustring.hxx>
32 #include <sal/log.hxx>
33 #include <sal/types.h>
34 #include <typelib/typedescription.hxx>
35 #include <uno/dispatcher.hxx>
37 #include "binaryany.hxx"
39 #include "currentcontext.hxx"
40 #include "incomingrequest.hxx"
41 #include "specialfunctionids.hxx"
45 IncomingRequest::IncomingRequest(
46 rtl::Reference
< Bridge
> const & bridge
, rtl::ByteSequence
const & tid
,
47 OUString
const & oid
, css::uno::UnoInterfaceReference
const & object
,
48 css::uno::TypeDescription
const & type
, sal_uInt16 functionId
,
49 bool synchronous
, css::uno::TypeDescription
const & member
, bool setter
,
50 std::vector
< BinaryAny
> const & inArguments
, bool currentContextMode
,
51 css::uno::UnoInterfaceReference
const & currentContext
):
52 bridge_(bridge
), tid_(tid
), oid_(oid
), object_(object
), type_(type
),
53 functionId_(functionId
), synchronous_(synchronous
), member_(member
),
54 setter_(setter
), inArguments_(inArguments
),
55 currentContextMode_(currentContextMode
), currentContext_(currentContext
)
59 assert(member
.get()->bComplete
);
62 IncomingRequest::~IncomingRequest() {}
64 void IncomingRequest::execute() const {
66 std::vector
< BinaryAny
> outArgs
;
70 css::uno::UnoInterfaceReference oldCc
;
71 if (currentContextMode_
) {
72 oldCc
= current_context::get();
73 current_context::set(currentContext_
);
78 isExc
= !execute_throw(&ret
, &outArgs
);
79 } catch (const std::exception
& e
) {
80 throw css::uno::RuntimeException(
81 "caught C++ exception: "
82 + o3tl::runtimeToOUString(e
.what()));
84 } catch (const css::uno::RuntimeException
&) {
85 css::uno::Any
exc(cppu::getCaughtException());
86 ret
= bridge_
->mapCppToBinaryAny(exc
);
90 current_context::set(oldCc
);
92 } catch (const css::uno::RuntimeException
&) {
93 css::uno::Any
exc(cppu::getCaughtException());
94 ret
= bridge_
->mapCppToBinaryAny(exc
);
98 bridge_
->decrementActiveCalls();
100 bridge_
->getWriter()->queueReply(
101 tid_
, member_
, setter_
, isExc
, ret
, outArgs
, false);
103 } catch (const css::uno::RuntimeException
& e
) {
104 SAL_INFO("binaryurp", "caught " << e
);
105 } catch (const std::exception
& e
) {
106 SAL_INFO("binaryurp", "caught C++ exception " << e
.what());
108 bridge_
->terminate(false);
111 SAL_INFO("binaryurp", "oneway method raised exception");
113 bridge_
->decrementCalls();
117 static size_t size_t_round(size_t val
)
119 return (val
+ (sizeof(size_t)-1)) & ~(sizeof(size_t)-1);
122 bool IncomingRequest::execute_throw(
123 BinaryAny
* returnValue
, std::vector
< BinaryAny
> * outArguments
) const
125 assert(returnValue
!= nullptr);
127 returnValue
->getType().equals(
128 css::uno::TypeDescription(cppu::UnoType
<void>::get())));
129 assert(outArguments
!= nullptr);
130 assert(outArguments
->empty());
132 switch (functionId_
) {
133 case SPECIAL_FUNCTION_ID_RESERVED
:
134 assert(false); // this cannot happen
136 case SPECIAL_FUNCTION_ID_RELEASE
:
137 bridge_
->releaseStub(oid_
, type_
);
139 case SPECIAL_FUNCTION_ID_QUERY_INTERFACE
:
141 css::uno::Reference
< css::uno::XInterface
> ifc
;
142 css::uno::Reference
< css::bridge::XInstanceProvider
> prov(
143 bridge_
->getProvider());
146 ifc
= prov
->getInstance(oid_
);
147 } catch (const css::container::NoSuchElementException
& e
) {
148 SAL_INFO("binaryurp", "initial element " << oid_
<< ": " << e
);
152 css::uno::UnoInterfaceReference
unoIfc(
153 static_cast< uno_Interface
* >(
154 bridge_
->getCppToBinaryMapping().mapInterface(
156 (css::uno::TypeDescription(
159 css::uno::XInterface
> >::get()).
162 *returnValue
= BinaryAny(
163 css::uno::TypeDescription(
166 css::uno::XInterface
> >::get()),
174 assert(object_
.is());
175 css::uno::TypeDescription retType
;
176 std::vector
< std::vector
< char > > outBufs
;
177 std::vector
< void * > args
;
178 switch (member_
.get()->eTypeClass
) {
179 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
181 css::uno::TypeDescription
t(
183 typelib_InterfaceAttributeTypeDescription
* >(
187 assert(inArguments_
.size() == 1);
188 args
.push_back(inArguments_
[0].getValue(t
));
190 assert(inArguments_
.empty());
195 case typelib_TypeClass_INTERFACE_METHOD
:
197 typelib_InterfaceMethodTypeDescription
* mtd
=
199 typelib_InterfaceMethodTypeDescription
* >(
201 retType
= css::uno::TypeDescription(mtd
->pReturnTypeRef
);
202 std::vector
< BinaryAny
>::const_iterator
i(
203 inArguments_
.begin());
204 for (sal_Int32 j
= 0; j
!= mtd
->nParams
; ++j
) {
206 if (mtd
->pParams
[j
].bIn
) {
208 css::uno::TypeDescription(
209 mtd
->pParams
[j
].pTypeRef
));
211 outBufs
.emplace_back(size_t_round(
212 css::uno::TypeDescription(
213 mtd
->pParams
[j
].pTypeRef
).
215 p
= outBufs
.back().data();
218 if (mtd
->pParams
[j
].bOut
) {
219 outArguments
->push_back(BinaryAny());
222 assert(i
== inArguments_
.end());
226 assert(false); // this cannot happen
231 nSize
= size_t_round(retType
.get()->nSize
);
232 std::vector
< char > retBuf(nSize
);
234 uno_Any
* pexc
= &exc
;
235 (*object_
.get()->pDispatcher
)(
236 object_
.get(), member_
.get(), retBuf
.empty() ? nullptr : retBuf
.data(),
237 args
.empty() ? nullptr : args
.data(), &pexc
);
238 isExc
= pexc
!= nullptr;
240 *returnValue
= BinaryAny(
241 css::uno::TypeDescription(
242 cppu::UnoType
< css::uno::Any
>::get()),
244 uno_any_destruct(&exc
, nullptr);
246 if (!retBuf
.empty()) {
247 *returnValue
= BinaryAny(retType
, retBuf
.data());
248 uno_destructData(retBuf
.data(), retType
.get(), nullptr);
250 if (!outArguments
->empty()) {
252 member_
.get()->eTypeClass
==
253 typelib_TypeClass_INTERFACE_METHOD
);
254 typelib_InterfaceMethodTypeDescription
* mtd
=
256 typelib_InterfaceMethodTypeDescription
* >(
258 std::vector
< BinaryAny
>::iterator
i(outArguments
->begin());
259 std::vector
< std::vector
< char > >::iterator
j(
261 for (sal_Int32 k
= 0; k
!= mtd
->nParams
; ++k
) {
262 if (mtd
->pParams
[k
].bOut
) {
264 css::uno::TypeDescription(
265 mtd
->pParams
[k
].pTypeRef
),
268 if (!mtd
->pParams
[k
].bIn
) {
269 uno_type_destructData(
270 (j
++)->data(), mtd
->pParams
[k
].pTypeRef
, nullptr);
273 assert(i
== outArguments
->end());
274 assert(j
== outBufs
.end());
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */