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