137adc4f0SAndrew Rist /**************************************************************
237adc4f0SAndrew Rist *
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
1037adc4f0SAndrew Rist *
1137adc4f0SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
1237adc4f0SAndrew Rist *
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.
1937adc4f0SAndrew Rist *
2037adc4f0SAndrew Rist *************************************************************/
2137adc4f0SAndrew Rist
2237adc4f0SAndrew 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
allocate(sal_Size size)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
copyMemberValues(css::uno::TypeDescription const & type,std::vector<BinaryAny>::iterator const & it,void * buffer)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
Unmarshal(rtl::Reference<Bridge> const & bridge,ReaderState & state,css::uno::Sequence<sal_Int8> const & buffer)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
~Unmarshal()111cdf0e10cSrcweir Unmarshal::~Unmarshal() {}
112cdf0e10cSrcweir
read8()113cdf0e10cSrcweir sal_uInt8 Unmarshal::read8() {
114cdf0e10cSrcweir check(1);
115cdf0e10cSrcweir return *data_++;
116cdf0e10cSrcweir }
117cdf0e10cSrcweir
read16()118cdf0e10cSrcweir sal_uInt16 Unmarshal::read16() {
119cdf0e10cSrcweir check(2);
120cdf0e10cSrcweir sal_uInt16 n = static_cast< sal_uInt16 >(*data_++) << 8;
121cdf0e10cSrcweir return n | *data_++;
122cdf0e10cSrcweir }
123cdf0e10cSrcweir
read32()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
readType()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
readOid()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();
247*0848378bSHerbert Dürr if (oid.isEmpty() && idx != cache::ignore) {
248*0848378bSHerbert Dürr if ( state_.oidCache[idx].isEmpty() ) {
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
readTid()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
readValue(css::uno::TypeDescription const & type)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
done() const406cdf0e10cSrcweir 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
check(sal_Int32 size) const416cdf0e10cSrcweir 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
readCompressed()426cdf0e10cSrcweir sal_uInt32 Unmarshal::readCompressed() {
427cdf0e10cSrcweir sal_uInt8 n = read8();
428cdf0e10cSrcweir return n == 0xFF ? read32() : n;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir
readCacheIndex()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
read64()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
readString()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
readSequence(css::uno::TypeDescription const & type)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
readMemberValues(css::uno::TypeDescription const & type,std::vector<BinaryAny> * values)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