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