1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski #include "sal/config.h"
25*b1cdbd2cSJim Jagielski
26*b1cdbd2cSJim Jagielski #include <exception>
27*b1cdbd2cSJim Jagielski #include <memory>
28*b1cdbd2cSJim Jagielski #include <vector>
29*b1cdbd2cSJim Jagielski
30*b1cdbd2cSJim Jagielski #include "com/sun/star/connection/XConnection.hpp"
31*b1cdbd2cSJim Jagielski #include "com/sun/star/io/IOException.hpp"
32*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Any.hxx"
33*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Exception.hpp"
34*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Reference.hxx"
35*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/RuntimeException.hpp"
36*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Sequence.hxx"
37*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Type.hxx"
38*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/XCurrentContext.hpp"
39*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/XInterface.hpp"
40*b1cdbd2cSJim Jagielski #include "cppu/unotype.hxx"
41*b1cdbd2cSJim Jagielski #include "osl/diagnose.h"
42*b1cdbd2cSJim Jagielski #include "rtl/byteseq.h"
43*b1cdbd2cSJim Jagielski #include "rtl/string.h"
44*b1cdbd2cSJim Jagielski #include "rtl/textenc.h"
45*b1cdbd2cSJim Jagielski #include "rtl/ustring.h"
46*b1cdbd2cSJim Jagielski #include "rtl/ustring.hxx"
47*b1cdbd2cSJim Jagielski #include "sal/types.h"
48*b1cdbd2cSJim Jagielski #include "typelib/typeclass.h"
49*b1cdbd2cSJim Jagielski #include "typelib/typedescription.h"
50*b1cdbd2cSJim Jagielski #include "typelib/typedescription.hxx"
51*b1cdbd2cSJim Jagielski #include "uno/lbnames.h"
52*b1cdbd2cSJim Jagielski
53*b1cdbd2cSJim Jagielski #include "binaryany.hxx"
54*b1cdbd2cSJim Jagielski #include "bridge.hxx"
55*b1cdbd2cSJim Jagielski #include "incomingreply.hxx"
56*b1cdbd2cSJim Jagielski #include "incomingrequest.hxx"
57*b1cdbd2cSJim Jagielski #include "outgoingrequest.hxx"
58*b1cdbd2cSJim Jagielski #include "reader.hxx"
59*b1cdbd2cSJim Jagielski #include "specialfunctionids.hxx"
60*b1cdbd2cSJim Jagielski #include "unmarshal.hxx"
61*b1cdbd2cSJim Jagielski
62*b1cdbd2cSJim Jagielski namespace binaryurp {
63*b1cdbd2cSJim Jagielski
64*b1cdbd2cSJim Jagielski namespace {
65*b1cdbd2cSJim Jagielski
66*b1cdbd2cSJim Jagielski namespace css = com::sun::star;
67*b1cdbd2cSJim Jagielski
read(css::uno::Reference<css::connection::XConnection> const & connection,sal_uInt32 size,bool eofOk)68*b1cdbd2cSJim Jagielski css::uno::Sequence< sal_Int8 > read(
69*b1cdbd2cSJim Jagielski css::uno::Reference< css::connection::XConnection > const & connection,
70*b1cdbd2cSJim Jagielski sal_uInt32 size, bool eofOk)
71*b1cdbd2cSJim Jagielski {
72*b1cdbd2cSJim Jagielski OSL_ASSERT(connection.is());
73*b1cdbd2cSJim Jagielski if (size > SAL_MAX_INT32) {
74*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
75*b1cdbd2cSJim Jagielski rtl::OUString(
76*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
77*b1cdbd2cSJim Jagielski "binaryurp::Reader: block size too large")),
78*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
79*b1cdbd2cSJim Jagielski }
80*b1cdbd2cSJim Jagielski css::uno::Sequence< sal_Int8 > buf;
81*b1cdbd2cSJim Jagielski sal_Int32 n = connection->read(buf, static_cast< sal_Int32 >(size));
82*b1cdbd2cSJim Jagielski if (n == 0 && eofOk) {
83*b1cdbd2cSJim Jagielski return css::uno::Sequence< sal_Int8 >();
84*b1cdbd2cSJim Jagielski }
85*b1cdbd2cSJim Jagielski if (n != static_cast< sal_Int32 >(size)) {
86*b1cdbd2cSJim Jagielski throw css::io::IOException(
87*b1cdbd2cSJim Jagielski rtl::OUString(
88*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
89*b1cdbd2cSJim Jagielski "binaryurp::Reader: premature end of input")),
90*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
91*b1cdbd2cSJim Jagielski }
92*b1cdbd2cSJim Jagielski OSL_ASSERT(buf.getLength() == static_cast< sal_Int32 >(size));
93*b1cdbd2cSJim Jagielski return buf;
94*b1cdbd2cSJim Jagielski }
95*b1cdbd2cSJim Jagielski
request(void * pThreadSpecificData)96*b1cdbd2cSJim Jagielski extern "C" void SAL_CALL request(void * pThreadSpecificData) {
97*b1cdbd2cSJim Jagielski OSL_ASSERT(pThreadSpecificData != 0);
98*b1cdbd2cSJim Jagielski std::auto_ptr< IncomingRequest >(
99*b1cdbd2cSJim Jagielski static_cast< IncomingRequest * >(pThreadSpecificData))->
100*b1cdbd2cSJim Jagielski execute();
101*b1cdbd2cSJim Jagielski }
102*b1cdbd2cSJim Jagielski
103*b1cdbd2cSJim Jagielski }
104*b1cdbd2cSJim Jagielski
Reader(rtl::Reference<Bridge> const & bridge)105*b1cdbd2cSJim Jagielski Reader::Reader(rtl::Reference< Bridge > const & bridge): bridge_(bridge) {
106*b1cdbd2cSJim Jagielski OSL_ASSERT(bridge.is());
107*b1cdbd2cSJim Jagielski acquire();
108*b1cdbd2cSJim Jagielski }
109*b1cdbd2cSJim Jagielski
~Reader()110*b1cdbd2cSJim Jagielski Reader::~Reader() {}
111*b1cdbd2cSJim Jagielski
run()112*b1cdbd2cSJim Jagielski void Reader::run() {
113*b1cdbd2cSJim Jagielski setName("binaryurpReader");
114*b1cdbd2cSJim Jagielski try {
115*b1cdbd2cSJim Jagielski bridge_->sendRequestChangeRequest();
116*b1cdbd2cSJim Jagielski css::uno::Reference< css::connection::XConnection > con(
117*b1cdbd2cSJim Jagielski bridge_->getConnection());
118*b1cdbd2cSJim Jagielski for (;;) {
119*b1cdbd2cSJim Jagielski css::uno::Sequence< sal_Int8 > s(read(con, 8, true));
120*b1cdbd2cSJim Jagielski if (s.getLength() == 0) {
121*b1cdbd2cSJim Jagielski break;
122*b1cdbd2cSJim Jagielski }
123*b1cdbd2cSJim Jagielski Unmarshal header(bridge_, state_, s);
124*b1cdbd2cSJim Jagielski sal_uInt32 size = header.read32();
125*b1cdbd2cSJim Jagielski sal_uInt32 count = header.read32();
126*b1cdbd2cSJim Jagielski header.done();
127*b1cdbd2cSJim Jagielski if (count == 0) {
128*b1cdbd2cSJim Jagielski throw css::io::IOException(
129*b1cdbd2cSJim Jagielski rtl::OUString(
130*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
131*b1cdbd2cSJim Jagielski "binaryurp::Reader: block with zero message count"
132*b1cdbd2cSJim Jagielski " received")),
133*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
134*b1cdbd2cSJim Jagielski }
135*b1cdbd2cSJim Jagielski Unmarshal block(bridge_, state_, read(con, size, false));
136*b1cdbd2cSJim Jagielski for (sal_uInt32 i = 0; i != count; ++i) {
137*b1cdbd2cSJim Jagielski readMessage(block);
138*b1cdbd2cSJim Jagielski }
139*b1cdbd2cSJim Jagielski block.done();
140*b1cdbd2cSJim Jagielski }
141*b1cdbd2cSJim Jagielski } catch (css::uno::Exception & e) {
142*b1cdbd2cSJim Jagielski OSL_TRACE(
143*b1cdbd2cSJim Jagielski OSL_LOG_PREFIX "caught UNO exception '%s'",
144*b1cdbd2cSJim Jagielski rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
145*b1cdbd2cSJim Jagielski } catch (std::exception & e) {
146*b1cdbd2cSJim Jagielski OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
147*b1cdbd2cSJim Jagielski }
148*b1cdbd2cSJim Jagielski bridge_->terminate();
149*b1cdbd2cSJim Jagielski }
150*b1cdbd2cSJim Jagielski
onTerminated()151*b1cdbd2cSJim Jagielski void Reader::onTerminated() {
152*b1cdbd2cSJim Jagielski release();
153*b1cdbd2cSJim Jagielski }
154*b1cdbd2cSJim Jagielski
readMessage(Unmarshal & unmarshal)155*b1cdbd2cSJim Jagielski void Reader::readMessage(Unmarshal & unmarshal) {
156*b1cdbd2cSJim Jagielski sal_uInt8 flags1 = unmarshal.read8();
157*b1cdbd2cSJim Jagielski bool newType;
158*b1cdbd2cSJim Jagielski bool newOid;
159*b1cdbd2cSJim Jagielski bool newTid;
160*b1cdbd2cSJim Jagielski bool forceSynchronous;
161*b1cdbd2cSJim Jagielski sal_uInt16 functionId;
162*b1cdbd2cSJim Jagielski if ((flags1 & 0x80) != 0) { // bit 7: LONGHEADER
163*b1cdbd2cSJim Jagielski if ((flags1 & 0x40) == 0) { // bit 6: REQUEST
164*b1cdbd2cSJim Jagielski readReplyMessage(unmarshal, flags1);
165*b1cdbd2cSJim Jagielski return;
166*b1cdbd2cSJim Jagielski }
167*b1cdbd2cSJim Jagielski newType = (flags1 & 0x20) != 0; // bit 5: NEWTYPE
168*b1cdbd2cSJim Jagielski newOid = (flags1 & 0x10) != 0; // bit 4: NEWOID
169*b1cdbd2cSJim Jagielski newTid = (flags1 & 0x08) != 0; // bit 3: NEWTID
170*b1cdbd2cSJim Jagielski if ((flags1 & 0x01) != 0) { // bit 0: MOREFLAGSS
171*b1cdbd2cSJim Jagielski sal_uInt8 flags2 = unmarshal.read8();
172*b1cdbd2cSJim Jagielski forceSynchronous = (flags2 & 0x80) != 0; // bit 7: MUSTREPLY
173*b1cdbd2cSJim Jagielski if (((flags2 & 0x40) != 0) != forceSynchronous) {
174*b1cdbd2cSJim Jagielski // bit 6: SYNCHRONOUS
175*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
176*b1cdbd2cSJim Jagielski rtl::OUString(
177*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
178*b1cdbd2cSJim Jagielski "URP: request message with MUSTREPLY != SYNCHRONOUS"
179*b1cdbd2cSJim Jagielski " received")),
180*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
181*b1cdbd2cSJim Jagielski }
182*b1cdbd2cSJim Jagielski } else {
183*b1cdbd2cSJim Jagielski forceSynchronous = false;
184*b1cdbd2cSJim Jagielski }
185*b1cdbd2cSJim Jagielski functionId = ((flags1 & 0x04) != 0) // bit 2: FUNCTIONID16
186*b1cdbd2cSJim Jagielski ? unmarshal.read16() : unmarshal.read8();
187*b1cdbd2cSJim Jagielski } else {
188*b1cdbd2cSJim Jagielski newType = false;
189*b1cdbd2cSJim Jagielski newOid = false;
190*b1cdbd2cSJim Jagielski newTid = false;
191*b1cdbd2cSJim Jagielski forceSynchronous = false;
192*b1cdbd2cSJim Jagielski functionId = ((flags1 & 0x40) != 0) // bit 6: FUNCTIONID14
193*b1cdbd2cSJim Jagielski ? ((flags1 & 0x3F) << 8) | unmarshal.read8() : flags1 & 0x3F;
194*b1cdbd2cSJim Jagielski }
195*b1cdbd2cSJim Jagielski css::uno::TypeDescription type;
196*b1cdbd2cSJim Jagielski if (newType) {
197*b1cdbd2cSJim Jagielski type = unmarshal.readType();
198*b1cdbd2cSJim Jagielski lastType_ = type;
199*b1cdbd2cSJim Jagielski } else {
200*b1cdbd2cSJim Jagielski if (!lastType_.is()) {
201*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
202*b1cdbd2cSJim Jagielski rtl::OUString(
203*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
204*b1cdbd2cSJim Jagielski "URP: request message with NEWTYPE received when last"
205*b1cdbd2cSJim Jagielski " interface type has not yet been set")),
206*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
207*b1cdbd2cSJim Jagielski }
208*b1cdbd2cSJim Jagielski type = lastType_;
209*b1cdbd2cSJim Jagielski }
210*b1cdbd2cSJim Jagielski rtl::OUString oid;
211*b1cdbd2cSJim Jagielski if (newOid) {
212*b1cdbd2cSJim Jagielski oid = unmarshal.readOid();
213*b1cdbd2cSJim Jagielski if ( oid.isEmpty() ) {
214*b1cdbd2cSJim Jagielski throw css::io::IOException(
215*b1cdbd2cSJim Jagielski rtl::OUString(
216*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
217*b1cdbd2cSJim Jagielski "binaryurp::Unmarshal: emtpy OID")),
218*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
219*b1cdbd2cSJim Jagielski }
220*b1cdbd2cSJim Jagielski lastOid_ = oid;
221*b1cdbd2cSJim Jagielski } else {
222*b1cdbd2cSJim Jagielski if ( lastOid_.isEmpty() ) {
223*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
224*b1cdbd2cSJim Jagielski rtl::OUString(
225*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
226*b1cdbd2cSJim Jagielski "URP: request message with NEWOID received when last"
227*b1cdbd2cSJim Jagielski " OID has not yet been set")),
228*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
229*b1cdbd2cSJim Jagielski }
230*b1cdbd2cSJim Jagielski oid = lastOid_;
231*b1cdbd2cSJim Jagielski }
232*b1cdbd2cSJim Jagielski rtl::ByteSequence tid(getTid(unmarshal, newTid));
233*b1cdbd2cSJim Jagielski lastTid_ = tid;
234*b1cdbd2cSJim Jagielski type.makeComplete();
235*b1cdbd2cSJim Jagielski if (type.get()->eTypeClass != typelib_TypeClass_INTERFACE) {
236*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
237*b1cdbd2cSJim Jagielski rtl::OUString(
238*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
239*b1cdbd2cSJim Jagielski "URP: request message with non-interface interface type"
240*b1cdbd2cSJim Jagielski " received")),
241*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
242*b1cdbd2cSJim Jagielski }
243*b1cdbd2cSJim Jagielski typelib_InterfaceTypeDescription * itd =
244*b1cdbd2cSJim Jagielski reinterpret_cast< typelib_InterfaceTypeDescription * >(type.get());
245*b1cdbd2cSJim Jagielski if (functionId >= itd->nMapFunctionIndexToMemberIndex) {
246*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
247*b1cdbd2cSJim Jagielski rtl::OUString(
248*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
249*b1cdbd2cSJim Jagielski "URP: request message with unknown function ID received")),
250*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
251*b1cdbd2cSJim Jagielski }
252*b1cdbd2cSJim Jagielski sal_Int32 memberId = itd->pMapFunctionIndexToMemberIndex[functionId];
253*b1cdbd2cSJim Jagielski css::uno::TypeDescription memberTd(itd->ppAllMembers[memberId]);
254*b1cdbd2cSJim Jagielski memberTd.makeComplete();
255*b1cdbd2cSJim Jagielski OSL_ASSERT(memberTd.is());
256*b1cdbd2cSJim Jagielski bool protProps = bridge_->isProtocolPropertiesRequest(oid, type);
257*b1cdbd2cSJim Jagielski bool ccMode = !protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE &&
258*b1cdbd2cSJim Jagielski bridge_->isCurrentContextMode();
259*b1cdbd2cSJim Jagielski css::uno::UnoInterfaceReference cc;
260*b1cdbd2cSJim Jagielski if (ccMode) {
261*b1cdbd2cSJim Jagielski css::uno::TypeDescription t(
262*b1cdbd2cSJim Jagielski cppu::UnoType< css::uno::Reference< css::uno::XCurrentContext > >::
263*b1cdbd2cSJim Jagielski get());
264*b1cdbd2cSJim Jagielski cc.set(
265*b1cdbd2cSJim Jagielski *static_cast< uno_Interface ** >(
266*b1cdbd2cSJim Jagielski unmarshal.readValue(t).getValue(t)));
267*b1cdbd2cSJim Jagielski }
268*b1cdbd2cSJim Jagielski bool synchronous;
269*b1cdbd2cSJim Jagielski if (memberTd.get()->eTypeClass == typelib_TypeClass_INTERFACE_METHOD &&
270*b1cdbd2cSJim Jagielski (reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
271*b1cdbd2cSJim Jagielski memberTd.get())->
272*b1cdbd2cSJim Jagielski bOneWay))
273*b1cdbd2cSJim Jagielski {
274*b1cdbd2cSJim Jagielski synchronous = forceSynchronous;
275*b1cdbd2cSJim Jagielski } else {
276*b1cdbd2cSJim Jagielski if (forceSynchronous) {
277*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
278*b1cdbd2cSJim Jagielski rtl::OUString(
279*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
280*b1cdbd2cSJim Jagielski "URP: synchronous request message with non-oneway"
281*b1cdbd2cSJim Jagielski " function ID received")),
282*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
283*b1cdbd2cSJim Jagielski }
284*b1cdbd2cSJim Jagielski synchronous = true;
285*b1cdbd2cSJim Jagielski }
286*b1cdbd2cSJim Jagielski bool setter = false;
287*b1cdbd2cSJim Jagielski std::vector< BinaryAny > inArgs;
288*b1cdbd2cSJim Jagielski switch (memberTd.get()->eTypeClass) {
289*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_ATTRIBUTE:
290*b1cdbd2cSJim Jagielski setter = itd->pMapMemberIndexToFunctionIndex[memberId] != functionId;
291*b1cdbd2cSJim Jagielski // pMapMemberIndexToFunctionIndex contains function index of
292*b1cdbd2cSJim Jagielski // attribute getter
293*b1cdbd2cSJim Jagielski if (setter) {
294*b1cdbd2cSJim Jagielski inArgs.push_back(
295*b1cdbd2cSJim Jagielski unmarshal.readValue(
296*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
297*b1cdbd2cSJim Jagielski reinterpret_cast<
298*b1cdbd2cSJim Jagielski typelib_InterfaceAttributeTypeDescription * >(
299*b1cdbd2cSJim Jagielski memberTd.get())->
300*b1cdbd2cSJim Jagielski pAttributeTypeRef)));
301*b1cdbd2cSJim Jagielski }
302*b1cdbd2cSJim Jagielski break;
303*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_METHOD:
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski typelib_InterfaceMethodTypeDescription * mtd =
306*b1cdbd2cSJim Jagielski reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
307*b1cdbd2cSJim Jagielski memberTd.get());
308*b1cdbd2cSJim Jagielski for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
309*b1cdbd2cSJim Jagielski if (mtd->pParams[i].bIn) {
310*b1cdbd2cSJim Jagielski inArgs.push_back(
311*b1cdbd2cSJim Jagielski unmarshal.readValue(
312*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
313*b1cdbd2cSJim Jagielski mtd->pParams[i].pTypeRef)));
314*b1cdbd2cSJim Jagielski }
315*b1cdbd2cSJim Jagielski }
316*b1cdbd2cSJim Jagielski break;
317*b1cdbd2cSJim Jagielski }
318*b1cdbd2cSJim Jagielski default:
319*b1cdbd2cSJim Jagielski OSL_ASSERT(false); // this cannot happen
320*b1cdbd2cSJim Jagielski break;
321*b1cdbd2cSJim Jagielski }
322*b1cdbd2cSJim Jagielski bridge_->incrementCalls(
323*b1cdbd2cSJim Jagielski !protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE);
324*b1cdbd2cSJim Jagielski if (protProps) {
325*b1cdbd2cSJim Jagielski switch (functionId) {
326*b1cdbd2cSJim Jagielski case SPECIAL_FUNCTION_ID_REQUEST_CHANGE:
327*b1cdbd2cSJim Jagielski bridge_->handleRequestChangeRequest(tid, inArgs);
328*b1cdbd2cSJim Jagielski break;
329*b1cdbd2cSJim Jagielski case SPECIAL_FUNCTION_ID_COMMIT_CHANGE:
330*b1cdbd2cSJim Jagielski bridge_->handleCommitChangeRequest(tid, inArgs);
331*b1cdbd2cSJim Jagielski break;
332*b1cdbd2cSJim Jagielski default:
333*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
334*b1cdbd2cSJim Jagielski rtl::OUString(
335*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
336*b1cdbd2cSJim Jagielski "URP: request message with UrpProtocolProperties OID"
337*b1cdbd2cSJim Jagielski " and unknown function ID received")),
338*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
339*b1cdbd2cSJim Jagielski }
340*b1cdbd2cSJim Jagielski } else {
341*b1cdbd2cSJim Jagielski css::uno::UnoInterfaceReference obj;
342*b1cdbd2cSJim Jagielski switch (functionId) {
343*b1cdbd2cSJim Jagielski case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
344*b1cdbd2cSJim Jagielski obj = bridge_->findStub(oid, type);
345*b1cdbd2cSJim Jagielski if (!obj.is()) {
346*b1cdbd2cSJim Jagielski OSL_ASSERT(
347*b1cdbd2cSJim Jagielski inArgs.size() == 1
348*b1cdbd2cSJim Jagielski && inArgs[0].getType().equals(
349*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
350*b1cdbd2cSJim Jagielski cppu::UnoType< css::uno::Type >::get())));
351*b1cdbd2cSJim Jagielski if (!(type.equals(
352*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
353*b1cdbd2cSJim Jagielski cppu::UnoType<
354*b1cdbd2cSJim Jagielski css::uno::Reference<
355*b1cdbd2cSJim Jagielski css::uno::XInterface > >::get()))
356*b1cdbd2cSJim Jagielski && (css::uno::TypeDescription(
357*b1cdbd2cSJim Jagielski *static_cast<
358*b1cdbd2cSJim Jagielski typelib_TypeDescriptionReference ** >(
359*b1cdbd2cSJim Jagielski inArgs[0].getValue(inArgs[0].getType()))).
360*b1cdbd2cSJim Jagielski equals(
361*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
362*b1cdbd2cSJim Jagielski cppu::UnoType<
363*b1cdbd2cSJim Jagielski css::uno::Reference<
364*b1cdbd2cSJim Jagielski css::uno::XInterface > >::get())))))
365*b1cdbd2cSJim Jagielski {
366*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
367*b1cdbd2cSJim Jagielski rtl::OUString(
368*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
369*b1cdbd2cSJim Jagielski "URP: queryInterface request message with"
370*b1cdbd2cSJim Jagielski " unknown OID received")),
371*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
372*b1cdbd2cSJim Jagielski }
373*b1cdbd2cSJim Jagielski }
374*b1cdbd2cSJim Jagielski break;
375*b1cdbd2cSJim Jagielski case SPECIAL_FUNCTION_ID_RESERVED:
376*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
377*b1cdbd2cSJim Jagielski rtl::OUString(
378*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
379*b1cdbd2cSJim Jagielski "URP: request message with unknown function ID 1"
380*b1cdbd2cSJim Jagielski " received")),
381*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
382*b1cdbd2cSJim Jagielski case SPECIAL_FUNCTION_ID_RELEASE:
383*b1cdbd2cSJim Jagielski break;
384*b1cdbd2cSJim Jagielski default:
385*b1cdbd2cSJim Jagielski obj = bridge_->findStub(oid, type);
386*b1cdbd2cSJim Jagielski if (!obj.is()) {
387*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
388*b1cdbd2cSJim Jagielski rtl::OUString(
389*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
390*b1cdbd2cSJim Jagielski "URP: request message with unknown OID received")),
391*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
392*b1cdbd2cSJim Jagielski }
393*b1cdbd2cSJim Jagielski break;
394*b1cdbd2cSJim Jagielski }
395*b1cdbd2cSJim Jagielski std::auto_ptr< IncomingRequest > req(
396*b1cdbd2cSJim Jagielski new IncomingRequest(
397*b1cdbd2cSJim Jagielski bridge_, tid, oid, obj, type, functionId, synchronous, memberTd,
398*b1cdbd2cSJim Jagielski setter, inArgs, ccMode, cc));
399*b1cdbd2cSJim Jagielski if (synchronous) {
400*b1cdbd2cSJim Jagielski bridge_->incrementActiveCalls();
401*b1cdbd2cSJim Jagielski }
402*b1cdbd2cSJim Jagielski uno_threadpool_putJob(
403*b1cdbd2cSJim Jagielski bridge_->getThreadPool(), tid.getHandle(), req.get(), &request,
404*b1cdbd2cSJim Jagielski !synchronous);
405*b1cdbd2cSJim Jagielski req.release();
406*b1cdbd2cSJim Jagielski }
407*b1cdbd2cSJim Jagielski }
408*b1cdbd2cSJim Jagielski
readReplyMessage(Unmarshal & unmarshal,sal_uInt8 flags1)409*b1cdbd2cSJim Jagielski void Reader::readReplyMessage(Unmarshal & unmarshal, sal_uInt8 flags1) {
410*b1cdbd2cSJim Jagielski rtl::ByteSequence tid(getTid(unmarshal, (flags1 & 0x08) != 0));
411*b1cdbd2cSJim Jagielski // bit 3: NEWTID
412*b1cdbd2cSJim Jagielski lastTid_ = tid;
413*b1cdbd2cSJim Jagielski OutgoingRequest req(bridge_->lastOutgoingRequest(tid));
414*b1cdbd2cSJim Jagielski bool exc = (flags1 & 0x20) != 0; // bit 5: EXCEPTION
415*b1cdbd2cSJim Jagielski BinaryAny ret;
416*b1cdbd2cSJim Jagielski std::vector< BinaryAny > outArgs;
417*b1cdbd2cSJim Jagielski if (exc) {
418*b1cdbd2cSJim Jagielski ret = unmarshal.readValue(
419*b1cdbd2cSJim Jagielski css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()));
420*b1cdbd2cSJim Jagielski if (!typelib_typedescription_isAssignableFrom(
421*b1cdbd2cSJim Jagielski (css::uno::TypeDescription(
422*b1cdbd2cSJim Jagielski cppu::UnoType< css::uno::RuntimeException >::get()).
423*b1cdbd2cSJim Jagielski get()),
424*b1cdbd2cSJim Jagielski ret.getType().get()))
425*b1cdbd2cSJim Jagielski {
426*b1cdbd2cSJim Jagielski sal_Int32 n = 0;
427*b1cdbd2cSJim Jagielski typelib_TypeDescriptionReference ** p = 0;
428*b1cdbd2cSJim Jagielski switch (req.member.get()->eTypeClass) {
429*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_ATTRIBUTE:
430*b1cdbd2cSJim Jagielski {
431*b1cdbd2cSJim Jagielski typelib_InterfaceAttributeTypeDescription * atd =
432*b1cdbd2cSJim Jagielski reinterpret_cast<
433*b1cdbd2cSJim Jagielski typelib_InterfaceAttributeTypeDescription * >(
434*b1cdbd2cSJim Jagielski req.member.get());
435*b1cdbd2cSJim Jagielski n = req.setter ? atd->nSetExceptions : atd->nGetExceptions;
436*b1cdbd2cSJim Jagielski p = req.setter
437*b1cdbd2cSJim Jagielski ? atd->ppSetExceptions : atd->ppGetExceptions;
438*b1cdbd2cSJim Jagielski break;
439*b1cdbd2cSJim Jagielski }
440*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_METHOD:
441*b1cdbd2cSJim Jagielski {
442*b1cdbd2cSJim Jagielski typelib_InterfaceMethodTypeDescription * mtd =
443*b1cdbd2cSJim Jagielski reinterpret_cast<
444*b1cdbd2cSJim Jagielski typelib_InterfaceMethodTypeDescription * >(
445*b1cdbd2cSJim Jagielski req.member.get());
446*b1cdbd2cSJim Jagielski n = mtd->nExceptions;
447*b1cdbd2cSJim Jagielski p = mtd->ppExceptions;
448*b1cdbd2cSJim Jagielski break;
449*b1cdbd2cSJim Jagielski }
450*b1cdbd2cSJim Jagielski default:
451*b1cdbd2cSJim Jagielski OSL_ASSERT(false); // this cannot happen
452*b1cdbd2cSJim Jagielski break;
453*b1cdbd2cSJim Jagielski }
454*b1cdbd2cSJim Jagielski bool ok = false;
455*b1cdbd2cSJim Jagielski for (sal_Int32 i = 0; i != n; ++i) {
456*b1cdbd2cSJim Jagielski if (typelib_typedescriptionreference_isAssignableFrom(
457*b1cdbd2cSJim Jagielski p[i],
458*b1cdbd2cSJim Jagielski reinterpret_cast< typelib_TypeDescriptionReference * >(
459*b1cdbd2cSJim Jagielski ret.getType().get())))
460*b1cdbd2cSJim Jagielski {
461*b1cdbd2cSJim Jagielski ok = true;
462*b1cdbd2cSJim Jagielski break;
463*b1cdbd2cSJim Jagielski }
464*b1cdbd2cSJim Jagielski }
465*b1cdbd2cSJim Jagielski if (!ok) {
466*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
467*b1cdbd2cSJim Jagielski rtl::OUString(
468*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
469*b1cdbd2cSJim Jagielski "URP: reply message with bad exception type"
470*b1cdbd2cSJim Jagielski " received")),
471*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
472*b1cdbd2cSJim Jagielski }
473*b1cdbd2cSJim Jagielski }
474*b1cdbd2cSJim Jagielski } else {
475*b1cdbd2cSJim Jagielski switch (req.member.get()->eTypeClass) {
476*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_ATTRIBUTE:
477*b1cdbd2cSJim Jagielski if (!req.setter) {
478*b1cdbd2cSJim Jagielski ret = unmarshal.readValue(
479*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
480*b1cdbd2cSJim Jagielski reinterpret_cast<
481*b1cdbd2cSJim Jagielski typelib_InterfaceAttributeTypeDescription * >(
482*b1cdbd2cSJim Jagielski req.member.get())->
483*b1cdbd2cSJim Jagielski pAttributeTypeRef));
484*b1cdbd2cSJim Jagielski }
485*b1cdbd2cSJim Jagielski break;
486*b1cdbd2cSJim Jagielski case typelib_TypeClass_INTERFACE_METHOD:
487*b1cdbd2cSJim Jagielski {
488*b1cdbd2cSJim Jagielski typelib_InterfaceMethodTypeDescription * mtd =
489*b1cdbd2cSJim Jagielski reinterpret_cast<
490*b1cdbd2cSJim Jagielski typelib_InterfaceMethodTypeDescription * >(
491*b1cdbd2cSJim Jagielski req.member.get());
492*b1cdbd2cSJim Jagielski ret = unmarshal.readValue(
493*b1cdbd2cSJim Jagielski css::uno::TypeDescription(mtd->pReturnTypeRef));
494*b1cdbd2cSJim Jagielski for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
495*b1cdbd2cSJim Jagielski if (mtd->pParams[i].bOut) {
496*b1cdbd2cSJim Jagielski outArgs.push_back(
497*b1cdbd2cSJim Jagielski unmarshal.readValue(
498*b1cdbd2cSJim Jagielski css::uno::TypeDescription(
499*b1cdbd2cSJim Jagielski mtd->pParams[i].pTypeRef)));
500*b1cdbd2cSJim Jagielski }
501*b1cdbd2cSJim Jagielski }
502*b1cdbd2cSJim Jagielski break;
503*b1cdbd2cSJim Jagielski }
504*b1cdbd2cSJim Jagielski default:
505*b1cdbd2cSJim Jagielski OSL_ASSERT(false); // this cannot happen
506*b1cdbd2cSJim Jagielski break;
507*b1cdbd2cSJim Jagielski }
508*b1cdbd2cSJim Jagielski }
509*b1cdbd2cSJim Jagielski switch (req.kind) {
510*b1cdbd2cSJim Jagielski case OutgoingRequest::KIND_NORMAL:
511*b1cdbd2cSJim Jagielski {
512*b1cdbd2cSJim Jagielski std::auto_ptr< IncomingReply > resp(
513*b1cdbd2cSJim Jagielski new IncomingReply(exc, ret, outArgs));
514*b1cdbd2cSJim Jagielski uno_threadpool_putJob(
515*b1cdbd2cSJim Jagielski bridge_->getThreadPool(), tid.getHandle(), resp.get(), 0,
516*b1cdbd2cSJim Jagielski false);
517*b1cdbd2cSJim Jagielski resp.release();
518*b1cdbd2cSJim Jagielski break;
519*b1cdbd2cSJim Jagielski }
520*b1cdbd2cSJim Jagielski case OutgoingRequest::KIND_REQUEST_CHANGE:
521*b1cdbd2cSJim Jagielski OSL_ASSERT(outArgs.empty());
522*b1cdbd2cSJim Jagielski bridge_->handleRequestChangeReply(exc, ret);
523*b1cdbd2cSJim Jagielski break;
524*b1cdbd2cSJim Jagielski case OutgoingRequest::KIND_COMMIT_CHANGE:
525*b1cdbd2cSJim Jagielski OSL_ASSERT(outArgs.empty());
526*b1cdbd2cSJim Jagielski bridge_->handleCommitChangeReply(exc, ret);
527*b1cdbd2cSJim Jagielski break;
528*b1cdbd2cSJim Jagielski default:
529*b1cdbd2cSJim Jagielski OSL_ASSERT(false); // this cannot happen
530*b1cdbd2cSJim Jagielski break;
531*b1cdbd2cSJim Jagielski }
532*b1cdbd2cSJim Jagielski }
533*b1cdbd2cSJim Jagielski
getTid(Unmarshal & unmarshal,bool newTid) const534*b1cdbd2cSJim Jagielski rtl::ByteSequence Reader::getTid(Unmarshal & unmarshal, bool newTid) const {
535*b1cdbd2cSJim Jagielski if (newTid) {
536*b1cdbd2cSJim Jagielski return unmarshal.readTid();
537*b1cdbd2cSJim Jagielski }
538*b1cdbd2cSJim Jagielski if (lastTid_.getLength() == 0) {
539*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
540*b1cdbd2cSJim Jagielski rtl::OUString(
541*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
542*b1cdbd2cSJim Jagielski "URP: message with NEWTID received when last TID has not"
543*b1cdbd2cSJim Jagielski " yet been set")),
544*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
545*b1cdbd2cSJim Jagielski }
546*b1cdbd2cSJim Jagielski return lastTid_;
547*b1cdbd2cSJim Jagielski }
548*b1cdbd2cSJim Jagielski
549*b1cdbd2cSJim Jagielski }
550