1*37adc4f0SAndrew Rist /************************************************************** 2*37adc4f0SAndrew Rist * 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 10*37adc4f0SAndrew Rist * 11*37adc4f0SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*37adc4f0SAndrew Rist * 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. 19*37adc4f0SAndrew Rist * 20*37adc4f0SAndrew Rist *************************************************************/ 21*37adc4f0SAndrew Rist 22*37adc4f0SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "sal/config.h" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <cstdlib> 27cdf0e10cSrcweir #include <new> 28cdf0e10cSrcweir #include <vector> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include "boost/noncopyable.hpp" 31cdf0e10cSrcweir #include "com/sun/star/io/IOException.hpp" 32cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx" 33cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 34cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx" 35cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 36cdf0e10cSrcweir #include "cppu/unotype.hxx" 37cdf0e10cSrcweir #include "osl/diagnose.h" 38cdf0e10cSrcweir #include "rtl/byteseq.hxx" 39cdf0e10cSrcweir #include "rtl/ref.hxx" 40cdf0e10cSrcweir #include "rtl/textcvt.h" 41cdf0e10cSrcweir #include "rtl/textenc.h" 42cdf0e10cSrcweir #include "rtl/ustring.h" 43cdf0e10cSrcweir #include "rtl/ustring.hxx" 44cdf0e10cSrcweir #include "sal/types.h" 45cdf0e10cSrcweir #include "typelib/typeclass.h" 46cdf0e10cSrcweir #include "typelib/typedescription.h" 47cdf0e10cSrcweir #include "typelib/typedescription.hxx" 48cdf0e10cSrcweir #include "uno/any2.h" 49cdf0e10cSrcweir #include "uno/data.h" 50cdf0e10cSrcweir #include "uno/dispatcher.hxx" 51cdf0e10cSrcweir 52cdf0e10cSrcweir #include "binaryany.hxx" 53cdf0e10cSrcweir #include "bridge.hxx" 54cdf0e10cSrcweir #include "cache.hxx" 55cdf0e10cSrcweir #include "readerstate.hxx" 56cdf0e10cSrcweir #include "unmarshal.hxx" 57cdf0e10cSrcweir 58cdf0e10cSrcweir namespace binaryurp { 59cdf0e10cSrcweir 60cdf0e10cSrcweir namespace { 61cdf0e10cSrcweir 62cdf0e10cSrcweir namespace css = com::sun::star; 63cdf0e10cSrcweir 64cdf0e10cSrcweir void * allocate(sal_Size size) { 65cdf0e10cSrcweir void * p = rtl_allocateMemory(size); 66cdf0e10cSrcweir if (p == 0) { 67cdf0e10cSrcweir throw std::bad_alloc(); 68cdf0e10cSrcweir } 69cdf0e10cSrcweir return p; 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir std::vector< BinaryAny >::iterator copyMemberValues( 73cdf0e10cSrcweir css::uno::TypeDescription const & type, 74cdf0e10cSrcweir std::vector< BinaryAny >::iterator const & it, void * buffer) throw () 75cdf0e10cSrcweir { 76cdf0e10cSrcweir OSL_ASSERT( 77cdf0e10cSrcweir type.is() && 78cdf0e10cSrcweir (type.get()->eTypeClass == typelib_TypeClass_STRUCT || 79cdf0e10cSrcweir type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) && 80cdf0e10cSrcweir buffer != 0); 81cdf0e10cSrcweir type.makeComplete(); 82cdf0e10cSrcweir std::vector< BinaryAny >::iterator i(it); 83cdf0e10cSrcweir typelib_CompoundTypeDescription * ctd = 84cdf0e10cSrcweir reinterpret_cast< typelib_CompoundTypeDescription * >(type.get()); 85cdf0e10cSrcweir if (ctd->pBaseTypeDescription != 0) { 86cdf0e10cSrcweir i = copyMemberValues( 87cdf0e10cSrcweir css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase), i, 88cdf0e10cSrcweir buffer); 89cdf0e10cSrcweir } 90cdf0e10cSrcweir for (sal_Int32 j = 0; j != ctd->nMembers; ++j) { 91cdf0e10cSrcweir uno_type_copyData( 92cdf0e10cSrcweir static_cast< char * >(buffer) + ctd->pMemberOffsets[j], 93cdf0e10cSrcweir const_cast< void * >( 94cdf0e10cSrcweir i++->getValue(css::uno::TypeDescription(ctd->ppTypeRefs[j]))), 95cdf0e10cSrcweir ctd->ppTypeRefs[j], 0); 96cdf0e10cSrcweir } 97cdf0e10cSrcweir return i; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir Unmarshal::Unmarshal( 103cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, ReaderState & state, 104cdf0e10cSrcweir css::uno::Sequence< sal_Int8 > const & buffer): 105cdf0e10cSrcweir bridge_(bridge), state_(state), buffer_(buffer) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir data_ = reinterpret_cast< sal_uInt8 const * >(buffer_.getConstArray()); 108cdf0e10cSrcweir end_ = data_ + buffer_.getLength(); 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir Unmarshal::~Unmarshal() {} 112cdf0e10cSrcweir 113cdf0e10cSrcweir sal_uInt8 Unmarshal::read8() { 114cdf0e10cSrcweir check(1); 115cdf0e10cSrcweir return *data_++; 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir sal_uInt16 Unmarshal::read16() { 119cdf0e10cSrcweir check(2); 120cdf0e10cSrcweir sal_uInt16 n = static_cast< sal_uInt16 >(*data_++) << 8; 121cdf0e10cSrcweir return n | *data_++; 122cdf0e10cSrcweir } 123cdf0e10cSrcweir 124cdf0e10cSrcweir sal_uInt32 Unmarshal::read32() { 125cdf0e10cSrcweir check(4); 126cdf0e10cSrcweir sal_uInt32 n = static_cast< sal_uInt32 >(*data_++) << 24; 127cdf0e10cSrcweir n |= static_cast< sal_uInt32 >(*data_++) << 16; 128cdf0e10cSrcweir n |= static_cast< sal_uInt32 >(*data_++) << 8; 129cdf0e10cSrcweir return n | *data_++; 130cdf0e10cSrcweir } 131cdf0e10cSrcweir 132cdf0e10cSrcweir css::uno::TypeDescription Unmarshal::readType() { 133cdf0e10cSrcweir sal_uInt8 flags = read8(); 134cdf0e10cSrcweir typelib_TypeClass tc = static_cast< typelib_TypeClass >(flags & 0x7F); 135cdf0e10cSrcweir switch (tc) { 136cdf0e10cSrcweir case typelib_TypeClass_VOID: 137cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 138cdf0e10cSrcweir case typelib_TypeClass_BYTE: 139cdf0e10cSrcweir case typelib_TypeClass_SHORT: 140cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 141cdf0e10cSrcweir case typelib_TypeClass_LONG: 142cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 143cdf0e10cSrcweir case typelib_TypeClass_HYPER: 144cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 145cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 146cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 147cdf0e10cSrcweir case typelib_TypeClass_CHAR: 148cdf0e10cSrcweir case typelib_TypeClass_STRING: 149cdf0e10cSrcweir case typelib_TypeClass_TYPE: 150cdf0e10cSrcweir case typelib_TypeClass_ANY: 151cdf0e10cSrcweir if ((flags & 0x80) != 0) { 152cdf0e10cSrcweir throw css::io::IOException( 153cdf0e10cSrcweir rtl::OUString( 154cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 155cdf0e10cSrcweir "binaryurp::Unmarshal: cache flag of simple type is" 156cdf0e10cSrcweir " set")), 157cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir return css::uno::TypeDescription( 160cdf0e10cSrcweir *typelib_static_type_getByTypeClass( 161cdf0e10cSrcweir static_cast< typelib_TypeClass >(tc))); 162cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: 163cdf0e10cSrcweir case typelib_TypeClass_ENUM: 164cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 165cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 166cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 167cdf0e10cSrcweir { 168cdf0e10cSrcweir sal_uInt16 idx = readCacheIndex(); 169cdf0e10cSrcweir if ((flags & 0x80) == 0) { 170cdf0e10cSrcweir if (idx == cache::ignore || !state_.typeCache[idx].is()) { 171cdf0e10cSrcweir throw css::io::IOException( 172cdf0e10cSrcweir rtl::OUString( 173cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 174cdf0e10cSrcweir "binaryurp::Unmarshal: unknown type cache" 175cdf0e10cSrcweir " index")), 176cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir return state_.typeCache[idx]; 179cdf0e10cSrcweir } else { 180cdf0e10cSrcweir css::uno::TypeDescription t(readString()); 181cdf0e10cSrcweir if (!t.is() || 182cdf0e10cSrcweir t.get()->eTypeClass != static_cast< typelib_TypeClass >(tc)) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir throw css::io::IOException( 185cdf0e10cSrcweir rtl::OUString( 186cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 187cdf0e10cSrcweir "binaryurp::Unmarshal: type with unknown" 188cdf0e10cSrcweir " name")), 189cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir for (css::uno::TypeDescription t2(t); 192cdf0e10cSrcweir t2.get()->eTypeClass == typelib_TypeClass_SEQUENCE;) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir t2.makeComplete(); 195cdf0e10cSrcweir t2 = css::uno::TypeDescription( 196cdf0e10cSrcweir reinterpret_cast< typelib_IndirectTypeDescription * >( 197cdf0e10cSrcweir t2.get())->pType); 198cdf0e10cSrcweir if (!t2.is()) { 199cdf0e10cSrcweir throw css::io::IOException( 200cdf0e10cSrcweir rtl::OUString( 201cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 202cdf0e10cSrcweir "binaryurp::Unmarshal: sequence type with" 203cdf0e10cSrcweir " unknown component type")), 204cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir switch (t2.get()->eTypeClass) { 207cdf0e10cSrcweir case typelib_TypeClass_VOID: 208cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 209cdf0e10cSrcweir throw css::io::IOException( 210cdf0e10cSrcweir rtl::OUString( 211cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 212cdf0e10cSrcweir "binaryurp::Unmarshal: sequence type with" 213cdf0e10cSrcweir " bad component type")), 214cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 215cdf0e10cSrcweir default: 216cdf0e10cSrcweir break; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir } 219cdf0e10cSrcweir if (idx != cache::ignore) { 220cdf0e10cSrcweir state_.typeCache[idx] = t; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir return t; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir } 225cdf0e10cSrcweir default: 226cdf0e10cSrcweir throw css::io::IOException( 227cdf0e10cSrcweir rtl::OUString( 228cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 229cdf0e10cSrcweir "binaryurp::Unmarshal: type of unknown type class")), 230cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 231cdf0e10cSrcweir } 232cdf0e10cSrcweir } 233cdf0e10cSrcweir 234cdf0e10cSrcweir rtl::OUString Unmarshal::readOid() { 235cdf0e10cSrcweir rtl::OUString oid(readString()); 236cdf0e10cSrcweir for (sal_Int32 i = 0; i != oid.getLength(); ++i) { 237cdf0e10cSrcweir if (oid[i] > 0x7F) { 238cdf0e10cSrcweir throw css::io::IOException( 239cdf0e10cSrcweir rtl::OUString( 240cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 241cdf0e10cSrcweir "binaryurp::Unmarshal: OID contains non-ASCII" 242cdf0e10cSrcweir " character")), 243cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir } 246cdf0e10cSrcweir sal_uInt16 idx = readCacheIndex(); 247cdf0e10cSrcweir if (oid.getLength() == 0 && idx != cache::ignore) { 248cdf0e10cSrcweir if (state_.oidCache[idx].getLength() == 0) { 249cdf0e10cSrcweir throw css::io::IOException( 250cdf0e10cSrcweir rtl::OUString( 251cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 252cdf0e10cSrcweir "binaryurp::Unmarshal: unknown OID cache index")), 253cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 254cdf0e10cSrcweir } 255cdf0e10cSrcweir return state_.oidCache[idx]; 256cdf0e10cSrcweir } 257cdf0e10cSrcweir if (idx != cache::ignore) { 258cdf0e10cSrcweir state_.oidCache[idx] = oid; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir return oid; 261cdf0e10cSrcweir } 262cdf0e10cSrcweir 263cdf0e10cSrcweir rtl::ByteSequence Unmarshal::readTid() { 264cdf0e10cSrcweir rtl::ByteSequence tid( 265cdf0e10cSrcweir *static_cast< sal_Sequence * const * >( 266cdf0e10cSrcweir readSequence( 267cdf0e10cSrcweir css::uno::TypeDescription( 268cdf0e10cSrcweir cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get())). 269cdf0e10cSrcweir getValue( 270cdf0e10cSrcweir css::uno::TypeDescription( 271cdf0e10cSrcweir cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get())))); 272cdf0e10cSrcweir sal_uInt16 idx = readCacheIndex(); 273cdf0e10cSrcweir if (tid.getLength() == 0) { 274cdf0e10cSrcweir if (idx == cache::ignore || state_.tidCache[idx].getLength() == 0) { 275cdf0e10cSrcweir throw css::io::IOException( 276cdf0e10cSrcweir rtl::OUString( 277cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 278cdf0e10cSrcweir "binaryurp::Unmarshal: unknown TID cache index")), 279cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 280cdf0e10cSrcweir } 281cdf0e10cSrcweir return state_.tidCache[idx]; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir if (idx != cache::ignore) { 284cdf0e10cSrcweir state_.tidCache[idx] = tid; 285cdf0e10cSrcweir } 286cdf0e10cSrcweir return tid; 287cdf0e10cSrcweir } 288cdf0e10cSrcweir 289cdf0e10cSrcweir BinaryAny Unmarshal::readValue(css::uno::TypeDescription const & type) { 290cdf0e10cSrcweir OSL_ASSERT(type.is()); 291cdf0e10cSrcweir switch (type.get()->eTypeClass) { 292cdf0e10cSrcweir default: 293cdf0e10cSrcweir std::abort(); // this cannot happen 294cdf0e10cSrcweir // pseudo fall-through to avoid compiler warnings 295cdf0e10cSrcweir case typelib_TypeClass_VOID: 296cdf0e10cSrcweir return BinaryAny(); 297cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 298cdf0e10cSrcweir { 299cdf0e10cSrcweir sal_uInt8 v = read8(); 300cdf0e10cSrcweir if (v > 1) { 301cdf0e10cSrcweir throw css::io::IOException( 302cdf0e10cSrcweir rtl::OUString( 303cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 304cdf0e10cSrcweir "binaryurp::Unmarshal: boolean of unknown value")), 305cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 306cdf0e10cSrcweir } 307cdf0e10cSrcweir return BinaryAny(type, &v); 308cdf0e10cSrcweir } 309cdf0e10cSrcweir case typelib_TypeClass_BYTE: 310cdf0e10cSrcweir { 311cdf0e10cSrcweir sal_uInt8 v = read8(); 312cdf0e10cSrcweir return BinaryAny(type, &v); 313cdf0e10cSrcweir } 314cdf0e10cSrcweir case typelib_TypeClass_SHORT: 315cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 316cdf0e10cSrcweir case typelib_TypeClass_CHAR: 317cdf0e10cSrcweir { 318cdf0e10cSrcweir sal_uInt16 v = read16(); 319cdf0e10cSrcweir return BinaryAny(type, &v); 320cdf0e10cSrcweir } 321cdf0e10cSrcweir case typelib_TypeClass_LONG: 322cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 323cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 324cdf0e10cSrcweir { 325cdf0e10cSrcweir sal_uInt32 v = read32(); 326cdf0e10cSrcweir return BinaryAny(type, &v); 327cdf0e10cSrcweir } 328cdf0e10cSrcweir case typelib_TypeClass_HYPER: 329cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 330cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 331cdf0e10cSrcweir { 332cdf0e10cSrcweir sal_uInt64 v = read64(); 333cdf0e10cSrcweir return BinaryAny(type, &v); 334cdf0e10cSrcweir } 335cdf0e10cSrcweir case typelib_TypeClass_STRING: 336cdf0e10cSrcweir { 337cdf0e10cSrcweir rtl::OUString v(readString()); 338cdf0e10cSrcweir return BinaryAny(type, &v.pData); 339cdf0e10cSrcweir } 340cdf0e10cSrcweir case typelib_TypeClass_TYPE: 341cdf0e10cSrcweir { 342cdf0e10cSrcweir css::uno::TypeDescription v(readType()); 343cdf0e10cSrcweir typelib_TypeDescription * p = v.get(); 344cdf0e10cSrcweir return BinaryAny(type, &p); 345cdf0e10cSrcweir } 346cdf0e10cSrcweir case typelib_TypeClass_ANY: 347cdf0e10cSrcweir { 348cdf0e10cSrcweir css::uno::TypeDescription t(readType()); 349cdf0e10cSrcweir if (t.get()->eTypeClass == typelib_TypeClass_ANY) { 350cdf0e10cSrcweir throw css::io::IOException( 351cdf0e10cSrcweir rtl::OUString( 352cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 353cdf0e10cSrcweir "binaryurp::Unmarshal: any of type ANY")), 354cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 355cdf0e10cSrcweir } 356cdf0e10cSrcweir return readValue(t); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: 359cdf0e10cSrcweir type.makeComplete(); 360cdf0e10cSrcweir return readSequence(type); 361cdf0e10cSrcweir case typelib_TypeClass_ENUM: 362cdf0e10cSrcweir { 363cdf0e10cSrcweir sal_Int32 v = static_cast< sal_Int32 >(read32()); 364cdf0e10cSrcweir type.makeComplete(); 365cdf0e10cSrcweir typelib_EnumTypeDescription * etd = 366cdf0e10cSrcweir reinterpret_cast< typelib_EnumTypeDescription * >(type.get()); 367cdf0e10cSrcweir bool found = false; 368cdf0e10cSrcweir for (sal_Int32 i = 0; i != etd->nEnumValues; ++i) { 369cdf0e10cSrcweir if (etd->pEnumValues[i] == v) { 370cdf0e10cSrcweir found = true; 371cdf0e10cSrcweir break; 372cdf0e10cSrcweir } 373cdf0e10cSrcweir } 374cdf0e10cSrcweir if (!found) { 375cdf0e10cSrcweir throw css::io::IOException( 376cdf0e10cSrcweir rtl::OUString( 377cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 378cdf0e10cSrcweir "binaryurp::Unmarshal: unknown enum value")), 379cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 380cdf0e10cSrcweir } 381cdf0e10cSrcweir return BinaryAny(type, &v); 382cdf0e10cSrcweir } 383cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 384cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 385cdf0e10cSrcweir { 386cdf0e10cSrcweir std::vector< BinaryAny > as; 387cdf0e10cSrcweir readMemberValues(type, &as); 388cdf0e10cSrcweir void * buf = allocate(type.get()->nSize); 389cdf0e10cSrcweir copyMemberValues(type, as.begin(), buf); 390cdf0e10cSrcweir uno_Any raw; 391cdf0e10cSrcweir raw.pType = reinterpret_cast< typelib_TypeDescriptionReference * >( 392cdf0e10cSrcweir type.get()); 393cdf0e10cSrcweir raw.pData = buf; 394cdf0e10cSrcweir raw.pReserved = 0; 395cdf0e10cSrcweir return BinaryAny(raw); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 398cdf0e10cSrcweir { 399cdf0e10cSrcweir css::uno::UnoInterfaceReference obj( 400cdf0e10cSrcweir bridge_->registerIncomingInterface(readOid(), type)); 401cdf0e10cSrcweir return BinaryAny(type, &obj.m_pUnoI); 402cdf0e10cSrcweir } 403cdf0e10cSrcweir } 404cdf0e10cSrcweir } 405cdf0e10cSrcweir 406cdf0e10cSrcweir void Unmarshal::done() const { 407cdf0e10cSrcweir if (data_ != end_) { 408cdf0e10cSrcweir throw css::io::IOException( 409cdf0e10cSrcweir rtl::OUString( 410cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 411cdf0e10cSrcweir "binaryurp::Unmarshal: block contains excess data")), 412cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 413cdf0e10cSrcweir } 414cdf0e10cSrcweir } 415cdf0e10cSrcweir 416cdf0e10cSrcweir void Unmarshal::check(sal_Int32 size) const { 417cdf0e10cSrcweir if (end_ - data_ < size) { 418cdf0e10cSrcweir throw css::io::IOException( 419cdf0e10cSrcweir rtl::OUString( 420cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 421cdf0e10cSrcweir "binaryurp::Unmarshal: trying to read past end of block")), 422cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 423cdf0e10cSrcweir } 424cdf0e10cSrcweir } 425cdf0e10cSrcweir 426cdf0e10cSrcweir sal_uInt32 Unmarshal::readCompressed() { 427cdf0e10cSrcweir sal_uInt8 n = read8(); 428cdf0e10cSrcweir return n == 0xFF ? read32() : n; 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir sal_uInt16 Unmarshal::readCacheIndex() { 432cdf0e10cSrcweir sal_uInt16 idx = read16(); 433cdf0e10cSrcweir if (idx >= cache::size && idx != cache::ignore) { 434cdf0e10cSrcweir throw css::io::IOException( 435cdf0e10cSrcweir rtl::OUString( 436cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 437cdf0e10cSrcweir "binaryurp::Unmarshal: cache index out of range")), 438cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 439cdf0e10cSrcweir } 440cdf0e10cSrcweir return idx; 441cdf0e10cSrcweir } 442cdf0e10cSrcweir 443cdf0e10cSrcweir sal_uInt64 Unmarshal::read64() { 444cdf0e10cSrcweir check(8); 445cdf0e10cSrcweir sal_uInt64 n = static_cast< sal_uInt64 >(*data_++) << 56; 446cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 48; 447cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 40; 448cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 32; 449cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 24; 450cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 16; 451cdf0e10cSrcweir n |= static_cast< sal_uInt64 >(*data_++) << 8; 452cdf0e10cSrcweir return n | *data_++; 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir rtl::OUString Unmarshal::readString() { 456cdf0e10cSrcweir sal_uInt32 n = readCompressed(); 457cdf0e10cSrcweir if (n > SAL_MAX_INT32) { 458cdf0e10cSrcweir throw css::uno::RuntimeException( 459cdf0e10cSrcweir rtl::OUString( 460cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 461cdf0e10cSrcweir "binaryurp::Unmarshal: string size too large")), 462cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 463cdf0e10cSrcweir } 464cdf0e10cSrcweir check(static_cast< sal_Int32 >(n)); 465cdf0e10cSrcweir rtl::OUString s; 466cdf0e10cSrcweir if (!rtl_convertStringToUString( 467cdf0e10cSrcweir &s.pData, reinterpret_cast< char const * >(data_), 468cdf0e10cSrcweir static_cast< sal_Int32 >(n), RTL_TEXTENCODING_UTF8, 469cdf0e10cSrcweir (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | 470cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | 471cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) 472cdf0e10cSrcweir { 473cdf0e10cSrcweir throw css::io::IOException( 474cdf0e10cSrcweir rtl::OUString( 475cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 476cdf0e10cSrcweir "binaryurp::Unmarshal: string does not contain UTF-8")), 477cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 478cdf0e10cSrcweir } 479cdf0e10cSrcweir data_ += n; 480cdf0e10cSrcweir return s; 481cdf0e10cSrcweir } 482cdf0e10cSrcweir 483cdf0e10cSrcweir BinaryAny Unmarshal::readSequence(css::uno::TypeDescription const & type) { 484cdf0e10cSrcweir OSL_ASSERT( 485cdf0e10cSrcweir type.is() && type.get()->eTypeClass == typelib_TypeClass_SEQUENCE); 486cdf0e10cSrcweir sal_uInt32 n = readCompressed(); 487cdf0e10cSrcweir if (n > SAL_MAX_INT32) { 488cdf0e10cSrcweir throw css::uno::RuntimeException( 489cdf0e10cSrcweir rtl::OUString( 490cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 491cdf0e10cSrcweir "binaryurp::Unmarshal: sequence size too large")), 492cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 493cdf0e10cSrcweir } 494cdf0e10cSrcweir if (n == 0) { 495cdf0e10cSrcweir return BinaryAny(type, 0); 496cdf0e10cSrcweir } 497cdf0e10cSrcweir css::uno::TypeDescription ctd( 498cdf0e10cSrcweir reinterpret_cast< typelib_IndirectTypeDescription * >( 499cdf0e10cSrcweir type.get())->pType); 500cdf0e10cSrcweir if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) { 501cdf0e10cSrcweir check(static_cast< sal_Int32 >(n)); 502cdf0e10cSrcweir rtl::ByteSequence s( 503cdf0e10cSrcweir reinterpret_cast< sal_Int8 const * >(data_), 504cdf0e10cSrcweir static_cast< sal_Int32 >(n)); 505cdf0e10cSrcweir data_ += n; 506cdf0e10cSrcweir sal_Sequence * p = s.getHandle(); 507cdf0e10cSrcweir return BinaryAny(type, &p); 508cdf0e10cSrcweir } 509cdf0e10cSrcweir std::vector< BinaryAny > as; 510cdf0e10cSrcweir for (sal_uInt32 i = 0; i != n; ++i) { 511cdf0e10cSrcweir as.push_back(readValue(ctd)); 512cdf0e10cSrcweir } 513cdf0e10cSrcweir OSL_ASSERT(ctd.get()->nSize >= 0); 514cdf0e10cSrcweir sal_uInt64 size = static_cast< sal_uInt64 >(n) * 515cdf0e10cSrcweir static_cast< sal_uInt64 >(ctd.get()->nSize); 516cdf0e10cSrcweir // sal_uInt32 * sal_Int32 -> sal_uInt64 cannot overflow 517cdf0e10cSrcweir if (size > SAL_MAX_SIZE - SAL_SEQUENCE_HEADER_SIZE) { 518cdf0e10cSrcweir throw css::uno::RuntimeException( 519cdf0e10cSrcweir rtl::OUString( 520cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 521cdf0e10cSrcweir "binaryurp::Unmarshal: sequence size too large")), 522cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 523cdf0e10cSrcweir } 524cdf0e10cSrcweir void * buf = allocate( 525cdf0e10cSrcweir SAL_SEQUENCE_HEADER_SIZE + static_cast< sal_Size >(size)); 526cdf0e10cSrcweir static_cast< sal_Sequence * >(buf)->nRefCount = 0; 527cdf0e10cSrcweir static_cast< sal_Sequence * >(buf)->nElements = 528cdf0e10cSrcweir static_cast< sal_Int32 >(n); 529cdf0e10cSrcweir for (sal_uInt32 i = 0; i != n; ++i) { 530cdf0e10cSrcweir uno_copyData( 531cdf0e10cSrcweir static_cast< sal_Sequence * >(buf)->elements + i * ctd.get()->nSize, 532cdf0e10cSrcweir const_cast< void * >(as[i].getValue(ctd)), ctd.get(), 0); 533cdf0e10cSrcweir } 534cdf0e10cSrcweir return BinaryAny(type, reinterpret_cast< sal_Sequence ** >(&buf)); 535cdf0e10cSrcweir } 536cdf0e10cSrcweir 537cdf0e10cSrcweir void Unmarshal::readMemberValues( 538cdf0e10cSrcweir css::uno::TypeDescription const & type, std::vector< BinaryAny > * values) 539cdf0e10cSrcweir { 540cdf0e10cSrcweir OSL_ASSERT( 541cdf0e10cSrcweir type.is() && 542cdf0e10cSrcweir (type.get()->eTypeClass == typelib_TypeClass_STRUCT || 543cdf0e10cSrcweir type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) && 544cdf0e10cSrcweir values != 0); 545cdf0e10cSrcweir type.makeComplete(); 546cdf0e10cSrcweir typelib_CompoundTypeDescription * ctd = 547cdf0e10cSrcweir reinterpret_cast< typelib_CompoundTypeDescription * >(type.get()); 548cdf0e10cSrcweir if (ctd->pBaseTypeDescription != 0) { 549cdf0e10cSrcweir readMemberValues( 550cdf0e10cSrcweir css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase), 551cdf0e10cSrcweir values); 552cdf0e10cSrcweir } 553cdf0e10cSrcweir for (sal_Int32 i = 0; i != ctd->nMembers; ++i) { 554cdf0e10cSrcweir values->push_back( 555cdf0e10cSrcweir readValue(css::uno::TypeDescription(ctd->ppTypeRefs[i]))); 556cdf0e10cSrcweir } 557cdf0e10cSrcweir } 558cdf0e10cSrcweir 559cdf0e10cSrcweir } 560