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 "boost/noncopyable.hpp"
26 #include "com/sun/star/bridge/XInstanceProvider.hpp"
27 #include "cppuhelper/exc_hlp.hxx"
28 #include "rtl/byteseq.hxx"
29 #include "rtl/ref.hxx"
30 #include "rtl/ustring.hxx"
31 #include "sal/types.h"
32 #include "typelib/typedescription.hxx"
33 #include "uno/dispatcher.hxx"
35 #include "binaryany.hxx"
37 #include "currentcontext.hxx"
38 #include "incomingrequest.hxx"
39 #include "specialfunctionids.hxx"
43 IncomingRequest::IncomingRequest(
44 rtl::Reference
< Bridge
> const & bridge
, rtl::ByteSequence
const & tid
,
45 OUString
const & oid
, css::uno::UnoInterfaceReference
const & object
,
46 css::uno::TypeDescription
const & type
, sal_uInt16 functionId
,
47 bool synchronous
, css::uno::TypeDescription
const & member
, bool setter
,
48 std::vector
< BinaryAny
> const & inArguments
, bool currentContextMode
,
49 css::uno::UnoInterfaceReference
const & currentContext
):
50 bridge_(bridge
), tid_(tid
), oid_(oid
), object_(object
), type_(type
),
51 functionId_(functionId
), synchronous_(synchronous
), member_(member
),
52 setter_(setter
), inArguments_(inArguments
),
53 currentContextMode_(currentContextMode
), currentContext_(currentContext
)
55 OSL_ASSERT(bridge
.is() && member
.is() && member
.get()->bComplete
);
58 IncomingRequest::~IncomingRequest() {}
60 void IncomingRequest::execute() const {
62 std::vector
< BinaryAny
> outArgs
;
66 css::uno::UnoInterfaceReference oldCc
;
67 if (currentContextMode_
) {
68 oldCc
= current_context::get();
69 current_context::set(currentContext_
);
74 isExc
= !execute_throw(&ret
, &outArgs
);
75 } catch (const std::exception
& e
) {
76 throw css::uno::RuntimeException(
77 ("caught C++ exception: " +
79 OString(e
.what()), RTL_TEXTENCODING_ASCII_US
)),
80 css::uno::Reference
< css::uno::XInterface
>());
81 // best-effort string conversion
83 } catch (const css::uno::RuntimeException
&) {
84 css::uno::Any
exc(cppu::getCaughtException());
85 ret
= bridge_
->mapCppToBinaryAny(exc
);
89 current_context::set(oldCc
);
91 } catch (const css::uno::RuntimeException
&) {
92 css::uno::Any
exc(cppu::getCaughtException());
93 ret
= bridge_
->mapCppToBinaryAny(exc
);
97 bridge_
->decrementActiveCalls();
99 bridge_
->getWriter()->queueReply(
100 tid_
, member_
, setter_
, isExc
, ret
, outArgs
, false);
102 } catch (const css::uno::RuntimeException
& e
) {
104 "caught UNO runtime exception '%s'",
105 (OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).
107 } catch (const std::exception
& e
) {
108 OSL_TRACE("caught C++ exception '%s'", e
.what());
110 bridge_
->terminate(false);
113 OSL_TRACE("oneway method raised exception");
115 bridge_
->decrementCalls();
119 static size_t size_t_round(size_t val
)
121 return (val
+ (sizeof(size_t)-1)) & ~(sizeof(size_t)-1);
124 bool IncomingRequest::execute_throw(
125 BinaryAny
* returnValue
, std::vector
< BinaryAny
> * outArguments
) const
129 returnValue
->getType().equals(
130 css::uno::TypeDescription(
131 cppu::UnoType
< cppu::UnoVoidType
>::get())) &&
132 outArguments
!= 0 && outArguments
->empty());
134 switch (functionId_
) {
135 case SPECIAL_FUNCTION_ID_RESERVED
:
136 OSL_ASSERT(false); // this cannot happen
138 case SPECIAL_FUNCTION_ID_RELEASE
:
139 bridge_
->releaseStub(oid_
, type_
);
141 case SPECIAL_FUNCTION_ID_QUERY_INTERFACE
:
143 css::uno::Reference
< css::uno::XInterface
> ifc
;
144 css::uno::Reference
< css::bridge::XInstanceProvider
> prov(
145 bridge_
->getProvider());
148 ifc
= prov
->getInstance(oid_
);
149 } catch (const css::container::NoSuchElementException
& e
) {
151 "initial element '%s': NoSuchElementException '%s'",
152 OUStringToOString(oid_
, RTL_TEXTENCODING_UTF8
).getStr(),
153 (OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).
158 css::uno::UnoInterfaceReference
unoIfc(
159 static_cast< uno_Interface
* >(
160 bridge_
->getCppToBinaryMapping().mapInterface(
162 (css::uno::TypeDescription(
165 css::uno::XInterface
> >::get()).
168 *returnValue
= BinaryAny(
169 css::uno::TypeDescription(
172 css::uno::XInterface
> >::get()),
180 OSL_ASSERT(object_
.is());
181 css::uno::TypeDescription retType
;
182 std::list
< std::vector
< char > > outBufs
;
183 std::vector
< void * > args
;
184 switch (member_
.get()->eTypeClass
) {
185 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
187 css::uno::TypeDescription
t(
189 typelib_InterfaceAttributeTypeDescription
* >(
193 OSL_ASSERT(inArguments_
.size() == 1);
194 args
.push_back(inArguments_
[0].getValue(t
));
196 OSL_ASSERT(inArguments_
.empty());
201 case typelib_TypeClass_INTERFACE_METHOD
:
203 typelib_InterfaceMethodTypeDescription
* mtd
=
205 typelib_InterfaceMethodTypeDescription
* >(
207 retType
= css::uno::TypeDescription(mtd
->pReturnTypeRef
);
208 std::vector
< BinaryAny
>::const_iterator
i(
209 inArguments_
.begin());
210 for (sal_Int32 j
= 0; j
!= mtd
->nParams
; ++j
) {
212 if (mtd
->pParams
[j
].bIn
) {
214 css::uno::TypeDescription(
215 mtd
->pParams
[j
].pTypeRef
));
218 std::vector
< char >(size_t_round(
219 css::uno::TypeDescription(
220 mtd
->pParams
[j
].pTypeRef
).
222 p
= &outBufs
.back()[0];
225 if (mtd
->pParams
[j
].bOut
) {
226 outArguments
->push_back(BinaryAny());
229 OSL_ASSERT(i
== inArguments_
.end());
233 OSL_ASSERT(false); // this cannot happen
238 nSize
= size_t_round(retType
.get()->nSize
);
239 std::vector
< char > retBuf(nSize
);
241 uno_Any
* pexc
= &exc
;
242 (*object_
.get()->pDispatcher
)(
243 object_
.get(), member_
.get(), retBuf
.empty() ? 0 : &retBuf
[0],
244 args
.empty() ? 0 : &args
[0], &pexc
);
247 *returnValue
= BinaryAny(
248 css::uno::TypeDescription(
249 cppu::UnoType
< css::uno::Any
>::get()),
251 uno_any_destruct(&exc
, 0);
253 if (!retBuf
.empty()) {
254 *returnValue
= BinaryAny(retType
, &retBuf
[0]);
255 uno_destructData(&retBuf
[0], retType
.get(), 0);
257 if (!outArguments
->empty()) {
259 member_
.get()->eTypeClass
==
260 typelib_TypeClass_INTERFACE_METHOD
);
261 typelib_InterfaceMethodTypeDescription
* mtd
=
263 typelib_InterfaceMethodTypeDescription
* >(
265 std::vector
< BinaryAny
>::iterator
i(outArguments
->begin());
266 std::list
< std::vector
< char > >::iterator
j(
268 for (sal_Int32 k
= 0; k
!= mtd
->nParams
; ++k
) {
269 if (mtd
->pParams
[k
].bOut
) {
271 css::uno::TypeDescription(
272 mtd
->pParams
[k
].pTypeRef
),
275 if (!mtd
->pParams
[k
].bIn
) {
276 uno_type_destructData(
277 &(*j
++)[0], mtd
->pParams
[k
].pTypeRef
, 0);
280 OSL_ASSERT(i
== outArguments
->end());
281 OSL_ASSERT(j
== outBufs
.end());
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */