LCOV - code coverage report
Current view: top level - binaryurp/source - writer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 166 184 90.2 %
Date: 2012-08-25 Functions: 16 16 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 187 328 57.0 %

           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 <exception>
      23                 :            : #include <vector>
      24                 :            : 
      25                 :            : #include "com/sun/star/connection/XConnection.hpp"
      26                 :            : #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
      27                 :            : #include "com/sun/star/uno/XCurrentContext.hpp"
      28                 :            : #include "cppuhelper/exc_hlp.hxx"
      29                 :            : #include "osl/mutex.hxx"
      30                 :            : #include "rtl/memory.h"
      31                 :            : #include "uno/dispatcher.hxx"
      32                 :            : 
      33                 :            : #include "binaryany.hxx"
      34                 :            : #include "bridge.hxx"
      35                 :            : #include "currentcontext.hxx"
      36                 :            : #include "specialfunctionids.hxx"
      37                 :            : #include "writer.hxx"
      38                 :            : 
      39                 :            : namespace binaryurp {
      40                 :            : 
      41                 :            : namespace {
      42                 :            : 
      43                 :            : namespace css = com::sun::star;
      44                 :            : 
      45                 :            : }
      46                 :            : 
      47         [ +  - ]:     389594 : Writer::Item::Item() {}
      48                 :            : 
      49                 :      22782 : Writer::Item::Item(
      50                 :            :     rtl::ByteSequence const & theTid, OUString const & theOid,
      51                 :            :     css::uno::TypeDescription const & theType,
      52                 :            :     css::uno::TypeDescription const & theMember,
      53                 :            :     std::vector< BinaryAny > const & inArguments,
      54                 :            :     css::uno::UnoInterfaceReference const & theCurrentContext):
      55                 :            :     request(true), tid(theTid), oid(theOid), type(theType), member(theMember),
      56 [ +  - ][ +  - ]:      22782 :     arguments(inArguments), currentContext(theCurrentContext)
      57                 :      22782 : {}
      58                 :            : 
      59                 :     366717 : Writer::Item::Item(
      60                 :            :     rtl::ByteSequence const & theTid,
      61                 :            :     css::uno::TypeDescription const & theMember, bool theSetter,
      62                 :            :     bool theException, BinaryAny const & theReturnValue,
      63                 :            :     std::vector< BinaryAny > const & outArguments,
      64                 :            :     bool theSetCurrentContextMode):
      65                 :            :     request(false), tid(theTid), member(theMember), setter(theSetter),
      66                 :            :     arguments(outArguments), exception(theException),
      67         [ +  - ]:     366717 :     returnValue(theReturnValue), setCurrentContextMode(theSetCurrentContextMode)
      68                 :     366717 : {}
      69                 :            : 
      70                 :        102 : Writer::Writer(rtl::Reference< Bridge > const  & bridge):
      71                 :            :     Thread("binaryurpWriter"), bridge_(bridge), marshal_(bridge, state_),
      72 [ +  - ][ +  - ]:        102 :     stop_(false)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      73                 :            : {
      74                 :            :     OSL_ASSERT(bridge.is());
      75                 :        102 : }
      76                 :            : 
      77                 :        161 : void Writer::sendDirectRequest(
      78                 :            :     rtl::ByteSequence const & tid, OUString const & oid,
      79                 :            :     css::uno::TypeDescription const & type,
      80                 :            :     css::uno::TypeDescription const & member,
      81                 :            :     std::vector< BinaryAny > const & inArguments)
      82                 :            : {
      83                 :            :     OSL_ASSERT(!unblocked_.check());
      84                 :            :     sendRequest(
      85                 :            :         tid, oid, type, member, inArguments, false,
      86         [ +  - ]:        161 :         css::uno::UnoInterfaceReference());
      87                 :        161 : }
      88                 :            : 
      89                 :        145 : void Writer::sendDirectReply(
      90                 :            :     rtl::ByteSequence const & tid, css::uno::TypeDescription const & member,
      91                 :            :     bool exception, BinaryAny const & returnValue,
      92                 :            :     std::vector< BinaryAny > const & outArguments)
      93                 :            : {
      94                 :            :     OSL_ASSERT(!unblocked_.check());
      95                 :        145 :     sendReply(tid, member, false, exception, returnValue,outArguments);
      96                 :        145 : }
      97                 :            : 
      98                 :      22782 : void Writer::queueRequest(
      99                 :            :     rtl::ByteSequence const & tid, OUString const & oid,
     100                 :            :     css::uno::TypeDescription const & type,
     101                 :            :     css::uno::TypeDescription const & member,
     102                 :            :     std::vector< BinaryAny > const & inArguments)
     103                 :            : {
     104         [ +  - ]:      22782 :     css::uno::UnoInterfaceReference cc(current_context::get());
     105         [ +  - ]:      22782 :     osl::MutexGuard g(mutex_);
     106 [ +  - ][ +  - ]:      22782 :     queue_.push_back(Item(tid, oid, type, member, inArguments, cc));
                 [ +  - ]
     107 [ +  - ][ +  - ]:      22782 :     items_.set();
                 [ +  - ]
     108                 :      22782 : }
     109                 :            : 
     110                 :     366717 : void Writer::queueReply(
     111                 :            :     rtl::ByteSequence const & tid,
     112                 :            :     com::sun::star::uno::TypeDescription const & member, bool setter,
     113                 :            :     bool exception, BinaryAny const & returnValue,
     114                 :            :     std::vector< BinaryAny > const & outArguments, bool setCurrentContextMode)
     115                 :            : {
     116         [ +  - ]:     366717 :     osl::MutexGuard g(mutex_);
     117                 :            :     queue_.push_back(
     118                 :            :         Item(
     119                 :            :             tid, member, setter, exception, returnValue, outArguments,
     120 [ +  - ][ +  - ]:     366717 :             setCurrentContextMode));
                 [ +  - ]
     121 [ +  - ][ +  - ]:     366717 :     items_.set();
     122                 :     366717 : }
     123                 :            : 
     124                 :        102 : void Writer::unblock() {
     125                 :            :     // Assumes that osl::Condition::set works as a memory barrier, so that
     126                 :            :     // changes made by preceeding sendDirectRequest/Reply calls are visible to
     127                 :            :     // subsequent sendRequest/Reply calls:
     128                 :        102 :     unblocked_.set();
     129                 :        102 : }
     130                 :            : 
     131                 :        100 : void Writer::stop() {
     132                 :            :     {
     133         [ +  - ]:        100 :         osl::MutexGuard g(mutex_);
     134         [ +  - ]:        100 :         stop_ = true;
     135                 :            :     }
     136                 :        100 :     unblocked_.set();
     137                 :        100 :     items_.set();
     138                 :        100 : }
     139                 :            : 
     140 [ +  - ][ +  - ]:        200 : Writer::~Writer() {}
         [ +  - ][ +  - ]
                 [ -  + ]
     141                 :            : 
     142                 :        102 : void Writer::execute() {
     143                 :            :     try {
     144         [ +  - ]:        102 :         unblocked_.wait();
     145                 :     389593 :         for (;;) {
     146         [ +  - ]:     389596 :             items_.wait();
     147         [ +  - ]:     389594 :             Item item;
     148                 :            :             {
     149         [ +  - ]:     389594 :                 osl::MutexGuard g(mutex_);
     150         [ +  + ]:     389594 :                 if (stop_) {
     151                 :        100 :                     return;
     152                 :            :                 }
     153                 :            :                 OSL_ASSERT(!queue_.empty());
     154 [ +  - ][ +  - ]:     389495 :                 item = queue_.front();
     155         [ +  - ]:     389495 :                 queue_.pop_front();
     156         [ +  + ]:     389495 :                 if (queue_.empty()) {
     157         [ +  - ]:     389495 :                     items_.reset();
     158 [ +  - ][ +  + ]:     389594 :                 }
     159                 :            :             }
     160         [ +  + ]:     389594 :             if (item.request) {
     161                 :            :                 sendRequest(
     162                 :            :                     item.tid, item.oid, item.type, item.member, item.arguments,
     163                 :      22778 :                     (item.oid != "UrpProtocolProperties" &&
     164                 :            :                      !item.member.equals(
     165                 :            :                          css::uno::TypeDescription(
     166                 :            :                              OUString(
     167                 :            :                                  RTL_CONSTASCII_USTRINGPARAM(
     168                 :            :                                      "com.sun.star.uno.XInterface::"
     169 [ +  - ][ +  - ]:      45556 :                                      "release")))) &&
         [ +  - ][ +  - ]
           [ #  #  #  # ]
     170         [ +  - ]:      13606 :                      bridge_->isCurrentContextMode()),
     171 [ +  + ][ +  - ]:      59162 :                     item.currentContext);
         [ +  - ][ +  - ]
     172                 :            :             } else {
     173                 :            :                 sendReply(
     174                 :            :                     item.tid, item.member, item.setter, item.exception,
     175         [ +  + ]:     366717 :                     item.returnValue, item.arguments);
     176         [ -  + ]:     366716 :                 if (item.setCurrentContextMode) {
     177         [ #  # ]:     389494 :                     bridge_->setCurrentContextMode();
     178                 :            :                 }
     179                 :            :             }
     180 [ +  - ][ +  + ]:     389594 :         }
              [ -  +  - ]
     181                 :          1 :     } catch (const css::uno::Exception & e) {
     182                 :            :         OSL_TRACE(
     183                 :            :             OSL_LOG_PREFIX "caught UNO exception '%s'",
     184                 :            :             OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
     185                 :          0 :     } catch (const std::exception & e) {
     186                 :            :         OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
     187                 :            :     }
     188                 :          1 :     bridge_->terminate(false);
     189                 :            : }
     190                 :            : 
     191                 :      22939 : void Writer::sendRequest(
     192                 :            :     rtl::ByteSequence const & tid, OUString const & oid,
     193                 :            :     css::uno::TypeDescription const & type,
     194                 :            :     css::uno::TypeDescription const & member,
     195                 :            :     std::vector< BinaryAny > const & inArguments, bool currentContextMode,
     196                 :            :     css::uno::UnoInterfaceReference const & currentContext)
     197                 :            : {
     198                 :            :     OSL_ASSERT(tid.getLength() != 0 && !oid.isEmpty() && member.is());
     199                 :      22939 :     css::uno::TypeDescription t(type);
     200                 :      22939 :     sal_Int32 functionId = 0;
     201                 :      22939 :     bool forceSynchronous = false;
     202                 :      22939 :     member.makeComplete();
     203      [ +  +  - ]:      22939 :     switch (member.get()->eTypeClass) {
     204                 :            :     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     205                 :            :         {
     206                 :            :             typelib_InterfaceAttributeTypeDescription * atd =
     207                 :            :                 reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
     208                 :       1801 :                     member.get());
     209                 :            :             OSL_ASSERT(atd->pInterface != 0);
     210         [ +  - ]:       1801 :             if (!t.is()) {
     211         [ +  - ]:       1801 :                 t = css::uno::TypeDescription(&atd->pInterface->aBase);
     212                 :            :             }
     213                 :       1801 :             t.makeComplete();
     214                 :            :             functionId = atd->pInterface->pMapMemberIndexToFunctionIndex[
     215                 :       1801 :                 atd->aBase.nPosition];
     216         [ -  + ]:       1801 :             if (!inArguments.empty()) { // setter
     217                 :          0 :                 ++functionId;
     218                 :            :             }
     219                 :       1801 :             break;
     220                 :            :         }
     221                 :            :     case typelib_TypeClass_INTERFACE_METHOD:
     222                 :            :         {
     223                 :            :             typelib_InterfaceMethodTypeDescription * mtd =
     224                 :            :                 reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
     225                 :      21138 :                     member.get());
     226                 :            :             OSL_ASSERT(mtd->pInterface != 0);
     227         [ +  + ]:      21138 :             if (!t.is()) {
     228         [ +  - ]:      11805 :                 t = css::uno::TypeDescription(&mtd->pInterface->aBase);
     229                 :            :             }
     230                 :      21138 :             t.makeComplete();
     231                 :            :             functionId = mtd->pInterface->pMapMemberIndexToFunctionIndex[
     232                 :      21138 :                 mtd->aBase.nPosition];
     233                 :            :             forceSynchronous = mtd->bOneWay &&
     234 [ +  + ][ +  + ]:      21138 :                 functionId != SPECIAL_FUNCTION_ID_RELEASE;
     235                 :      21138 :             break;
     236                 :            :         }
     237                 :            :     default:
     238                 :            :         OSL_ASSERT(false); // this cannot happen
     239                 :          0 :         break;
     240                 :            :     }
     241                 :            :     OSL_ASSERT(functionId >= 0);
     242         [ -  + ]:      22939 :     if (functionId > SAL_MAX_UINT16) {
     243                 :            :         throw css::uno::RuntimeException(
     244                 :            :             OUString(
     245                 :            :                 RTL_CONSTASCII_USTRINGPARAM("function ID too large for URP")),
     246 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
     247                 :            :     }
     248         [ +  - ]:      22939 :     std::vector< unsigned char > buf;
     249 [ +  + ][ +  - ]:      22939 :     bool newType = !(lastType_.is() && t.equals(lastType_));
                 [ +  + ]
     250                 :      22939 :     bool newOid = oid != lastOid_;
     251                 :      22939 :     bool newTid = tid != lastTid_;
     252 [ +  + ][ +  + ]:      22939 :     if (newType || newOid || newTid || forceSynchronous || functionId > 0x3FFF)
         [ +  + ][ -  + ]
                 [ +  + ]
     253                 :            :         // > 14 bit function ID
     254                 :            :     {
     255                 :            :         Marshal::write8(
     256                 :            :             &buf,
     257                 :            :             (0xC0 | (newType ? 0x20 : 0) | (newOid ? 0x10 : 0) |
     258                 :            :              (newTid ? 0x08 : 0) | (functionId > 0xFF ? 0x04 : 0) |
     259 [ +  + ][ +  + ]:      12076 :              (forceSynchronous ? 0x01 : 0)));
         [ +  + ][ -  + ]
         [ +  + ][ +  - ]
     260                 :            :             // bit 7: LONGHEADER, bit 6: REQUEST, bit 5: NEWTYPE, bit 4: NEWOID,
     261                 :            :             // bit 3: NEWTID, bit 2: FUNCTIONID16, bit 0: MOREFLAGS
     262         [ +  + ]:      12076 :         if (forceSynchronous) {
     263         [ +  - ]:       1148 :             Marshal::write8(&buf, 0xC0); // bit 7: MUSTREPLY, bit 6: SYNCHRONOUS
     264                 :            :         }
     265         [ +  - ]:      12076 :         if (functionId <= 0xFF) {
     266         [ +  - ]:      12076 :             Marshal::write8(&buf, static_cast< sal_uInt8 >(functionId));
     267                 :            :         } else {
     268         [ #  # ]:          0 :             Marshal::write16(&buf, static_cast< sal_uInt16 >(functionId));
     269                 :            :         }
     270         [ +  + ]:      12076 :         if (newType) {
     271         [ +  - ]:       3523 :             marshal_.writeType(&buf, t);
     272                 :            :         }
     273         [ +  + ]:      12076 :         if (newOid) {
     274         [ +  - ]:       4572 :             marshal_.writeOid(&buf, oid);
     275                 :            :         }
     276         [ +  + ]:      18723 :         if (newTid) {
     277         [ +  - ]:       6647 :             marshal_.writeTid(&buf, tid);
     278                 :            :         }
     279         [ +  - ]:      10863 :     } else if (functionId <= 0x3F) { // <= 6 bit function ID
     280         [ +  - ]:      10863 :         Marshal::write8(&buf, static_cast< sal_uInt8 >(functionId));
     281                 :            :             // bit 7: !LONGHEADER, bit 6: !FUNCTIONID14
     282                 :            :     } else {
     283                 :            :         Marshal::write8(
     284         [ #  # ]:          0 :             &buf, static_cast< sal_uInt8 >(0x40 | (functionId >> 8)));
     285                 :            :             // bit 7: !LONGHEADER, bit 6: FUNCTIONID14
     286         [ #  # ]:          0 :         Marshal::write8(&buf, functionId & 0xFF);
     287                 :            :     }
     288         [ +  + ]:      22939 :     if (currentContextMode) {
     289         [ +  - ]:      13606 :         css::uno::UnoInterfaceReference cc(currentContext);
     290                 :            :         marshal_.writeValue(
     291                 :            :             &buf,
     292                 :            :             css::uno::TypeDescription(
     293                 :            :                 cppu::UnoType<
     294         [ +  - ]:      13606 :                     css::uno::Reference< css::uno::XCurrentContext > >::get()),
     295                 :            :             BinaryAny(
     296                 :            :                 css::uno::TypeDescription(
     297                 :            :                     cppu::UnoType<
     298                 :            :                         css::uno::Reference<
     299         [ +  - ]:      13606 :                             css::uno::XCurrentContext > >::get()),
     300 [ +  - ][ +  - ]:      27212 :                 &cc.m_pUnoI));
     301                 :            :     }
     302      [ +  +  - ]:      22939 :     switch (member.get()->eTypeClass) {
     303                 :            :     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     304         [ -  + ]:       1801 :         if (!inArguments.empty()) { // setter
     305                 :            :             OSL_ASSERT(inArguments.size() == 1);
     306                 :            :             marshal_.writeValue(
     307                 :            :                 &buf,
     308                 :            :                 css::uno::TypeDescription(
     309                 :            :                     reinterpret_cast<
     310                 :            :                         typelib_InterfaceAttributeTypeDescription * >(
     311                 :          0 :                             member.get())->
     312                 :            :                     pAttributeTypeRef),
     313   [ #  #  #  # ]:          0 :                 inArguments.front());
     314                 :            :         }
     315                 :       1801 :         break;
     316                 :            :     case typelib_TypeClass_INTERFACE_METHOD:
     317                 :            :         {
     318                 :            :             typelib_InterfaceMethodTypeDescription * mtd =
     319                 :            :                 reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
     320                 :      21138 :                     member.get());
     321                 :      21138 :             std::vector< BinaryAny >::const_iterator i(inArguments.begin());
     322         [ +  + ]:      32467 :             for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
     323         [ +  + ]:      11329 :                 if (mtd->pParams[j].bIn) {
     324                 :            :                     marshal_.writeValue(
     325                 :            :                         &buf,
     326                 :      11319 :                         css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
     327 [ +  - ][ +  - ]:      11319 :                         *i++);
     328                 :            :                 }
     329                 :            :             }
     330                 :            :             OSL_ASSERT(i == inArguments.end());
     331                 :            :             break;
     332                 :            :         }
     333                 :            :     default:
     334                 :            :         OSL_ASSERT(false); // this cannot happen
     335                 :          0 :         break;
     336                 :            :     }
     337         [ +  - ]:      22939 :     sendMessage(buf);
     338         [ +  - ]:      22939 :     lastType_ = t;
     339                 :      22939 :     lastOid_ = oid;
     340                 :      22939 :     lastTid_ = tid;
     341                 :      22939 : }
     342                 :            : 
     343                 :     366862 : void Writer::sendReply(
     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)
     348                 :            : {
     349                 :            :     OSL_ASSERT(tid.getLength() != 0 && member.is() && member.get()->bComplete);
     350         [ +  - ]:     366862 :     std::vector< unsigned char > buf;
     351                 :     366862 :     bool newTid = tid != lastTid_;
     352 [ +  + ][ +  - ]:     366862 :     Marshal::write8(&buf, 0x80 | (exception ? 0x20 : 0) | (newTid ? 0x08 : 0));
                 [ +  + ]
     353                 :            :         // bit 7: LONGHEADER; bit 6: !REQUEST; bit 5: EXCEPTION; bit 3: NEWTID
     354         [ +  + ]:     366862 :     if (newTid) {
     355         [ +  - ]:       6352 :         marshal_.writeTid(&buf, tid);
     356                 :            :     }
     357         [ +  + ]:     366862 :     if (exception) {
     358                 :            :         marshal_.writeValue(
     359                 :            :             &buf,
     360                 :       1784 :             css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()),
     361         [ +  - ]:       1784 :             returnValue);
     362                 :            :     } else {
     363      [ +  +  - ]:     365078 :         switch (member.get()->eTypeClass) {
     364                 :            :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     365         [ +  + ]:       7514 :             if (!setter) {
     366                 :            :                 marshal_.writeValue(
     367                 :            :                     &buf,
     368                 :            :                     css::uno::TypeDescription(
     369                 :            :                         reinterpret_cast<
     370                 :            :                             typelib_InterfaceAttributeTypeDescription * >(
     371                 :       7032 :                                 member.get())->
     372                 :            :                         pAttributeTypeRef),
     373         [ +  - ]:       7032 :                     returnValue);
     374                 :            :             }
     375                 :       7514 :             break;
     376                 :            :         case typelib_TypeClass_INTERFACE_METHOD:
     377                 :            :             {
     378                 :            :                 typelib_InterfaceMethodTypeDescription * mtd =
     379                 :            :                     reinterpret_cast<
     380                 :            :                         typelib_InterfaceMethodTypeDescription * >(
     381                 :     357564 :                             member.get());
     382                 :            :                 marshal_.writeValue(
     383                 :            :                     &buf, css::uno::TypeDescription(mtd->pReturnTypeRef),
     384         [ +  - ]:     357564 :                     returnValue);
     385                 :            :                 std::vector< BinaryAny >::const_iterator i(
     386                 :     357564 :                     outArguments.begin());
     387         [ +  + ]:     655596 :                 for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
     388         [ +  + ]:     298032 :                     if (mtd->pParams[j].bOut) {
     389                 :            :                         marshal_.writeValue(
     390                 :            :                             &buf,
     391                 :        202 :                             css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
     392 [ +  - ][ +  - ]:        202 :                             *i++);
     393                 :            :                     }
     394                 :            :                 }
     395                 :            :                 OSL_ASSERT(i == outArguments.end());
     396                 :            :                 break;
     397                 :            :             }
     398                 :            :         default:
     399                 :            :             OSL_ASSERT(false); // this cannot happen
     400                 :          0 :             break;
     401                 :            :         }
     402                 :            :     }
     403         [ +  + ]:     366862 :     sendMessage(buf);
     404                 :     366861 :     lastTid_ = tid;
     405         [ +  - ]:     366862 :     bridge_->decrementCalls();
     406                 :     366861 : }
     407                 :            : 
     408                 :     389801 : void Writer::sendMessage(std::vector< unsigned char > const & buffer) {
     409         [ +  - ]:     389801 :     std::vector< unsigned char > header;
     410         [ -  + ]:     389801 :     if (buffer.size() > SAL_MAX_UINT32) {
     411                 :            :         throw css::uno::RuntimeException(
     412                 :            :             OUString(
     413                 :            :                 RTL_CONSTASCII_USTRINGPARAM("message too large for URP")),
     414 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
     415                 :            :     }
     416         [ +  - ]:     389801 :     Marshal::write32(&header, static_cast< sal_uInt32 >(buffer.size()));
     417         [ +  - ]:     389801 :     Marshal::write32(&header, 1);
     418                 :            :     OSL_ASSERT(!buffer.empty());
     419         [ +  - ]:     389801 :     unsigned char const * p = &buffer[0];
     420                 :     389801 :     std::vector< unsigned char >::size_type n = buffer.size();
     421                 :            :     OSL_ASSERT(header.size() <= SAL_MAX_INT32 && SAL_MAX_INT32 <= SAL_MAX_SIZE);
     422                 :     389801 :     sal_Size k = SAL_MAX_INT32 - header.size();
     423         [ +  - ]:     389801 :     if (n < k) {
     424                 :     389801 :         k = static_cast< sal_Size >(n);
     425                 :            :     }
     426                 :            :     css::uno::Sequence< sal_Int8 > s(
     427         [ +  - ]:     389801 :         static_cast< sal_Int32 >(header.size() + k));
     428                 :            :     OSL_ASSERT(!header.empty());
     429                 :            :     rtl_copyMemory(
     430 [ +  - ][ +  - ]:     389801 :         s.getArray(), &header[0], static_cast< sal_Size >(header.size()));
                 [ +  - ]
     431                 :          0 :     for (;;) {
     432 [ +  - ][ +  - ]:     389801 :         rtl_copyMemory(s.getArray() + s.getLength() - k, p, k);
     433                 :            :         try {
     434 [ +  - ][ +  - ]:     389801 :             bridge_->getConnection()->write(s);
                 [ +  + ]
     435         [ -  + ]:          2 :         } catch (const css::io::IOException & e) {
     436         [ -  + ]:          1 :             css::uno::Any exc(cppu::getCaughtException());
     437                 :            :             throw css::lang::WrappedTargetRuntimeException(
     438                 :            :                 (OUString(
     439                 :            :                     RTL_CONSTASCII_USTRINGPARAM(
     440                 :            :                         "Binary URP write raised IO exception: ")) +
     441                 :            :                  e.Message),
     442 [ -  + ][ -  + ]:          1 :                 css::uno::Reference< css::uno::XInterface >(), exc);
     443                 :            :         }
     444                 :     389800 :         n = static_cast< std::vector< unsigned char >::size_type >(n - k);
     445         [ +  - ]:     389800 :         if (n == 0) {
     446                 :     389800 :             break;
     447                 :            :         }
     448                 :          0 :         p += k;
     449                 :          0 :         k = SAL_MAX_INT32;
     450         [ #  # ]:          0 :         if (n < k) {
     451                 :          0 :             k = static_cast< sal_Size >(n);
     452                 :            :         }
     453         [ #  # ]:          0 :         s.realloc(k);
     454         [ +  - ]:     389801 :     }
     455                 :     389800 : }
     456                 :            : 
     457                 :            : }
     458                 :            : 
     459                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10