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