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