LCOV - code coverage report
Current view: top level - binaryurp/source - incomingrequest.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 104 115 90.4 %
Date: 2015-06-13 12:38:46 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          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 <list>
      23             : #include <vector>
      24             : 
      25             : #include "com/sun/star/bridge/XInstanceProvider.hpp"
      26             : #include "cppuhelper/exc_hlp.hxx"
      27             : #include "rtl/byteseq.hxx"
      28             : #include "rtl/ref.hxx"
      29             : #include "rtl/ustring.hxx"
      30             : #include "sal/types.h"
      31             : #include "typelib/typedescription.hxx"
      32             : #include "uno/dispatcher.hxx"
      33             : 
      34             : #include "binaryany.hxx"
      35             : #include "bridge.hxx"
      36             : #include "currentcontext.hxx"
      37             : #include "incomingrequest.hxx"
      38             : #include "specialfunctionids.hxx"
      39             : 
      40             : namespace binaryurp {
      41             : 
      42      259607 : IncomingRequest::IncomingRequest(
      43             :     rtl::Reference< Bridge > const & bridge, rtl::ByteSequence const & tid,
      44             :     OUString const & oid, css::uno::UnoInterfaceReference const & object,
      45             :     css::uno::TypeDescription const & type, sal_uInt16 functionId,
      46             :     bool synchronous, css::uno::TypeDescription const & member, bool setter,
      47             :     std::vector< BinaryAny > const & inArguments, bool currentContextMode,
      48             :     css::uno::UnoInterfaceReference const & currentContext):
      49             :     bridge_(bridge), tid_(tid), oid_(oid), object_(object), type_(type),
      50             :     functionId_(functionId), synchronous_(synchronous), member_(member),
      51             :     setter_(setter), inArguments_(inArguments),
      52      259607 :     currentContextMode_(currentContextMode), currentContext_(currentContext)
      53             : {
      54             :     OSL_ASSERT(bridge.is() && member.is() && member.get()->bComplete);
      55      259607 : }
      56             : 
      57      259605 : IncomingRequest::~IncomingRequest() {}
      58             : 
      59      259563 : void IncomingRequest::execute() const {
      60      259563 :     BinaryAny ret;
      61      311872 :     std::vector< BinaryAny > outArgs;
      62             :     bool isExc;
      63             :     try {
      64      259560 :         bool resetCc = false;
      65      259560 :         css::uno::UnoInterfaceReference oldCc;
      66      259568 :         if (currentContextMode_) {
      67      207338 :             oldCc = current_context::get();
      68      207341 :             current_context::set(currentContext_);
      69      207341 :             resetCc = true;
      70             :         }
      71             :         try {
      72             :             try {
      73      259571 :                 isExc = !execute_throw(&ret, &outArgs);
      74           0 :             } catch (const std::exception & e) {
      75             :                 throw css::uno::RuntimeException(
      76           0 :                     "caught C++ exception: " +
      77             :                     OStringToOUString(
      78           0 :                          OString(e.what()), RTL_TEXTENCODING_ASCII_US));
      79             :                     // best-effort string conversion
      80             :             }
      81          30 :         } catch (const css::uno::RuntimeException &) {
      82          30 :             css::uno::Any exc(cppu::getCaughtException());
      83          30 :             ret = bridge_->mapCppToBinaryAny(exc);
      84          30 :             isExc = true;
      85             :         }
      86      259606 :         if (resetCc) {
      87      207341 :             current_context::set(oldCc);
      88      259606 :         }
      89           0 :     } catch (const css::uno::RuntimeException &) {
      90           0 :         css::uno::Any exc(cppu::getCaughtException());
      91           0 :         ret = bridge_->mapCppToBinaryAny(exc);
      92           0 :         isExc = true;
      93             :     }
      94      259607 :     if (synchronous_) {
      95      207341 :         bridge_->decrementActiveCalls();
      96             :         try {
      97             :             bridge_->getWriter()->queueReply(
      98      207341 :                 tid_, member_, setter_, isExc, ret, outArgs, false);
      99      466946 :             return;
     100           2 :         } catch (const css::uno::RuntimeException & e) {
     101             :             OSL_TRACE(
     102             :                 "caught UNO runtime exception '%s'",
     103             :                 (OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).
     104             :                  getStr()));
     105           0 :         } catch (const std::exception & e) {
     106             :             OSL_TRACE("caught C++ exception '%s'", e.what());
     107             :         }
     108           2 :         bridge_->terminate(false);
     109             :     } else {
     110             :         if (isExc) {
     111             :             OSL_TRACE("oneway method raised exception");
     112             :         }
     113       52266 :         bridge_->decrementCalls();
     114       52268 :     }
     115             : }
     116             : 
     117      207112 : static size_t size_t_round(size_t val)
     118             : {
     119      207112 :     return (val + (sizeof(size_t)-1)) & ~(sizeof(size_t)-1);
     120             : }
     121             : 
     122      259603 : bool IncomingRequest::execute_throw(
     123             :     BinaryAny * returnValue, std::vector< BinaryAny > * outArguments) const
     124             : {
     125             :     OSL_ASSERT(
     126             :         returnValue != 0 &&
     127             :         returnValue->getType().equals(
     128             :             css::uno::TypeDescription(cppu::UnoType<void>::get())) &&
     129             :         outArguments != 0 && outArguments->empty());
     130      259603 :     bool isExc = false;
     131      259603 :     switch (functionId_) {
     132             :     case SPECIAL_FUNCTION_ID_RESERVED:
     133             :         OSL_ASSERT(false); // this cannot happen
     134           0 :         break;
     135             :     case SPECIAL_FUNCTION_ID_RELEASE:
     136       52266 :         bridge_->releaseStub(oid_, type_);
     137       52236 :         break;
     138             :     case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
     139       21832 :         if (!object_.is()) {
     140          96 :             css::uno::Reference< css::uno::XInterface > ifc;
     141             :             css::uno::Reference< css::bridge::XInstanceProvider > prov(
     142         192 :                 bridge_->getProvider());
     143          96 :             if (prov.is()) {
     144             :                 try {
     145          96 :                     ifc = prov->getInstance(oid_);
     146           0 :                 } catch (const css::container::NoSuchElementException & e) {
     147             :                     OSL_TRACE(
     148             :                         "initial element '%s': NoSuchElementException '%s'",
     149             :                         OUStringToOString(oid_, RTL_TEXTENCODING_UTF8).getStr(),
     150             :                         (OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).
     151             :                          getStr()));
     152             :                 }
     153             :             }
     154          96 :             if (ifc.is()) {
     155             :                 css::uno::UnoInterfaceReference unoIfc(
     156             :                     static_cast< uno_Interface * >(
     157          96 :                         bridge_->getCppToBinaryMapping().mapInterface(
     158          96 :                             ifc.get(),
     159             :                             (css::uno::TypeDescription(
     160             :                                 cppu::UnoType<
     161             :                                     css::uno::Reference<
     162          96 :                                         css::uno::XInterface > >::get()).
     163         288 :                              get()))),
     164          96 :                     SAL_NO_ACQUIRE);
     165         192 :                 *returnValue = BinaryAny(
     166             :                     css::uno::TypeDescription(
     167             :                         cppu::UnoType<
     168             :                             css::uno::Reference<
     169          96 :                                 css::uno::XInterface > >::get()),
     170         192 :                     &unoIfc.m_pUnoI);
     171             :             }
     172         192 :             break;
     173             :         }
     174             :         // fall through
     175             :     default:
     176             :         {
     177             :             OSL_ASSERT(object_.is());
     178      207242 :             css::uno::TypeDescription retType;
     179      414490 :             std::list< std::vector< char > > outBufs;
     180      414489 :             std::vector< void * > args;
     181      207244 :             switch (member_.get()->eTypeClass) {
     182             :             case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     183             :                 {
     184             :                     css::uno::TypeDescription t(
     185             :                         reinterpret_cast<
     186             :                             typelib_InterfaceAttributeTypeDescription * >(
     187        3966 :                                 member_.get())->
     188        3966 :                         pAttributeTypeRef);
     189        3966 :                     if (setter_) {
     190             :                         OSL_ASSERT(inArguments_.size() == 1);
     191         186 :                         args.push_back(inArguments_[0].getValue(t));
     192             :                     } else {
     193             :                         OSL_ASSERT(inArguments_.empty());
     194        3780 :                         retType = t;
     195             :                     }
     196        3966 :                     break;
     197             :                 }
     198             :             case typelib_TypeClass_INTERFACE_METHOD:
     199             :                 {
     200             :                     typelib_InterfaceMethodTypeDescription * mtd =
     201             :                         reinterpret_cast<
     202             :                             typelib_InterfaceMethodTypeDescription * >(
     203      203277 :                                 member_.get());
     204      203276 :                     retType = css::uno::TypeDescription(mtd->pReturnTypeRef);
     205             :                     std::vector< BinaryAny >::const_iterator i(
     206      203279 :                         inArguments_.begin());
     207      365069 :                     for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
     208             :                         void * p;
     209      161792 :                         if (mtd->pParams[j].bIn) {
     210             :                             p = i++->getValue(
     211             :                                 css::uno::TypeDescription(
     212      161738 :                                     mtd->pParams[j].pTypeRef));
     213             :                         } else {
     214             :                             outBufs.push_back(
     215             :                                 std::vector< char >(size_t_round(
     216             :                                     css::uno::TypeDescription(
     217          54 :                                         mtd->pParams[j].pTypeRef).
     218         108 :                                     get()->nSize)));
     219          54 :                             p = &outBufs.back()[0];
     220             :                         }
     221      161792 :                         args.push_back(p);
     222      161792 :                         if (mtd->pParams[j].bOut) {
     223         101 :                             outArguments->push_back(BinaryAny());
     224             :                         }
     225             :                     }
     226             :                     OSL_ASSERT(i == inArguments_.end());
     227      203277 :                     break;
     228             :                 }
     229             :             default:
     230             :                 OSL_ASSERT(false); // this cannot happen
     231           0 :                 break;
     232             :             }
     233      207243 :             size_t nSize = 0;
     234      207243 :             if (retType.is())
     235      207058 :                 nSize = size_t_round(retType.get()->nSize);
     236      207244 :             std::vector< char > retBuf(nSize);
     237             :             uno_Any exc;
     238      207245 :             uno_Any * pexc = &exc;
     239      207245 :             (*object_.get()->pDispatcher)(
     240      414488 :                 object_.get(), member_.get(), retBuf.empty() ? 0 : &retBuf[0],
     241      621734 :                 args.empty() ? 0 : &args[0], &pexc);
     242      207245 :             isExc = pexc != 0;
     243      207245 :             if (isExc) {
     244        1874 :                 *returnValue = BinaryAny(
     245             :                     css::uno::TypeDescription(
     246         937 :                         cppu::UnoType< css::uno::Any >::get()),
     247         937 :                     &exc);
     248         937 :                 uno_any_destruct(&exc, 0);
     249             :             } else {
     250      206308 :                 if (!retBuf.empty()) {
     251      174125 :                     *returnValue = BinaryAny(retType, &retBuf[0]);
     252      174125 :                     uno_destructData(&retBuf[0], retType.get(), 0);
     253             :                 }
     254      206308 :                 if (!outArguments->empty()) {
     255             :                     OSL_ASSERT(
     256             :                         member_.get()->eTypeClass ==
     257             :                         typelib_TypeClass_INTERFACE_METHOD);
     258             :                     typelib_InterfaceMethodTypeDescription * mtd =
     259             :                         reinterpret_cast<
     260             :                             typelib_InterfaceMethodTypeDescription * >(
     261          82 :                                 member_.get());
     262          82 :                     std::vector< BinaryAny >::iterator i(outArguments->begin());
     263             :                     std::list< std::vector< char > >::iterator j(
     264          82 :                         outBufs.begin());
     265         199 :                     for (sal_Int32 k = 0; k != mtd->nParams; ++k) {
     266         117 :                         if (mtd->pParams[k].bOut) {
     267         303 :                             *i++ = BinaryAny(
     268             :                                 css::uno::TypeDescription(
     269         101 :                                     mtd->pParams[k].pTypeRef),
     270         202 :                                 args[k]);
     271             :                         }
     272         117 :                         if (!mtd->pParams[k].bIn) {
     273             :                             uno_type_destructData(
     274          54 :                                 &(*j++)[0], mtd->pParams[k].pTypeRef, 0);
     275             :                         }
     276             :                     }
     277             :                     OSL_ASSERT(i == outArguments->end());
     278             :                     OSL_ASSERT(j == outBufs.end());
     279             :                 }
     280             :             }
     281      414490 :             break;
     282             :         }
     283             :     }
     284      259576 :     return !isExc;
     285             : }
     286             : 
     287             : }
     288             : 
     289             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11