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 <vector> 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include "boost/noncopyable.hpp" 29cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx" 30cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 31cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx" 32cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 33cdf0e10cSrcweir #include "cppu/unotype.hxx" 34cdf0e10cSrcweir #include "osl/diagnose.h" 35cdf0e10cSrcweir #include "rtl/byteseq.hxx" 36cdf0e10cSrcweir #include "rtl/string.hxx" 37cdf0e10cSrcweir #include "rtl/textcvt.h" 38cdf0e10cSrcweir #include "rtl/textenc.h" 39cdf0e10cSrcweir #include "rtl/ustring.h" 40cdf0e10cSrcweir #include "rtl/ustring.hxx" 41cdf0e10cSrcweir #include "sal/types.h" 42cdf0e10cSrcweir #include "typelib/typeclass.h" 43cdf0e10cSrcweir #include "typelib/typedescription.h" 44cdf0e10cSrcweir #include "typelib/typedescription.hxx" 45cdf0e10cSrcweir #include "uno/dispatcher.hxx" 46cdf0e10cSrcweir 47cdf0e10cSrcweir #include "binaryany.hxx" 48cdf0e10cSrcweir #include "bridge.hxx" 49cdf0e10cSrcweir #include "cache.hxx" 50cdf0e10cSrcweir #include "lessoperators.hxx" 51cdf0e10cSrcweir #include "marshal.hxx" 52cdf0e10cSrcweir 53cdf0e10cSrcweir namespace binaryurp { 54cdf0e10cSrcweir 55cdf0e10cSrcweir namespace { 56cdf0e10cSrcweir 57cdf0e10cSrcweir namespace css = com::sun::star; 58cdf0e10cSrcweir 59cdf0e10cSrcweir void write64(std::vector< unsigned char > * buffer, sal_uInt64 value) { 60cdf0e10cSrcweir Marshal::write8(buffer, value >> 56); 61cdf0e10cSrcweir Marshal::write8(buffer, (value >> 48) & 0xFF); 62cdf0e10cSrcweir Marshal::write8(buffer, (value >> 40) & 0xFF); 63cdf0e10cSrcweir Marshal::write8(buffer, (value >> 32) & 0xFF); 64cdf0e10cSrcweir Marshal::write8(buffer, (value >> 24) & 0xFF); 65cdf0e10cSrcweir Marshal::write8(buffer, (value >> 16) & 0xFF); 66cdf0e10cSrcweir Marshal::write8(buffer, (value >> 8) & 0xFF); 67cdf0e10cSrcweir Marshal::write8(buffer, value & 0xFF); 68cdf0e10cSrcweir } 69cdf0e10cSrcweir 70cdf0e10cSrcweir void writeCompressed(std::vector< unsigned char > * buffer, sal_uInt32 value) { 71cdf0e10cSrcweir if (value < 0xFF) { 72cdf0e10cSrcweir Marshal::write8(buffer, static_cast< sal_uInt8 >(value)); 73cdf0e10cSrcweir } else { 74cdf0e10cSrcweir Marshal::write8(buffer, 0xFF); 75cdf0e10cSrcweir Marshal::write32(buffer, value); 76cdf0e10cSrcweir } 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir void writeString( 80cdf0e10cSrcweir std::vector< unsigned char > * buffer, rtl::OUString const & value) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir OSL_ASSERT(buffer != 0); 83cdf0e10cSrcweir rtl::OString v; 84cdf0e10cSrcweir if (!value.convertToString( 85cdf0e10cSrcweir &v, RTL_TEXTENCODING_UTF8, 86cdf0e10cSrcweir (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | 87cdf0e10cSrcweir RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir throw css::uno::RuntimeException( 90cdf0e10cSrcweir rtl::OUString( 91cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 92cdf0e10cSrcweir "UNO string contains invalid UTF-16 sequence")), 93cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 94cdf0e10cSrcweir } 95cdf0e10cSrcweir writeCompressed(buffer, static_cast< sal_uInt32 >(v.getLength())); 96cdf0e10cSrcweir buffer->insert(buffer->end(), v.getStr(), v.getStr() + v.getLength()); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir Marshal::Marshal(rtl::Reference< Bridge > const & bridge, WriterState & state): 102cdf0e10cSrcweir bridge_(bridge), state_(state) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir OSL_ASSERT(bridge.is()); 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 107cdf0e10cSrcweir Marshal::~Marshal() {} 108cdf0e10cSrcweir 109cdf0e10cSrcweir void Marshal::write8(std::vector< unsigned char > * buffer, sal_uInt8 value) { 110cdf0e10cSrcweir OSL_ASSERT(buffer != 0); 111cdf0e10cSrcweir buffer->push_back(value); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir void Marshal::write16(std::vector< unsigned char > * buffer, sal_uInt16 value) { 115cdf0e10cSrcweir write8(buffer, value >> 8); 116cdf0e10cSrcweir write8(buffer, value & 0xFF); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir void Marshal::write32(std::vector< unsigned char > * buffer, sal_uInt32 value) { 120cdf0e10cSrcweir write8(buffer, value >> 24); 121cdf0e10cSrcweir write8(buffer, (value >> 16) & 0xFF); 122cdf0e10cSrcweir write8(buffer, (value >> 8) & 0xFF); 123cdf0e10cSrcweir write8(buffer, value & 0xFF); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir void Marshal::writeValue( 127cdf0e10cSrcweir std::vector< unsigned char > * buffer, 128cdf0e10cSrcweir css::uno::TypeDescription const & type, BinaryAny const & value) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir OSL_ASSERT( 131cdf0e10cSrcweir type.is() && 132cdf0e10cSrcweir (type.get()->eTypeClass == typelib_TypeClass_ANY || 133cdf0e10cSrcweir value.getType().equals(type))); 134cdf0e10cSrcweir writeValue(buffer, type, value.getValue(type)); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir void Marshal::writeType( 138cdf0e10cSrcweir std::vector< unsigned char > * buffer, 139cdf0e10cSrcweir css::uno::TypeDescription const & value) 140cdf0e10cSrcweir { 141cdf0e10cSrcweir value.makeComplete(); 142cdf0e10cSrcweir OSL_ASSERT(value.is()); 143cdf0e10cSrcweir typelib_TypeClass tc = value.get()->eTypeClass; 144cdf0e10cSrcweir if (tc <= typelib_TypeClass_ANY) { 145cdf0e10cSrcweir write8(buffer, static_cast< sal_uInt8 >(tc)); 146cdf0e10cSrcweir } else { 147cdf0e10cSrcweir bool found; 148cdf0e10cSrcweir sal_uInt16 idx = state_.typeCache.add(value, &found); 149cdf0e10cSrcweir if (found) { 150cdf0e10cSrcweir write8(buffer, static_cast< sal_uInt8 >(tc)); 151cdf0e10cSrcweir write16(buffer, idx); 152cdf0e10cSrcweir } else { 153cdf0e10cSrcweir write8(buffer, static_cast< sal_uInt8 >(tc) | 0x80); 154cdf0e10cSrcweir write16(buffer, idx); 155cdf0e10cSrcweir writeString(buffer, rtl::OUString(value.get()->pTypeName)); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir } 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir void Marshal::writeOid( 161cdf0e10cSrcweir std::vector< unsigned char > * buffer, rtl::OUString const & oid) 162cdf0e10cSrcweir { 163cdf0e10cSrcweir bool found; 164cdf0e10cSrcweir sal_uInt16 idx; 165cdf0e10cSrcweir if (oid.getLength() == 0) { 166cdf0e10cSrcweir found = true; 167cdf0e10cSrcweir idx = cache::ignore; 168cdf0e10cSrcweir } else { 169cdf0e10cSrcweir idx = state_.oidCache.add(oid, &found); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir if (found) { 172cdf0e10cSrcweir write8(buffer, 0); 173cdf0e10cSrcweir } else { 174cdf0e10cSrcweir writeString(buffer, oid); 175cdf0e10cSrcweir } 176cdf0e10cSrcweir write16(buffer, idx); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir void Marshal::writeTid( 180cdf0e10cSrcweir std::vector< unsigned char > * buffer, rtl::ByteSequence const & tid) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir bool found; 183cdf0e10cSrcweir sal_uInt16 idx = state_.tidCache.add(tid, &found); 184cdf0e10cSrcweir if (found) { 185cdf0e10cSrcweir write8(buffer, 0); 186cdf0e10cSrcweir } else { 187cdf0e10cSrcweir sal_Sequence * p = tid.getHandle(); 188cdf0e10cSrcweir writeValue( 189cdf0e10cSrcweir buffer, 190cdf0e10cSrcweir css::uno::TypeDescription( 191cdf0e10cSrcweir cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()), &p); 192cdf0e10cSrcweir } 193cdf0e10cSrcweir write16(buffer, idx); 194cdf0e10cSrcweir } 195cdf0e10cSrcweir 196cdf0e10cSrcweir void Marshal::writeValue( 197cdf0e10cSrcweir std::vector< unsigned char > * buffer, 198cdf0e10cSrcweir css::uno::TypeDescription const & type, void const * value) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir OSL_ASSERT(buffer != 0 && type.is()); 201cdf0e10cSrcweir type.makeComplete(); 202cdf0e10cSrcweir switch (type.get()->eTypeClass) { 203cdf0e10cSrcweir case typelib_TypeClass_VOID: 204cdf0e10cSrcweir break; 205cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 206cdf0e10cSrcweir OSL_ASSERT(*static_cast< sal_uInt8 const * >(value) <= 1); 207cdf0e10cSrcweir // fall through 208cdf0e10cSrcweir case typelib_TypeClass_BYTE: 209cdf0e10cSrcweir write8(buffer, *static_cast< sal_uInt8 const * >(value)); 210cdf0e10cSrcweir break; 211cdf0e10cSrcweir case typelib_TypeClass_SHORT: 212cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 213cdf0e10cSrcweir case typelib_TypeClass_CHAR: 214cdf0e10cSrcweir write16(buffer, *static_cast< sal_uInt16 const * >(value)); 215cdf0e10cSrcweir break; 216cdf0e10cSrcweir case typelib_TypeClass_LONG: 217cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 218cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 219cdf0e10cSrcweir case typelib_TypeClass_ENUM: 220cdf0e10cSrcweir write32(buffer, *static_cast< sal_uInt32 const * >(value)); 221cdf0e10cSrcweir break; 222cdf0e10cSrcweir case typelib_TypeClass_HYPER: 223cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 224cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 225cdf0e10cSrcweir write64(buffer, *static_cast< sal_uInt64 const * >(value)); 226cdf0e10cSrcweir break; 227cdf0e10cSrcweir case typelib_TypeClass_STRING: 228cdf0e10cSrcweir writeString( 229cdf0e10cSrcweir buffer, 230cdf0e10cSrcweir rtl::OUString(*static_cast< rtl_uString * const * >(value))); 231cdf0e10cSrcweir break; 232cdf0e10cSrcweir case typelib_TypeClass_TYPE: 233cdf0e10cSrcweir writeType( 234cdf0e10cSrcweir buffer, 235cdf0e10cSrcweir css::uno::TypeDescription( 236cdf0e10cSrcweir *static_cast< typelib_TypeDescriptionReference * const * >( 237cdf0e10cSrcweir value))); 238cdf0e10cSrcweir break; 239cdf0e10cSrcweir case typelib_TypeClass_ANY: 240cdf0e10cSrcweir { 241cdf0e10cSrcweir uno_Any const * p = static_cast< uno_Any const * >(value); 242cdf0e10cSrcweir css::uno::TypeDescription t(p->pType); 243cdf0e10cSrcweir writeType(buffer, t); 244cdf0e10cSrcweir writeValue(buffer, t, p->pData); 245cdf0e10cSrcweir break; 246cdf0e10cSrcweir } 247cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: 248cdf0e10cSrcweir { 249cdf0e10cSrcweir sal_Sequence * p = *static_cast< sal_Sequence * const * >(value); 250cdf0e10cSrcweir writeCompressed(buffer, static_cast< sal_uInt32 >(p->nElements)); 251cdf0e10cSrcweir css::uno::TypeDescription ctd( 252cdf0e10cSrcweir reinterpret_cast< typelib_IndirectTypeDescription * >( 253cdf0e10cSrcweir type.get())-> 254cdf0e10cSrcweir pType); 255cdf0e10cSrcweir OSL_ASSERT(ctd.is()); 256cdf0e10cSrcweir if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) { 257cdf0e10cSrcweir buffer->insert( 258cdf0e10cSrcweir buffer->end(), p->elements, p->elements + p->nElements); 259cdf0e10cSrcweir } else { 260cdf0e10cSrcweir for (sal_Int32 i = 0; i != p->nElements; ++i) { 261cdf0e10cSrcweir writeValue(buffer, ctd, p->elements + i * ctd.get()->nSize); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir } 264cdf0e10cSrcweir break; 265cdf0e10cSrcweir } 266cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 267cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 268cdf0e10cSrcweir writeMemberValues(buffer, type, value); 269cdf0e10cSrcweir break; 270cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 271cdf0e10cSrcweir writeOid( 272cdf0e10cSrcweir buffer, 273cdf0e10cSrcweir bridge_->registerOutgoingInterface( 274cdf0e10cSrcweir css::uno::UnoInterfaceReference( 275cdf0e10cSrcweir *static_cast< uno_Interface * const * >(value)), 276cdf0e10cSrcweir type)); 277cdf0e10cSrcweir break; 278cdf0e10cSrcweir default: 279cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen 280cdf0e10cSrcweir break; 281cdf0e10cSrcweir } 282cdf0e10cSrcweir } 283cdf0e10cSrcweir 284cdf0e10cSrcweir void Marshal::writeMemberValues( 285cdf0e10cSrcweir std::vector< unsigned char > * buffer, 286cdf0e10cSrcweir css::uno::TypeDescription const & type, void const * aggregateValue) 287cdf0e10cSrcweir { 288cdf0e10cSrcweir OSL_ASSERT( 289cdf0e10cSrcweir type.is() && 290cdf0e10cSrcweir (type.get()->eTypeClass == typelib_TypeClass_STRUCT || 291cdf0e10cSrcweir type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) && 292cdf0e10cSrcweir aggregateValue != 0); 293cdf0e10cSrcweir type.makeComplete(); 294cdf0e10cSrcweir typelib_CompoundTypeDescription * ctd = 295cdf0e10cSrcweir reinterpret_cast< typelib_CompoundTypeDescription * >(type.get()); 296cdf0e10cSrcweir if (ctd->pBaseTypeDescription != 0) { 297cdf0e10cSrcweir writeMemberValues( 298cdf0e10cSrcweir buffer, 299cdf0e10cSrcweir css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase), 300cdf0e10cSrcweir aggregateValue); 301cdf0e10cSrcweir } 302cdf0e10cSrcweir for (sal_Int32 i = 0; i != ctd->nMembers; ++i) { 303cdf0e10cSrcweir writeValue( 304cdf0e10cSrcweir buffer, css::uno::TypeDescription(ctd->ppTypeRefs[i]), 305cdf0e10cSrcweir (static_cast< char const * >(aggregateValue) + 306cdf0e10cSrcweir ctd->pMemberOffsets[i])); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir } 311