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