/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
sal_uInt16 Unmarshal::read16() {
check(2);
sal_uInt16 n = static_cast< sal_uInt16 >(*data_++) << 8; return n | *data_++;
}
sal_uInt32 Unmarshal::read32() {
check(4);
sal_uInt32 n = static_cast< sal_uInt32 >(*data_++) << 24;
n |= static_cast< sal_uInt32 >(*data_++) << 16;
n |= static_cast< sal_uInt32 >(*data_++) << 8; return n | *data_++;
}
css::uno::TypeDescription Unmarshal::readType() {
sal_uInt8 flags = read8();
typelib_TypeClass tc = static_cast< typelib_TypeClass >(flags & 0x7F); switch (tc) { case typelib_TypeClass_VOID: case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_CHAR: case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_ANY: if ((flags & 0x80) != 0) { throw css::io::IOException(
u"binaryurp::Unmarshal: cache flag of simple type is set"_ustr);
} return css::uno::TypeDescription(
*typelib_static_type_getByTypeClass(tc)); case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_ENUM: case typelib_TypeClass_STRUCT: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_INTERFACE:
{
sal_uInt16 idx = readCacheIndex(); if ((flags & 0x80) == 0) { if (idx == cache::ignore || !state_.typeCache[idx].is()) { throw css::io::IOException(
u"binaryurp::Unmarshal: unknown type cache index"_ustr);
} return state_.typeCache[idx];
} else {
OUString const str(readString());
css::uno::TypeDescription t(str); if (!t.is() || t.get()->eTypeClass != tc) {
throw css::io::IOException( "binaryurp::Unmarshal: type with unknown name: " + str);
} for (css::uno::TypeDescription t2(t);
t2.get()->eTypeClass == typelib_TypeClass_SEQUENCE;)
{
t2.makeComplete();
t2 = css::uno::TypeDescription( reinterpret_cast< typelib_IndirectTypeDescription * >(
t2.get())->pType); if (!t2.is()) { throw css::io::IOException(
u"binaryurp::Unmarshal: sequence type with unknown" " component type"_ustr);
} switch (t2.get()->eTypeClass) { case typelib_TypeClass_VOID: case typelib_TypeClass_EXCEPTION: throw css::io::IOException(
u"binaryurp::Unmarshal: sequence type with bad" " component type"_ustr); default: break;
}
} if (idx != cache::ignore) {
state_.typeCache[idx] = t;
} return t;
}
} default: throw css::io::IOException(
u"binaryurp::Unmarshal: type of unknown type class"_ustr);
}
}
OUString Unmarshal::readOid() {
OUString oid(readString()); for (sal_Int32 i = 0; i != oid.getLength(); ++i) { if (oid[i] > 0x7F) { throw css::io::IOException(
u"binaryurp::Unmarshal: OID contains non-ASCII character"_ustr);
}
}
sal_uInt16 idx = readCacheIndex(); if (oid.isEmpty() && idx != cache::ignore) { if (state_.oidCache[idx].isEmpty()) { throw css::io::IOException(
u"binaryurp::Unmarshal: unknown OID cache index"_ustr);
} return state_.oidCache[idx];
} if (idx != cache::ignore) {
state_.oidCache[idx] = oid;
} return oid;
}
void Unmarshal::check(sal_Int32 size) const { if (end_ - data_ < size) { throw css::io::IOException(
u"binaryurp::Unmarshal: trying to read past end of block"_ustr);
}
}
sal_uInt32 Unmarshal::readCompressed() {
sal_uInt8 n = read8(); return n == 0xFF ? read32() : n;
}
sal_uInt16 Unmarshal::readCacheIndex() {
sal_uInt16 idx = read16(); if (idx >= cache::size && idx != cache::ignore) { throw css::io::IOException(
u"binaryurp::Unmarshal: cache index out of range"_ustr);
} return idx;
}
sal_uInt64 Unmarshal::read64() {
check(8);
sal_uInt64 n = static_cast< sal_uInt64 >(*data_++) << 56;
n |= static_cast< sal_uInt64 >(*data_++) << 48;
n |= static_cast< sal_uInt64 >(*data_++) << 40;
n |= static_cast< sal_uInt64 >(*data_++) << 32;
n |= static_cast< sal_uInt64 >(*data_++) << 24;
n |= static_cast< sal_uInt64 >(*data_++) << 16;
n |= static_cast< sal_uInt64 >(*data_++) << 8; return n | *data_++;
}
OUString Unmarshal::readString() {
sal_uInt32 n = readCompressed(); if (n > SAL_MAX_INT32) { throw css::uno::RuntimeException(
u"binaryurp::Unmarshal: string size too large"_ustr);
}
check(static_cast< sal_Int32 >(n));
OUString s; if (!rtl_convertStringToUString(
&s.pData, reinterpret_cast< charconst * >(data_), static_cast< sal_Int32 >(n), RTL_TEXTENCODING_UTF8,
(RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
{ throw css::io::IOException(
u"binaryurp::Unmarshal: string does not contain UTF-8"_ustr);
}
data_ += n; return s;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.