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 "cppuhelper/exc_hlp.hxx"
27 #include "rtl/byteseq.hxx"
28 #include "rtl/ref.hxx"
29 #include "rtl/ustring.hxx"
30 #include "sal/types.h"
31 #include "typelib/typedescription.hxx"
32 #include "uno/dispatcher.hxx"
34 #include "binaryany.hxx"
36 #include "currentcontext.hxx"
37 #include "incomingrequest.hxx"
38 #include "specialfunctionids.hxx"
42 IncomingRequest::IncomingRequest(
43 rtl::Reference
< Bridge
> const & bridge
, rtl::ByteSequence
const & tid
,
44 OUString
const & oid
, css::uno::UnoInterfaceReference
const & object
,
45 css::uno::TypeDescription
const & type
, sal_uInt16 functionId
,
46 bool synchronous
, css::uno::TypeDescription
const & member
, bool setter
,
47 std::vector
< BinaryAny
> const & inArguments
, bool currentContextMode
,
48 css::uno::UnoInterfaceReference
const & currentContext
):
49 bridge_(bridge
), tid_(tid
), oid_(oid
), object_(object
), type_(type
),
50 functionId_(functionId
), synchronous_(synchronous
), member_(member
),
51 setter_(setter
), inArguments_(inArguments
),
52 currentContextMode_(currentContextMode
), currentContext_(currentContext
)
54 OSL_ASSERT(bridge
.is() && member
.is() && member
.get()->bComplete
);
57 IncomingRequest::~IncomingRequest() {}
59 void IncomingRequest::execute() const {
61 std::vector
< BinaryAny
> outArgs
;
65 css::uno::UnoInterfaceReference oldCc
;
66 if (currentContextMode_
) {
67 oldCc
= current_context::get();
68 current_context::set(currentContext_
);
73 isExc
= !execute_throw(&ret
, &outArgs
);
74 } catch (const std::exception
& e
) {
75 throw css::uno::RuntimeException(
76 "caught C++ exception: " +
78 OString(e
.what()), RTL_TEXTENCODING_ASCII_US
));
79 // best-effort string conversion
81 } catch (const css::uno::RuntimeException
&) {
82 css::uno::Any
exc(cppu::getCaughtException());
83 ret
= bridge_
->mapCppToBinaryAny(exc
);
87 current_context::set(oldCc
);
89 } catch (const css::uno::RuntimeException
&) {
90 css::uno::Any
exc(cppu::getCaughtException());
91 ret
= bridge_
->mapCppToBinaryAny(exc
);
95 bridge_
->decrementActiveCalls();
97 bridge_
->getWriter()->queueReply(
98 tid_
, member_
, setter_
, isExc
, ret
, outArgs
, false);
100 } catch (const css::uno::RuntimeException
& e
) {
102 "caught UNO runtime exception '%s'",
103 (OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).
105 } catch (const std::exception
& e
) {
106 OSL_TRACE("caught C++ exception '%s'", e
.what());
108 bridge_
->terminate(false);
111 OSL_TRACE("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
127 returnValue
->getType().equals(
128 css::uno::TypeDescription(cppu::UnoType
<void>::get())) &&
129 outArguments
!= 0 && outArguments
->empty());
131 switch (functionId_
) {
132 case SPECIAL_FUNCTION_ID_RESERVED
:
133 OSL_ASSERT(false); // this cannot happen
135 case SPECIAL_FUNCTION_ID_RELEASE
:
136 bridge_
->releaseStub(oid_
, type_
);
138 case SPECIAL_FUNCTION_ID_QUERY_INTERFACE
:
140 css::uno::Reference
< css::uno::XInterface
> ifc
;
141 css::uno::Reference
< css::bridge::XInstanceProvider
> prov(
142 bridge_
->getProvider());
145 ifc
= prov
->getInstance(oid_
);
146 } catch (const css::container::NoSuchElementException
& e
) {
148 "initial element '%s': NoSuchElementException '%s'",
149 OUStringToOString(oid_
, RTL_TEXTENCODING_UTF8
).getStr(),
150 (OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).
155 css::uno::UnoInterfaceReference
unoIfc(
156 static_cast< uno_Interface
* >(
157 bridge_
->getCppToBinaryMapping().mapInterface(
159 (css::uno::TypeDescription(
162 css::uno::XInterface
> >::get()).
165 *returnValue
= BinaryAny(
166 css::uno::TypeDescription(
169 css::uno::XInterface
> >::get()),
177 OSL_ASSERT(object_
.is());
178 css::uno::TypeDescription retType
;
179 std::list
< std::vector
< char > > outBufs
;
180 std::vector
< void * > args
;
181 switch (member_
.get()->eTypeClass
) {
182 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
184 css::uno::TypeDescription
t(
186 typelib_InterfaceAttributeTypeDescription
* >(
190 OSL_ASSERT(inArguments_
.size() == 1);
191 args
.push_back(inArguments_
[0].getValue(t
));
193 OSL_ASSERT(inArguments_
.empty());
198 case typelib_TypeClass_INTERFACE_METHOD
:
200 typelib_InterfaceMethodTypeDescription
* mtd
=
202 typelib_InterfaceMethodTypeDescription
* >(
204 retType
= css::uno::TypeDescription(mtd
->pReturnTypeRef
);
205 std::vector
< BinaryAny
>::const_iterator
i(
206 inArguments_
.begin());
207 for (sal_Int32 j
= 0; j
!= mtd
->nParams
; ++j
) {
209 if (mtd
->pParams
[j
].bIn
) {
211 css::uno::TypeDescription(
212 mtd
->pParams
[j
].pTypeRef
));
215 std::vector
< char >(size_t_round(
216 css::uno::TypeDescription(
217 mtd
->pParams
[j
].pTypeRef
).
219 p
= &outBufs
.back()[0];
222 if (mtd
->pParams
[j
].bOut
) {
223 outArguments
->push_back(BinaryAny());
226 OSL_ASSERT(i
== inArguments_
.end());
230 OSL_ASSERT(false); // this cannot happen
235 nSize
= size_t_round(retType
.get()->nSize
);
236 std::vector
< char > retBuf(nSize
);
238 uno_Any
* pexc
= &exc
;
239 (*object_
.get()->pDispatcher
)(
240 object_
.get(), member_
.get(), retBuf
.empty() ? 0 : &retBuf
[0],
241 args
.empty() ? 0 : &args
[0], &pexc
);
244 *returnValue
= BinaryAny(
245 css::uno::TypeDescription(
246 cppu::UnoType
< css::uno::Any
>::get()),
248 uno_any_destruct(&exc
, 0);
250 if (!retBuf
.empty()) {
251 *returnValue
= BinaryAny(retType
, &retBuf
[0]);
252 uno_destructData(&retBuf
[0], retType
.get(), 0);
254 if (!outArguments
->empty()) {
256 member_
.get()->eTypeClass
==
257 typelib_TypeClass_INTERFACE_METHOD
);
258 typelib_InterfaceMethodTypeDescription
* mtd
=
260 typelib_InterfaceMethodTypeDescription
* >(
262 std::vector
< BinaryAny
>::iterator
i(outArguments
->begin());
263 std::list
< std::vector
< char > >::iterator
j(
265 for (sal_Int32 k
= 0; k
!= mtd
->nParams
; ++k
) {
266 if (mtd
->pParams
[k
].bOut
) {
268 css::uno::TypeDescription(
269 mtd
->pParams
[k
].pTypeRef
),
272 if (!mtd
->pParams
[k
].bIn
) {
273 uno_type_destructData(
274 &(*j
++)[0], mtd
->pParams
[k
].pTypeRef
, 0);
277 OSL_ASSERT(i
== outArguments
->end());
278 OSL_ASSERT(j
== outBufs
.end());
289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */