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>
26 #include <com/sun/star/bridge/XInstanceProvider.hpp>
27 #include <com/sun/star/container/NoSuchElementException.hpp>
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <o3tl/runtimetooustring.hxx>
30 #include <rtl/byteseq.hxx>
31 #include <rtl/ref.hxx>
32 #include <rtl/ustring.hxx>
33 #include <sal/log.hxx>
34 #include <sal/types.h>
35 #include <typelib/typedescription.hxx>
36 #include <uno/dispatcher.hxx>
38 #include "binaryany.hxx"
40 #include "currentcontext.hxx"
41 #include "incomingrequest.hxx"
42 #include "specialfunctionids.hxx"
46 IncomingRequest::IncomingRequest(
47 rtl::Reference
< Bridge
> const & bridge
, rtl::ByteSequence
const & tid
,
48 OUString
const & oid
, css::uno::UnoInterfaceReference
const & object
,
49 css::uno::TypeDescription
const & type
, sal_uInt16 functionId
,
50 bool synchronous
, css::uno::TypeDescription
const & member
, bool setter
,
51 std::vector
< BinaryAny
> const & inArguments
, bool currentContextMode
,
52 css::uno::UnoInterfaceReference
const & currentContext
):
53 bridge_(bridge
), tid_(tid
), oid_(oid
), object_(object
), type_(type
),
54 functionId_(functionId
), synchronous_(synchronous
), member_(member
),
55 setter_(setter
), inArguments_(inArguments
),
56 currentContextMode_(currentContextMode
), currentContext_(currentContext
)
60 assert(member
.get()->bComplete
);
63 IncomingRequest::~IncomingRequest() {}
65 void IncomingRequest::execute() const {
67 std::vector
< BinaryAny
> outArgs
;
71 css::uno::UnoInterfaceReference oldCc
;
72 if (currentContextMode_
) {
73 oldCc
= current_context::get();
74 current_context::set(currentContext_
);
79 isExc
= !execute_throw(&ret
, &outArgs
);
80 } catch (const std::exception
& e
) {
81 throw css::uno::RuntimeException(
82 "caught C++ exception: "
83 + o3tl::runtimeToOUString(e
.what()));
85 } catch (const css::uno::RuntimeException
&) {
86 css::uno::Any
exc(cppu::getCaughtException());
87 ret
= bridge_
->mapCppToBinaryAny(exc
);
91 current_context::set(oldCc
);
93 } catch (const css::uno::RuntimeException
&) {
94 css::uno::Any
exc(cppu::getCaughtException());
95 ret
= bridge_
->mapCppToBinaryAny(exc
);
99 bridge_
->decrementActiveCalls();
101 bridge_
->getWriter()->queueReply(
102 tid_
, member_
, setter_
, isExc
, ret
, outArgs
, false);
104 } catch (const css::uno::RuntimeException
& e
) {
105 SAL_INFO("binaryurp", "caught " << e
);
106 } catch (const std::exception
& e
) {
107 SAL_INFO("binaryurp", "caught C++ exception " << e
.what());
109 bridge_
->terminate(false);
112 SAL_INFO("binaryurp", "oneway method raised exception");
114 bridge_
->decrementCalls();
118 static size_t size_t_round(size_t val
)
120 return (val
+ (sizeof(size_t)-1)) & ~(sizeof(size_t)-1);
123 bool IncomingRequest::execute_throw(
124 BinaryAny
* returnValue
, std::vector
< BinaryAny
> * outArguments
) const
126 assert(returnValue
!= nullptr);
128 returnValue
->getType().equals(
129 css::uno::TypeDescription(cppu::UnoType
<void>::get())));
130 assert(outArguments
!= nullptr);
131 assert(outArguments
->empty());
133 switch (functionId_
) {
134 case SPECIAL_FUNCTION_ID_RESERVED
:
135 assert(false); // this cannot happen
137 case SPECIAL_FUNCTION_ID_RELEASE
:
138 bridge_
->releaseStub(oid_
, type_
);
140 case SPECIAL_FUNCTION_ID_QUERY_INTERFACE
:
142 css::uno::Reference
< css::uno::XInterface
> ifc
;
143 css::uno::Reference
< css::bridge::XInstanceProvider
> prov(
144 bridge_
->getProvider());
147 ifc
= prov
->getInstance(oid_
);
148 } catch (const css::container::NoSuchElementException
& e
) {
149 SAL_INFO("binaryurp", "initial element " << oid_
<< ": " << e
);
153 css::uno::UnoInterfaceReference
unoIfc(
154 static_cast< uno_Interface
* >(
155 bridge_
->getCppToBinaryMapping().mapInterface(
157 (css::uno::TypeDescription(
160 css::uno::XInterface
> >::get()).
163 *returnValue
= BinaryAny(
164 css::uno::TypeDescription(
167 css::uno::XInterface
> >::get()),
175 assert(object_
.is());
176 css::uno::TypeDescription retType
;
177 std::vector
< std::vector
< char > > outBufs
;
178 std::vector
< void * > args
;
179 switch (member_
.get()->eTypeClass
) {
180 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
182 css::uno::TypeDescription
t(
184 typelib_InterfaceAttributeTypeDescription
* >(
188 assert(inArguments_
.size() == 1);
189 args
.push_back(inArguments_
[0].getValue(t
));
191 assert(inArguments_
.empty());
196 case typelib_TypeClass_INTERFACE_METHOD
:
198 typelib_InterfaceMethodTypeDescription
* mtd
=
200 typelib_InterfaceMethodTypeDescription
* >(
202 retType
= css::uno::TypeDescription(mtd
->pReturnTypeRef
);
203 std::vector
< BinaryAny
>::const_iterator
i(
204 inArguments_
.begin());
205 for (sal_Int32 j
= 0; j
!= mtd
->nParams
; ++j
) {
207 if (mtd
->pParams
[j
].bIn
) {
209 css::uno::TypeDescription(
210 mtd
->pParams
[j
].pTypeRef
));
212 outBufs
.emplace_back(size_t_round(
213 css::uno::TypeDescription(
214 mtd
->pParams
[j
].pTypeRef
).
216 p
= &outBufs
.back()[0];
219 if (mtd
->pParams
[j
].bOut
) {
220 outArguments
->push_back(BinaryAny());
223 assert(i
== inArguments_
.end());
227 assert(false); // this cannot happen
232 nSize
= size_t_round(retType
.get()->nSize
);
233 std::vector
< char > retBuf(nSize
);
235 uno_Any
* pexc
= &exc
;
236 (*object_
.get()->pDispatcher
)(
237 object_
.get(), member_
.get(), retBuf
.empty() ? nullptr : &retBuf
[0],
238 args
.empty() ? nullptr : &args
[0], &pexc
);
239 isExc
= pexc
!= nullptr;
241 *returnValue
= BinaryAny(
242 css::uno::TypeDescription(
243 cppu::UnoType
< css::uno::Any
>::get()),
245 uno_any_destruct(&exc
, nullptr);
247 if (!retBuf
.empty()) {
248 *returnValue
= BinaryAny(retType
, &retBuf
[0]);
249 uno_destructData(&retBuf
[0], retType
.get(), nullptr);
251 if (!outArguments
->empty()) {
253 member_
.get()->eTypeClass
==
254 typelib_TypeClass_INTERFACE_METHOD
);
255 typelib_InterfaceMethodTypeDescription
* mtd
=
257 typelib_InterfaceMethodTypeDescription
* >(
259 std::vector
< BinaryAny
>::iterator
i(outArguments
->begin());
260 std::vector
< std::vector
< char > >::iterator
j(
262 for (sal_Int32 k
= 0; k
!= mtd
->nParams
; ++k
) {
263 if (mtd
->pParams
[k
].bOut
) {
265 css::uno::TypeDescription(
266 mtd
->pParams
[k
].pTypeRef
),
269 if (!mtd
->pParams
[k
].bIn
) {
270 uno_type_destructData(
271 &(*j
++)[0], mtd
->pParams
[k
].pTypeRef
, nullptr);
274 assert(i
== outArguments
->end());
275 assert(j
== outBufs
.end());
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */