1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2011 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "sal/config.h"
34 #include "boost/noncopyable.hpp"
35 #include "com/sun/star/bridge/XInstanceProvider.hpp"
36 #include "cppuhelper/exc_hlp.hxx"
37 #include "rtl/byteseq.hxx"
38 #include "rtl/ref.hxx"
39 #include "rtl/ustring.hxx"
40 #include "sal/types.h"
41 #include "typelib/typedescription.hxx"
42 #include "uno/dispatcher.hxx"
44 #include "binaryany.hxx"
46 #include "currentcontext.hxx"
47 #include "incomingrequest.hxx"
48 #include "specialfunctionids.hxx"
54 namespace css
= com::sun::star
;
58 IncomingRequest::IncomingRequest(
59 rtl::Reference
< Bridge
> const & bridge
, rtl::ByteSequence
const & tid
,
60 rtl::OUString
const & oid
, css::uno::UnoInterfaceReference
const & object
,
61 css::uno::TypeDescription
const & type
, sal_uInt16 functionId
,
62 bool synchronous
, css::uno::TypeDescription
const & member
, bool setter
,
63 std::vector
< BinaryAny
> const & inArguments
, bool currentContextMode
,
64 css::uno::UnoInterfaceReference
const & currentContext
):
65 bridge_(bridge
), tid_(tid
), oid_(oid
), object_(object
), type_(type
),
66 functionId_(functionId
), synchronous_(synchronous
), member_(member
),
67 setter_(setter
), inArguments_(inArguments
),
68 currentContextMode_(currentContextMode
), currentContext_(currentContext
)
70 OSL_ASSERT(bridge
.is() && member
.is() && member
.get()->bComplete
);
73 IncomingRequest::~IncomingRequest() {}
75 void IncomingRequest::execute() const {
77 std::vector
< BinaryAny
> outArgs
;
81 css::uno::UnoInterfaceReference oldCc
;
82 if (currentContextMode_
) {
83 oldCc
= current_context::get();
84 current_context::set(currentContext_
);
89 isExc
= !execute_throw(&ret
, &outArgs
);
90 } catch (std::exception
& e
) {
91 throw css::uno::RuntimeException(
93 RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
94 rtl::OStringToOUString(
95 rtl::OString(e
.what()), RTL_TEXTENCODING_ASCII_US
)),
96 css::uno::Reference
< css::uno::XInterface
>());
97 // best-effort string conversion
99 } catch (css::uno::RuntimeException
&) {
100 css::uno::Any
exc(cppu::getCaughtException());
101 ret
= bridge_
->mapCppToBinaryAny(exc
);
105 current_context::set(oldCc
);
107 } catch (css::uno::RuntimeException
&) {
108 css::uno::Any
exc(cppu::getCaughtException());
109 ret
= bridge_
->mapCppToBinaryAny(exc
);
113 bridge_
->decrementActiveCalls();
115 bridge_
->getWriter()->queueReply(
116 tid_
, member_
, setter_
, isExc
, ret
, outArgs
, false);
118 } catch (css::uno::RuntimeException
& e
) {
120 OSL_LOG_PREFIX
"caught UNO runtime exception '%s'",
121 (rtl::OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).
123 } catch (std::exception
& e
) {
124 OSL_TRACE(OSL_LOG_PREFIX
"caught C++ exception '%s'", e
.what());
126 bridge_
->terminate();
129 OSL_TRACE(OSL_LOG_PREFIX
"oneway method raised exception");
131 bridge_
->decrementCalls();
135 static size_t size_t_round(size_t val
)
137 return (val
+ (sizeof(size_t)-1)) & ~(sizeof(size_t)-1);
140 bool IncomingRequest::execute_throw(
141 BinaryAny
* returnValue
, std::vector
< BinaryAny
> * outArguments
) const
145 returnValue
->getType().equals(
146 css::uno::TypeDescription(
147 cppu::UnoType
< cppu::UnoVoidType
>::get())) &&
148 outArguments
!= 0 && outArguments
->empty());
150 switch (functionId_
) {
151 case SPECIAL_FUNCTION_ID_RESERVED
:
152 OSL_ASSERT(false); // this cannot happen
154 case SPECIAL_FUNCTION_ID_RELEASE
:
155 bridge_
->releaseStub(oid_
, type_
);
157 case SPECIAL_FUNCTION_ID_QUERY_INTERFACE
:
159 css::uno::Reference
< css::uno::XInterface
> ifc
;
160 css::uno::Reference
< css::bridge::XInstanceProvider
> prov(
161 bridge_
->getProvider());
164 ifc
= prov
->getInstance(oid_
);
165 } catch (css::container::NoSuchElementException
& e
) {
167 (OSL_LOG_PREFIX
"initial element '%s':"
168 " NoSuchElementException '%s'"),
169 (rtl::OUStringToOString(oid_
, RTL_TEXTENCODING_UTF8
).
171 (rtl::OUStringToOString(
172 e
.Message
, RTL_TEXTENCODING_UTF8
).
177 css::uno::UnoInterfaceReference
unoIfc(
178 static_cast< uno_Interface
* >(
179 bridge_
->getCppToBinaryMapping().mapInterface(
181 (css::uno::TypeDescription(
184 css::uno::XInterface
> >::get()).
187 *returnValue
= BinaryAny(
188 css::uno::TypeDescription(
191 css::uno::XInterface
> >::get()),
199 OSL_ASSERT(object_
.is());
200 css::uno::TypeDescription retType
;
201 std::list
< std::vector
< char > > outBufs
;
202 std::vector
< void * > args
;
203 switch (member_
.get()->eTypeClass
) {
204 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
206 css::uno::TypeDescription
t(
208 typelib_InterfaceAttributeTypeDescription
* >(
212 OSL_ASSERT(inArguments_
.size() == 1);
213 args
.push_back(inArguments_
[0].getValue(t
));
215 OSL_ASSERT(inArguments_
.empty());
220 case typelib_TypeClass_INTERFACE_METHOD
:
222 typelib_InterfaceMethodTypeDescription
* mtd
=
224 typelib_InterfaceMethodTypeDescription
* >(
226 retType
= css::uno::TypeDescription(mtd
->pReturnTypeRef
);
227 std::vector
< BinaryAny
>::const_iterator
i(
228 inArguments_
.begin());
229 for (sal_Int32 j
= 0; j
!= mtd
->nParams
; ++j
) {
231 if (mtd
->pParams
[j
].bIn
) {
233 css::uno::TypeDescription(
234 mtd
->pParams
[j
].pTypeRef
));
237 std::vector
< char >(size_t_round(
238 css::uno::TypeDescription(
239 mtd
->pParams
[j
].pTypeRef
).
241 p
= &outBufs
.back()[0];
244 if (mtd
->pParams
[j
].bOut
) {
245 outArguments
->push_back(BinaryAny());
248 OSL_ASSERT(i
== inArguments_
.end());
252 OSL_ASSERT(false); // this cannot happen
257 nSize
= size_t_round(retType
.get()->nSize
);
258 std::vector
< char > retBuf(nSize
);
260 uno_Any
* pexc
= &exc
;
261 (*object_
.get()->pDispatcher
)(
262 object_
.get(), member_
.get(), retBuf
.empty() ? 0 : &retBuf
[0],
263 args
.empty() ? 0 : &args
[0], &pexc
);
266 *returnValue
= BinaryAny(
267 css::uno::TypeDescription(
268 cppu::UnoType
< css::uno::Any
>::get()),
270 uno_any_destruct(&exc
, 0);
272 if (!retBuf
.empty()) {
273 *returnValue
= BinaryAny(retType
, &retBuf
[0]);
274 uno_destructData(&retBuf
[0], retType
.get(), 0);
276 if (!outArguments
->empty()) {
278 member_
.get()->eTypeClass
==
279 typelib_TypeClass_INTERFACE_METHOD
);
280 typelib_InterfaceMethodTypeDescription
* mtd
=
282 typelib_InterfaceMethodTypeDescription
* >(
284 std::vector
< BinaryAny
>::iterator
i(outArguments
->begin());
285 std::list
< std::vector
< char > >::iterator
j(
287 for (sal_Int32 k
= 0; k
!= mtd
->nParams
; ++k
) {
288 if (mtd
->pParams
[k
].bOut
) {
290 css::uno::TypeDescription(
291 mtd
->pParams
[k
].pTypeRef
),
294 if (!mtd
->pParams
[k
].bIn
) {
295 uno_type_destructData(
296 &(*j
++)[0], mtd
->pParams
[k
].pTypeRef
, 0);
299 OSL_ASSERT(i
== outArguments
->end());
300 OSL_ASSERT(j
== outBufs
.end());
311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */