bump product version to 5.0.4.1
[LibreOffice.git] / oox / source / ole / axbinaryreader.cxx
blob62835ee713a38cd7c5b418a069b98a4569a36b95
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "oox/ole/axbinaryreader.hxx"
22 #include "oox/ole/olehelper.hxx"
24 #include <osl/diagnose.h>
26 namespace oox {
27 namespace ole {
29 namespace {
31 const sal_uInt32 AX_STRING_SIZEMASK = 0x7FFFFFFF;
32 const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
34 } // namespace
36 AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) :
37 BinaryStreamBase( false ),
38 mpInStrm( &rInStrm ),
39 mnStrmPos( 0 ),
40 mnStrmSize( rInStrm.getRemaining() )
42 mbEof = mbEof || rInStrm.isEof();
45 sal_Int64 AxAlignedInputStream::size() const
47 return mpInStrm ? mnStrmSize : -1;
50 sal_Int64 AxAlignedInputStream::tell() const
52 return mpInStrm ? mnStrmPos : -1;
55 void AxAlignedInputStream::seek( sal_Int64 nPos )
57 mbEof = mbEof || (nPos < mnStrmPos);
58 if( !mbEof )
59 skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
62 void AxAlignedInputStream::close()
64 mpInStrm = 0;
65 mbEof = true;
68 sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
70 sal_Int32 nReadSize = 0;
71 if( !mbEof )
73 nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize );
74 mnStrmPos += nReadSize;
75 mbEof = mpInStrm->isEof();
77 return nReadSize;
80 sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
82 sal_Int32 nReadSize = 0;
83 if( !mbEof )
85 nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize );
86 mnStrmPos += nReadSize;
87 mbEof = mpInStrm->isEof();
89 return nReadSize;
92 void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
94 if( !mbEof )
96 mpInStrm->skip( nBytes, nAtomSize );
97 mnStrmPos += nBytes;
98 mbEof = mpInStrm->isEof();
102 void AxAlignedInputStream::align( size_t nSize )
104 skip( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
107 namespace {
109 bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
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;
124 } // namespace
126 AxBinaryPropertyReader::ComplexProperty::~ComplexProperty()
130 bool AxBinaryPropertyReader::PairProperty::readProperty( AxAlignedInputStream& rInStrm )
132 mrPairData.first = rInStrm.readInt32();
133 mrPairData.second = rInStrm.readInt32();
134 return true;
137 bool AxBinaryPropertyReader::StringProperty::readProperty( AxAlignedInputStream& rInStrm )
139 return lclReadString( rInStrm, mrValue, mnSize, false );
142 bool AxBinaryPropertyReader::ArrayStringProperty::readProperty( AxAlignedInputStream& rInStrm )
144 sal_Int64 nEndPos = rInStrm.tell() + mnSize;
145 while( rInStrm.tell() < nEndPos )
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 boundries
152 rInStrm.align( 4 );
154 return true;
157 bool AxBinaryPropertyReader::GuidProperty::readProperty( AxAlignedInputStream& rInStrm )
159 mrGuid = OleHelper::importGuid( rInStrm );
160 return true;
163 bool AxBinaryPropertyReader::FontProperty::readProperty( AxAlignedInputStream& rInStrm )
165 return mrFontData.importGuidAndFont( rInStrm );
168 bool AxBinaryPropertyReader::PictureProperty::readProperty( AxAlignedInputStream& rInStrm )
170 return OleHelper::importStdPic( mrPicData, rInStrm, true );
173 AxBinaryPropertyReader::AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags ) :
174 maInStrm( rInStrm ),
175 mbValid( true )
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 )
183 mnPropFlags = maInStrm.readInt64();
184 else
185 mnPropFlags = maInStrm.readuInt32();
186 mnNextProp = 1;
189 void AxBinaryPropertyReader::readBoolProperty( bool& orbValue, bool bReverse )
191 // there is no data, the boolean value is equivalent to the property flag itself
192 orbValue = startNextProperty() != bReverse;
195 void AxBinaryPropertyReader::readPairProperty( AxPairData& orPairData )
197 if( startNextProperty() )
198 maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
201 void AxBinaryPropertyReader::readStringProperty( OUString& orValue )
203 if( startNextProperty() )
205 sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
206 maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
210 void AxBinaryPropertyReader::readArrayStringProperty( std::vector<OUString>& orValue )
212 if( startNextProperty() )
214 sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
215 maLargeProps.push_back( ComplexPropVector::value_type( new ArrayStringProperty( orValue, nSize ) ) );
219 void AxBinaryPropertyReader::readGuidProperty( OUString& orGuid )
221 if( startNextProperty() )
222 maLargeProps.push_back( ComplexPropVector::value_type( new GuidProperty( orGuid ) ) );
225 void AxBinaryPropertyReader::readFontProperty( AxFontData& orFontData )
227 if( startNextProperty() )
229 sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
230 if( ensureValid( nData == -1 ) )
231 maStreamProps.push_back( ComplexPropVector::value_type( new FontProperty( orFontData ) ) );
235 void AxBinaryPropertyReader::readPictureProperty( StreamDataSequence& orPicData )
237 if( startNextProperty() )
239 sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
240 if( ensureValid( nData == -1 ) )
241 maStreamProps.push_back( ComplexPropVector::value_type( new PictureProperty( orPicData ) ) );
245 bool AxBinaryPropertyReader::finalizeImport()
247 // read large properties
248 maInStrm.align( 4 );
249 if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
251 for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
253 ensureValid( (*aIt)->readProperty( maInStrm ) );
254 maInStrm.align( 4 );
257 maInStrm.seek( mnPropsEnd );
259 // read stream properties (no stream alignment between properties!)
260 if( ensureValid() && !maStreamProps.empty() )
261 for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
262 ensureValid( (*aIt)->readProperty( maInStrm ) );
264 return mbValid;
267 bool AxBinaryPropertyReader::ensureValid( bool bCondition )
269 mbValid = mbValid && bCondition && !maInStrm.isEof();
270 return mbValid;
273 bool AxBinaryPropertyReader::startNextProperty()
275 bool bHasProp = getFlag( mnPropFlags, mnNextProp );
276 setFlag( mnPropFlags, mnNextProp, false );
277 mnNextProp <<= 1;
278 return ensureValid() && bHasProp;
281 } // namespace ole
282 } // namespace oox
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */