LibreOffice Module oox (master) 1
axbinaryreader.cxx
Go to the documentation of this file.
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
21
23#include <oox/ole/olehelper.hxx>
24
25#include <osl/diagnose.h>
26
27namespace oox::ole {
28
29namespace {
30
31const sal_uInt32 AX_STRING_SIZEMASK = 0x7FFFFFFF;
32const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
33
34} // namespace
35
37 BinaryStreamBase( false ),
38 mpInStrm( &rInStrm ),
39 mnStrmPos( 0 ),
40 mnStrmSize( rInStrm.getRemaining() )
41{
42 mbEof = mbEof || rInStrm.isEof();
43}
44
46{
47 return mpInStrm ? mnStrmSize : -1;
48}
49
51{
52 return mpInStrm ? mnStrmPos : -1;
53}
54
55void AxAlignedInputStream::seek( sal_Int64 nPos )
56{
57 mbEof = mbEof || (nPos < mnStrmPos);
58 if( !mbEof )
59 skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
60}
61
63{
64 mpInStrm = nullptr;
65 mbEof = true;
66}
67
68sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
69{
70 sal_Int32 nReadSize = 0;
71 if( !mbEof )
72 {
73 nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize );
74 mnStrmPos += nReadSize;
75 mbEof = mpInStrm->isEof();
76 }
77 return nReadSize;
78}
79
80sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
81{
82 sal_Int32 nReadSize = 0;
83 if( !mbEof )
84 {
85 nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize );
86 mnStrmPos += nReadSize;
87 mbEof = mpInStrm->isEof();
88 }
89 return nReadSize;
90}
91
92void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
93{
94 if( !mbEof )
95 {
96 mpInStrm->skip( nBytes, nAtomSize );
97 mnStrmPos += nBytes;
98 mbEof = mpInStrm->isEof();
99 }
100}
101
102void AxAlignedInputStream::align( size_t nSize )
103{
104 skip( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
105}
106
107namespace {
108
109bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
110{
111 bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
112 sal_uInt32 nBufSize = nSize & AX_STRING_SIZEMASK;
113 // Unicode: simple strings store byte count, array strings store char count
114 sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / ((bCompressed || bArrayString) ? 1 : 2) );
115 bool bValidChars = nChars <= 65536;
116 OSL_ENSURE( bValidChars, "lclReadString - string too long" );
117 sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2);
118 nChars = ::std::min< sal_Int32 >( nChars, 65536 );
119 rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed );
120 rInStrm.seek( nEndPos );
121 return bValidChars;
122}
123
124} // namespace
125
127{
128}
129
131{
132 mrPairData.first = rInStrm.readInt32();
133 mrPairData.second = rInStrm.readInt32();
134 return true;
135}
136
138{
139 return lclReadString( rInStrm, mrValue, mnSize, false );
140}
141
143{
144 sal_Int64 nEndPos = rInStrm.tell() + mnSize;
145 while( rInStrm.tell() < nEndPos )
146 {
147 OUString aString;
148 if( !lclReadString( rInStrm, aString, rInStrm.readuInt32(), true ) )
149 return false;
150 mrArray.push_back( aString );
151 // every array string is aligned on 4 byte boundaries
152 rInStrm.align( 4 );
153 }
154 return true;
155}
156
158{
159 mrGuid = OleHelper::importGuid( rInStrm );
160 return true;
161}
162
164{
165 return mrFontData.importGuidAndFont( rInStrm );
166}
167
169{
170 return OleHelper::importStdPic( mrPicData, rInStrm );
171}
172
174 maInStrm( rInStrm ),
175 mbValid( true )
176{
177 // version and size of property block
178 maInStrm.skip( 2 );
179 sal_uInt16 nBlockSize = maInStrm.readuInt16();
180 mnPropsEnd = maInStrm.tell() + nBlockSize;
181 // flagfield containing existing properties
182 if( b64BitPropFlags )
184 else
186 mnNextProp = 1;
187}
188
189void AxBinaryPropertyReader::readBoolProperty( bool& orbValue, bool bReverse )
190{
191 // there is no data, the boolean value is equivalent to the property flag itself
192 orbValue = startNextProperty() != bReverse;
193}
194
196{
197 if( startNextProperty() )
198 maLargeProps.push_back( ComplexPropVector::value_type( std::make_shared<PairProperty>( orPairData ) ) );
199}
200
202{
203 if( startNextProperty() )
204 {
205 sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
206 maLargeProps.push_back( ComplexPropVector::value_type( std::make_shared<StringProperty>( orValue, nSize ) ) );
207 }
208}
209
210void AxBinaryPropertyReader::readArrayStringProperty( std::vector<OUString>& orValue )
211{
212 if( startNextProperty() )
213 {
214 sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
215 maLargeProps.push_back( ComplexPropVector::value_type( std::make_shared<ArrayStringProperty>( orValue, nSize ) ) );
216 }
217}
218
220{
221 if( startNextProperty() )
222 maLargeProps.push_back( ComplexPropVector::value_type( std::make_shared<GuidProperty>( orGuid ) ) );
223}
224
226{
227 if( startNextProperty() )
228 {
229 sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
230 if( ensureValid( nData == -1 ) )
231 maStreamProps.push_back( ComplexPropVector::value_type( std::make_shared<FontProperty>( orFontData ) ) );
232 }
233}
234
236{
237 if( startNextProperty() )
238 {
239 sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
240 if( ensureValid( nData == -1 ) )
241 maStreamProps.push_back( ComplexPropVector::value_type( std::make_shared<PictureProperty>( orPicData ) ) );
242 }
243}
244
246{
247 // read large properties
248 maInStrm.align( 4 );
249 if( ensureValid( mnPropFlags == 0 ) )
250 {
251 for (auto const& largeProp : maLargeProps)
252 {
253 if (!ensureValid())
254 break;
255 ensureValid( largeProp->readProperty( maInStrm ) );
256 maInStrm.align( 4 );
257 }
258 }
260
261 // read stream properties (no stream alignment between properties!)
262 if( ensureValid() )
263 {
264 for (auto const& streamProp : maStreamProps)
265 {
266 if (!ensureValid())
267 break;
268 ensureValid( streamProp->readProperty( maInStrm ) );
269 }
270 }
271
272 return mbValid;
273}
274
276{
277 mbValid = mbValid && bCondition && !maInStrm.isEof();
278 return mbValid;
279}
280
282{
283 bool bHasProp = getFlag( mnPropFlags, mnNextProp );
284 setFlag( mnPropFlags, mnNextProp, false );
285 mnNextProp <<= 1;
286 return ensureValid() && bHasProp;
287}
288
289} // namespace oox::ole
290
291/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Interface for binary input stream classes.
virtual void skip(sal_Int32 nBytes, size_t nAtomSize=1)=0
Derived classes implement seeking the stream forward by the passed number of bytes.
virtual sal_Int32 readData(StreamDataSequence &orData, sal_Int32 nBytes, size_t nAtomSize=1)=0
Derived classes implement reading nBytes bytes to the passed sequence.
OUString readCompressedUnicodeArray(sal_Int32 nChars, bool bCompressed)
Reads a Unicode character array (may be compressed) and returns the string.
virtual sal_Int32 readMemory(void *opMem, sal_Int32 nBytes, size_t nAtomSize=1)=0
Derived classes implement reading nBytes bytes to the (preallocated!) memory buffer opMem.
Base class for binary stream classes.
bool isEof() const
Returns true, if the stream position is invalid (EOF).
bool mbEof
End of stream flag.
container_type::value_type value_type
Definition: refvector.hxx:46
A wrapper for a binary input stream that supports aligned read operations.
virtual sal_Int32 readMemory(void *opMem, sal_Int32 nBytes, size_t nAtomSize=1) override
Reads nBytes bytes to the (existing) buffer opMem.
virtual sal_Int64 tell() const override
Return the current relative stream position (relative to position of the wrapped stream at constructi...
void align(size_t nSize)
Aligns the stream to a multiple of the passed size (relative to the position of the wrapped stream at...
Type readAligned()
Aligns the stream according to the passed type and reads a value.
sal_Int64 mnStrmSize
Size of the wrapped stream data.
sal_Int64 mnStrmPos
Tracks relative position in the stream.
virtual void skip(sal_Int32 nBytes, size_t nAtomSize=1) override
Seeks the stream forward by the passed number of bytes.
virtual void close() override
Closes the input stream but not the wrapped stream.
AxAlignedInputStream(BinaryInputStream &rInStrm)
virtual void seek(sal_Int64 nPos) override
Seeks the stream to the passed relative position, if it is behind the current position.
virtual sal_Int64 size() const override
Returns the size of the data this stream represents, if the wrapped stream supports the size() operat...
virtual sal_Int32 readData(StreamDataSequence &orData, sal_Int32 nBytes, size_t nAtomSize=1) override
Reads nBytes bytes to the passed sequence.
BinaryInputStream * mpInStrm
The wrapped input stream.
ComplexPropVector maLargeProps
Stores info for all used large properties.
bool finalizeImport()
Final processing, reads contents of all complex properties.
AxBinaryPropertyReader(BinaryInputStream &rInStrm, bool b64BitPropFlags=false)
bool ensureValid(bool bCondition=true)
void readGuidProperty(OUString &orGuid)
Reads the next GUID property from the stream, if the respective flag in the property mask is set.
void readFontProperty(AxFontData &orFontData)
Reads the next font property from the stream, if the respective flag in the property mask is set.
void readStringProperty(OUString &orValue)
Reads the next string property from the stream, if the respective flag in the property mask is set.
void readPairProperty(AxPairData &orPairData)
Reads the next pair property from the stream, if the respective flag in the property mask is set.
sal_Int64 mnPropsEnd
End position of simple/large properties.
sal_Int64 mnPropFlags
Flags specifying existing properties.
bool mbValid
True = stream still valid.
void readArrayStringProperty(std::vector< OUString > &rStrings)
Reads ArrayString, an array of fmString ( compressed or uncompressed ) is read from the stream and in...
ComplexPropVector maStreamProps
Stores info for all used stream data properties.
void readBoolProperty(bool &orbValue, bool bReverse=false)
Reads the next boolean property value from the stream, if the respective flag in the property mask is...
AxAlignedInputStream maInStrm
The input stream to read from.
void readPictureProperty(StreamDataSequence &orPicData)
Reads the next picture property from the stream, if the respective flag in the property mask is set.
sal_Int64 mnNextProp
Next property to read.
sal_uInt32 mnSize
Definition: dffdumper.cxx:164
sal_uInt16 nPos
OOX_DLLPUBLIC OUString importGuid(BinaryInputStream &rInStrm)
Imports a GUID from the passed binary stream and returns its string representation (in uppercase char...
Definition: olehelper.cxx:261
OOX_DLLPUBLIC bool importStdPic(StreamDataSequence &orGraphicData, BinaryInputStream &rInStrm)
Imports an OLE StdPic picture from the current position of the passed binary stream.
Definition: olehelper.cxx:303
::std::pair< sal_Int32, sal_Int32 > AxPairData
A pair of integer values as a property.
void setFlag(Type &ornBitField, Type nMask, bool bSet=true)
Sets or clears (according to bSet) all set bits of nMask in ornBitField.
Definition: helper.hxx:167
css::uno::Sequence< sal_Int8 > StreamDataSequence
bool getFlag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: helper.hxx:137
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
virtual bool readProperty(AxAlignedInputStream &rInStrm) override
All entries of a font property.
Definition: axfontdata.hxx:54