xref: /aoo4110/main/binaryurp/source/reader.cxx (revision b1cdbd2c)
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