30#include <com/sun/star/connection/XConnection.hpp>
31#include <com/sun/star/io/IOException.hpp>
32#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
33#include <com/sun/star/uno/XCurrentContext.hpp>
36#include <uno/dispatcher.hxx>
50 , setCurrentContextMode(false)
54 rtl::ByteSequence theTid, OUString theOid,
55 css::uno::TypeDescription theType,
56 css::uno::TypeDescription theMember,
57 std::vector< BinaryAny >&& inArguments,
58 css::uno::UnoInterfaceReference theCurrentContext):
59 tid(
std::move(theTid)), oid(
std::move(theOid)),
type(
std::move(theType)), member(
std::move(theMember)),
60 currentContext(
std::move(theCurrentContext)), arguments(
std::move(inArguments)),
61 request(true), setter(false), exception(false), setCurrentContextMode(false)
65 rtl::ByteSequence theTid,
66 css::uno::TypeDescription theMember,
bool theSetter,
67 bool theException,
BinaryAny theReturnValue,
68 std::vector< BinaryAny >&& outArguments,
69 bool theSetCurrentContextMode):
70 tid(
std::move(theTid)), member(
std::move(theMember)),
71 returnValue(
std::move(theReturnValue)), arguments(
std::move(outArguments)),
72 request(false), setter(theSetter),
73 exception(theException), setCurrentContextMode(theSetCurrentContextMode)
84 rtl::ByteSequence
const & tid, OUString
const & oid,
85 css::uno::TypeDescription
const & type,
86 css::uno::TypeDescription
const & member,
87 std::vector< BinaryAny >
const & inArguments)
91 tid, oid,
type, member, inArguments,
false,
92 css::uno::UnoInterfaceReference());
96 rtl::ByteSequence
const & tid, css::uno::TypeDescription
const & member,
97 bool exception,
BinaryAny const & returnValue,
98 std::vector< BinaryAny >
const & outArguments)
101 sendReply(tid, member,
false, exception, returnValue,outArguments);
105 rtl::ByteSequence
const & tid, OUString
const & oid,
106 css::uno::TypeDescription
const & type,
107 css::uno::TypeDescription
const & member,
108 std::vector< BinaryAny >&& inArguments)
111 std::lock_guard g(
mutex_);
112 queue_.emplace_back(tid, oid,
type, member, std::move(inArguments), cc);
117 rtl::ByteSequence
const & tid,
118 com::sun::star::uno::TypeDescription
const & member,
bool setter,
119 bool exception,
BinaryAny const & returnValue,
120 std::vector< BinaryAny >&& outArguments,
bool setCurrentContextMode)
122 std::lock_guard g(
mutex_);
124 tid, member, setter, exception, returnValue, std::move(outArguments),
125 setCurrentContextMode);
138 std::lock_guard g(
mutex_);
154 std::lock_guard g(
mutex_);
168 (item.
oid !=
"UrpProtocolProperties" &&
170 css::uno::TypeDescription(
171 "com.sun.star.uno.XInterface::release")) &&
172 bridge_->isCurrentContextMode()),
179 bridge_->setCurrentContextMode();
183 }
catch (
const css::uno::Exception & e) {
184 SAL_INFO(
"binaryurp",
"caught " << e);
185 }
catch (
const std::exception & e) {
186 SAL_INFO(
"binaryurp",
"caught C++ exception " << e.what());
193 rtl::ByteSequence
const & tid, OUString
const & oid,
194 css::uno::TypeDescription
const & type,
195 css::uno::TypeDescription
const & member,
196 std::vector< BinaryAny >
const & inArguments,
bool currentContextMode,
197 css::uno::UnoInterfaceReference
const & currentContext)
199 assert(tid.getLength() != 0);
200 assert(!oid.isEmpty());
202 css::uno::TypeDescription
t(
type);
203 sal_Int32 functionId = 0;
204 bool bForceSynchronous =
false;
205 member.makeComplete();
206 switch (member.get()->eTypeClass) {
207 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
209 typelib_InterfaceAttributeTypeDescription * atd =
210 reinterpret_cast< typelib_InterfaceAttributeTypeDescription *
>(
212 assert(atd->pInterface !=
nullptr);
214 t = css::uno::TypeDescription(&atd->pInterface->aBase);
217 functionId = atd->pInterface->pMapMemberIndexToFunctionIndex[
218 atd->aBase.nPosition];
219 if (!inArguments.empty()) {
224 case typelib_TypeClass_INTERFACE_METHOD:
226 typelib_InterfaceMethodTypeDescription * mtd =
227 reinterpret_cast< typelib_InterfaceMethodTypeDescription *
>(
229 assert(mtd->pInterface !=
nullptr);
231 t = css::uno::TypeDescription(&mtd->pInterface->aBase);
234 functionId = mtd->pInterface->pMapMemberIndexToFunctionIndex[
235 mtd->aBase.nPosition];
236 bForceSynchronous = mtd->bOneWay &&
244 assert(functionId >= 0);
246 throw css::uno::RuntimeException(
"function ID too large for URP");
248 std::vector< unsigned char > buf;
252 if (newType || newOid || newTid || bForceSynchronous || functionId > 0x3FFF)
257 (0xC0 | (newType ? 0x20 : 0) | (newOid ? 0x10 : 0) |
258 (newTid ? 0x08 : 0) | (functionId > 0xFF ? 0x04 : 0) |
259 (bForceSynchronous ? 0x01 : 0)));
262 if (bForceSynchronous) {
265 if (functionId <= 0xFF) {
279 }
else if (functionId <= 0x3F) {
284 &buf,
static_cast< sal_uInt8 >(0x40 | (functionId >> 8)));
288 if (currentContextMode) {
289 css::uno::UnoInterfaceReference cc(currentContext);
292 css::uno::TypeDescription(
294 css::uno::Reference< css::uno::XCurrentContext > >
::get()),
296 css::uno::TypeDescription(
299 css::uno::XCurrentContext > >
::get()),
302 switch (member.get()->eTypeClass) {
303 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
304 if (!inArguments.empty()) {
305 assert(inArguments.size() == 1);
308 css::uno::TypeDescription(
310 typelib_InterfaceAttributeTypeDescription *
>(
313 inArguments.front());
316 case typelib_TypeClass_INTERFACE_METHOD:
318 typelib_InterfaceMethodTypeDescription * mtd =
319 reinterpret_cast< typelib_InterfaceMethodTypeDescription *
>(
321 std::vector< BinaryAny >::const_iterator
i(inArguments.begin());
322 for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
323 if (mtd->pParams[j].bIn) {
326 css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
330 assert(
i == inArguments.end());
344 rtl::ByteSequence
const & tid,
345 com::sun::star::uno::TypeDescription
const & member,
bool setter,
346 bool exception,
BinaryAny const & returnValue,
347 std::vector< BinaryAny >
const & outArguments)
349 assert(tid.getLength() != 0);
351 assert(member.get()->bComplete);
352 std::vector< unsigned char > buf;
354 Marshal::write8(&buf, 0x80 | (exception ? 0x20 : 0) | (newTid ? 0x08 : 0));
365 switch (member.get()->eTypeClass) {
366 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
370 css::uno::TypeDescription(
372 typelib_InterfaceAttributeTypeDescription *
>(
378 case typelib_TypeClass_INTERFACE_METHOD:
380 typelib_InterfaceMethodTypeDescription * mtd =
382 typelib_InterfaceMethodTypeDescription *
>(
385 &buf, css::uno::TypeDescription(mtd->pReturnTypeRef),
387 std::vector< BinaryAny >::const_iterator
i(
388 outArguments.begin());
389 for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
390 if (mtd->pParams[j].bOut) {
393 css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
397 assert(
i == outArguments.end());
411 std::vector< unsigned char >
header;
413 throw css::uno::RuntimeException(
414 "message too large for URP");
418 assert(!buffer.empty());
419 unsigned char const *
p = buffer.data();
420 std::vector< unsigned char >::size_type
n = buffer.size();
422 assert(
SAL_MAX_INT32 <= std::numeric_limits<std::size_t>::max());
427 css::uno::Sequence<sal_Int8> s(
header.size() + k);
429 std::memcpy(s.getArray(),
header.data(),
header.size());
431 std::memcpy(s.getArray() + s.getLength() - k,
p, k);
433 bridge_->getConnection()->write(s);
434 }
catch (
const css::io::IOException & e) {
436 throw css::lang::WrappedTargetRuntimeException(
437 "Binary URP write raised IO exception: " + e.Message,
438 css::uno::Reference< css::uno::XInterface >(), exc);
constexpr sal_Int8 header[]
static void write16(std::vector< unsigned char > *buffer, sal_uInt16 value)
void writeType(std::vector< unsigned char > *buffer, com::sun::star::uno::TypeDescription const &value)
void writeValue(std::vector< unsigned char > *buffer, com::sun::star::uno::TypeDescription const &type, BinaryAny const &value)
void writeTid(std::vector< unsigned char > *buffer, rtl::ByteSequence const &tid)
void writeOid(std::vector< unsigned char > *buffer, OUString const &oid)
static void write32(std::vector< unsigned char > *buffer, sal_uInt32 value)
static void write8(std::vector< unsigned char > *buffer, sal_uInt8 value)
void sendDirectReply(rtl::ByteSequence const &tid, com::sun::star::uno::TypeDescription const &member, bool exception, BinaryAny const &returnValue, std::vector< BinaryAny > const &outArguments)
std::deque< Item > queue_
void queueRequest(rtl::ByteSequence const &tid, OUString const &oid, com::sun::star::uno::TypeDescription const &type, com::sun::star::uno::TypeDescription const &member, std::vector< BinaryAny > &&inArguments)
void sendRequest(rtl::ByteSequence const &tid, OUString const &oid, com::sun::star::uno::TypeDescription const &type, com::sun::star::uno::TypeDescription const &member, std::vector< BinaryAny > const &inArguments, bool currentContextMode, com::sun::star::uno::UnoInterfaceReference const ¤tContext)
com::sun::star::uno::TypeDescription lastType_
void queueReply(rtl::ByteSequence const &tid, com::sun::star::uno::TypeDescription const &member, bool setter, bool exception, BinaryAny const &returnValue, std::vector< BinaryAny > &&outArguments, bool setCurrentContextMode)
void sendDirectRequest(rtl::ByteSequence const &tid, OUString const &oid, com::sun::star::uno::TypeDescription const &type, com::sun::star::uno::TypeDescription const &member, std::vector< BinaryAny > const &inArguments)
Writer(rtl::Reference< Bridge > const &bridge)
rtl::ByteSequence lastTid_
rtl::Reference< Bridge > bridge_
virtual ~Writer() override
void sendReply(rtl::ByteSequence const &tid, com::sun::star::uno::TypeDescription const &member, bool setter, bool exception, BinaryAny const &returnValue, std::vector< BinaryAny > const &outArguments)
virtual void execute() override
osl::Condition unblocked_
void sendMessage(std::vector< unsigned char > const &buffer)
#define SAL_INFO(area, stream)
css::uno::UnoInterfaceReference get()
@ SPECIAL_FUNCTION_ID_RELEASE
Any SAL_CALL getCaughtException()
bool setCurrentContextMode
std::vector< BinaryAny > arguments
com::sun::star::uno::UnoInterfaceReference currentContext
com::sun::star::uno::TypeDescription member
com::sun::star::uno::TypeDescription type