xref: /aoo41x/main/oox/source/ole/axbinaryreader.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 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 "oox/ole/axbinaryreader.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include "oox/ole/olehelper.hxx"
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir namespace oox {
33*cdf0e10cSrcweir namespace ole {
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir // ============================================================================
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir using ::rtl::OUString;
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir // ============================================================================
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir namespace {
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir const sal_uInt32 AX_STRING_SIZEMASK         = 0x7FFFFFFF;
44*cdf0e10cSrcweir const sal_uInt32 AX_STRING_COMPRESSED       = 0x80000000;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir } // namespace
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir // ============================================================================
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) :
51*cdf0e10cSrcweir     BinaryStreamBase( false ),
52*cdf0e10cSrcweir     mpInStrm( &rInStrm ),
53*cdf0e10cSrcweir     mnStrmPos( 0 ),
54*cdf0e10cSrcweir     mnStrmSize( rInStrm.getRemaining() )
55*cdf0e10cSrcweir {
56*cdf0e10cSrcweir     mbEof = mbEof || rInStrm.isEof();
57*cdf0e10cSrcweir }
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir sal_Int64 AxAlignedInputStream::size() const
60*cdf0e10cSrcweir {
61*cdf0e10cSrcweir     return mpInStrm ? mnStrmSize : -1;
62*cdf0e10cSrcweir }
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir sal_Int64 AxAlignedInputStream::tell() const
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir     return mpInStrm ? mnStrmPos : -1;
67*cdf0e10cSrcweir }
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir void AxAlignedInputStream::seek( sal_Int64 nPos )
70*cdf0e10cSrcweir {
71*cdf0e10cSrcweir     mbEof = mbEof || (nPos < mnStrmPos);
72*cdf0e10cSrcweir     if( !mbEof )
73*cdf0e10cSrcweir         skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
74*cdf0e10cSrcweir }
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir void AxAlignedInputStream::close()
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir     mpInStrm = 0;
79*cdf0e10cSrcweir     mbEof = true;
80*cdf0e10cSrcweir }
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
83*cdf0e10cSrcweir {
84*cdf0e10cSrcweir     sal_Int32 nReadSize = 0;
85*cdf0e10cSrcweir     if( !mbEof )
86*cdf0e10cSrcweir     {
87*cdf0e10cSrcweir         nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize );
88*cdf0e10cSrcweir         mnStrmPos += nReadSize;
89*cdf0e10cSrcweir         mbEof = mpInStrm->isEof();
90*cdf0e10cSrcweir     }
91*cdf0e10cSrcweir     return nReadSize;
92*cdf0e10cSrcweir }
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     sal_Int32 nReadSize = 0;
97*cdf0e10cSrcweir     if( !mbEof )
98*cdf0e10cSrcweir     {
99*cdf0e10cSrcweir         nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize );
100*cdf0e10cSrcweir         mnStrmPos += nReadSize;
101*cdf0e10cSrcweir         mbEof = mpInStrm->isEof();
102*cdf0e10cSrcweir     }
103*cdf0e10cSrcweir     return nReadSize;
104*cdf0e10cSrcweir }
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
107*cdf0e10cSrcweir {
108*cdf0e10cSrcweir     if( !mbEof )
109*cdf0e10cSrcweir     {
110*cdf0e10cSrcweir         mpInStrm->skip( nBytes, nAtomSize );
111*cdf0e10cSrcweir         mnStrmPos += nBytes;
112*cdf0e10cSrcweir         mbEof = mpInStrm->isEof();
113*cdf0e10cSrcweir     }
114*cdf0e10cSrcweir }
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir void AxAlignedInputStream::align( size_t nSize )
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     skip( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir // ============================================================================
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir AxFontData::AxFontData() :
124*cdf0e10cSrcweir     mnFontEffects( 0 ),
125*cdf0e10cSrcweir     mnFontHeight( 160 ),
126*cdf0e10cSrcweir     mnFontCharSet( WINDOWS_CHARSET_DEFAULT ),
127*cdf0e10cSrcweir     mnHorAlign( AX_FONTDATA_LEFT ),
128*cdf0e10cSrcweir     mbDblUnderline( false )
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir sal_Int16 AxFontData::getHeightPoints() const
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir     /*  MSO uses weird font sizes:
135*cdf0e10cSrcweir         1pt->30, 2pt->45, 3pt->60, 4pt->75, 5pt->105, 6pt->120, 7pt->135,
136*cdf0e10cSrcweir         8pt->165, 9pt->180, 10pt->195, 11pt->225, ... */
137*cdf0e10cSrcweir     return getLimitedValue< sal_Int16, sal_Int32 >( (mnFontHeight + 10) / 20, 1, SAL_MAX_INT16 );
138*cdf0e10cSrcweir }
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir void AxFontData::setHeightPoints( sal_Int16 nPoints )
141*cdf0e10cSrcweir {
142*cdf0e10cSrcweir     mnFontHeight = getLimitedValue< sal_Int32, sal_Int32 >( ((nPoints * 4 + 1) / 3) * 15, 30, 4294967 );
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir bool AxFontData::importBinaryModel( BinaryInputStream& rInStrm )
146*cdf0e10cSrcweir {
147*cdf0e10cSrcweir     AxBinaryPropertyReader aReader( rInStrm );
148*cdf0e10cSrcweir     aReader.readStringProperty( maFontName );
149*cdf0e10cSrcweir     aReader.readIntProperty< sal_uInt32 >( mnFontEffects );
150*cdf0e10cSrcweir     aReader.readIntProperty< sal_Int32 >( mnFontHeight );
151*cdf0e10cSrcweir     aReader.skipIntProperty< sal_Int32 >(); // font offset
152*cdf0e10cSrcweir     aReader.readIntProperty< sal_uInt8 >( mnFontCharSet );
153*cdf0e10cSrcweir     aReader.skipIntProperty< sal_uInt8 >(); // font pitch/family
154*cdf0e10cSrcweir     aReader.readIntProperty< sal_uInt8 >( mnHorAlign );
155*cdf0e10cSrcweir     aReader.skipIntProperty< sal_uInt16 >(); // font weight
156*cdf0e10cSrcweir     mbDblUnderline = false;
157*cdf0e10cSrcweir     return aReader.finalizeImport();
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir bool AxFontData::importStdFont( BinaryInputStream& rInStrm )
161*cdf0e10cSrcweir {
162*cdf0e10cSrcweir     StdFontInfo aFontInfo;
163*cdf0e10cSrcweir     if( OleHelper::importStdFont( aFontInfo, rInStrm, false ) )
164*cdf0e10cSrcweir     {
165*cdf0e10cSrcweir         maFontName = aFontInfo.maName;
166*cdf0e10cSrcweir         mnFontEffects = 0;
167*cdf0e10cSrcweir         setFlag( mnFontEffects, AX_FONTDATA_BOLD,      aFontInfo.mnWeight >= OLE_STDFONT_BOLD );
168*cdf0e10cSrcweir         setFlag( mnFontEffects, AX_FONTDATA_ITALIC,    getFlag( aFontInfo.mnFlags, OLE_STDFONT_ITALIC ) );
169*cdf0e10cSrcweir         setFlag( mnFontEffects, AX_FONTDATA_UNDERLINE, getFlag( aFontInfo.mnFlags, OLE_STDFONT_UNDERLINE ) );
170*cdf0e10cSrcweir         setFlag( mnFontEffects, AX_FONTDATA_STRIKEOUT, getFlag( aFontInfo.mnFlags,OLE_STDFONT_STRIKE ) );
171*cdf0e10cSrcweir         mbDblUnderline = false;
172*cdf0e10cSrcweir         // StdFont stores font height in 1/10,000 of points
173*cdf0e10cSrcweir         setHeightPoints( getLimitedValue< sal_Int16, sal_Int32 >( aFontInfo.mnHeight / 10000, 0, SAL_MAX_INT16 ) );
174*cdf0e10cSrcweir         mnFontCharSet = aFontInfo.mnCharSet;
175*cdf0e10cSrcweir         mnHorAlign = AX_FONTDATA_LEFT;
176*cdf0e10cSrcweir         return true;
177*cdf0e10cSrcweir     }
178*cdf0e10cSrcweir     return false;
179*cdf0e10cSrcweir }
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir bool AxFontData::importGuidAndFont( BinaryInputStream& rInStrm )
182*cdf0e10cSrcweir {
183*cdf0e10cSrcweir     OUString aGuid = OleHelper::importGuid( rInStrm );
184*cdf0e10cSrcweir     if( aGuid.equalsAscii( AX_GUID_CFONT ) )
185*cdf0e10cSrcweir         return importBinaryModel( rInStrm );
186*cdf0e10cSrcweir     if( aGuid.equalsAscii( OLE_GUID_STDFONT ) )
187*cdf0e10cSrcweir         return importStdFont( rInStrm );
188*cdf0e10cSrcweir     return false;
189*cdf0e10cSrcweir }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir // ============================================================================
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir namespace {
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir     bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
198*cdf0e10cSrcweir     sal_uInt32 nBufSize = nSize & AX_STRING_SIZEMASK;
199*cdf0e10cSrcweir     // Unicode: simple strings store byte count, array strings store char count
200*cdf0e10cSrcweir     sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / ((bCompressed || bArrayString) ? 1 : 2) );
201*cdf0e10cSrcweir     bool bValidChars = nChars <= 65536;
202*cdf0e10cSrcweir     OSL_ENSURE( bValidChars, "lclReadString - string too long" );
203*cdf0e10cSrcweir     sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2);
204*cdf0e10cSrcweir     nChars = ::std::min< sal_Int32 >( nChars, 65536 );
205*cdf0e10cSrcweir     rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed );
206*cdf0e10cSrcweir     rInStrm.seek( nEndPos );
207*cdf0e10cSrcweir     return bValidChars;
208*cdf0e10cSrcweir }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir } // namespace
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir // ----------------------------------------------------------------------------
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir AxBinaryPropertyReader::ComplexProperty::~ComplexProperty()
215*cdf0e10cSrcweir {
216*cdf0e10cSrcweir }
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir bool AxBinaryPropertyReader::PairProperty::readProperty( AxAlignedInputStream& rInStrm )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir     rInStrm >> mrPairData.first >> mrPairData.second;
221*cdf0e10cSrcweir     return true;
222*cdf0e10cSrcweir }
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir bool AxBinaryPropertyReader::StringProperty::readProperty( AxAlignedInputStream& rInStrm )
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir     return lclReadString( rInStrm, mrValue, mnSize, false );
227*cdf0e10cSrcweir }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir bool AxBinaryPropertyReader::StringArrayProperty::readProperty( AxAlignedInputStream& rInStrm )
230*cdf0e10cSrcweir {
231*cdf0e10cSrcweir     sal_Int64 nEndPos = rInStrm.tell() + mnSize;
232*cdf0e10cSrcweir     while( rInStrm.tell() < nEndPos )
233*cdf0e10cSrcweir     {
234*cdf0e10cSrcweir         OUString aString;
235*cdf0e10cSrcweir         if( !lclReadString( rInStrm, aString, rInStrm.readuInt32(), true ) )
236*cdf0e10cSrcweir             return false;
237*cdf0e10cSrcweir         mrArray.push_back( aString );
238*cdf0e10cSrcweir         // every array string is aligned on 4 byte boundries
239*cdf0e10cSrcweir         rInStrm.align( 4 );
240*cdf0e10cSrcweir     }
241*cdf0e10cSrcweir     return true;
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir bool AxBinaryPropertyReader::GuidProperty::readProperty( AxAlignedInputStream& rInStrm )
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir     mrGuid = OleHelper::importGuid( rInStrm );
247*cdf0e10cSrcweir     return true;
248*cdf0e10cSrcweir }
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir bool AxBinaryPropertyReader::FontProperty::readProperty( AxAlignedInputStream& rInStrm )
251*cdf0e10cSrcweir {
252*cdf0e10cSrcweir     return mrFontData.importGuidAndFont( rInStrm );
253*cdf0e10cSrcweir }
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir bool AxBinaryPropertyReader::PictureProperty::readProperty( AxAlignedInputStream& rInStrm )
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     return OleHelper::importStdPic( mrPicData, rInStrm, true );
258*cdf0e10cSrcweir }
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir // ----------------------------------------------------------------------------
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir AxBinaryPropertyReader::AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags ) :
263*cdf0e10cSrcweir     maInStrm( rInStrm ),
264*cdf0e10cSrcweir     mbValid( true )
265*cdf0e10cSrcweir {
266*cdf0e10cSrcweir     // version and size of property block
267*cdf0e10cSrcweir     maInStrm.skip( 2 );
268*cdf0e10cSrcweir     sal_uInt16 nBlockSize = maInStrm.readValue< sal_uInt16 >();
269*cdf0e10cSrcweir     mnPropsEnd = maInStrm.tell() + nBlockSize;
270*cdf0e10cSrcweir     // flagfield containing existing properties
271*cdf0e10cSrcweir     if( b64BitPropFlags )
272*cdf0e10cSrcweir         maInStrm >> mnPropFlags;
273*cdf0e10cSrcweir     else
274*cdf0e10cSrcweir         mnPropFlags = maInStrm.readuInt32();
275*cdf0e10cSrcweir     mnNextProp = 1;
276*cdf0e10cSrcweir }
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir void AxBinaryPropertyReader::readBoolProperty( bool& orbValue, bool bReverse )
279*cdf0e10cSrcweir {
280*cdf0e10cSrcweir     // there is no data, the boolean value is equivalent to the property flag itself
281*cdf0e10cSrcweir     orbValue = startNextProperty() != bReverse;
282*cdf0e10cSrcweir }
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir void AxBinaryPropertyReader::readPairProperty( AxPairData& orPairData )
285*cdf0e10cSrcweir {
286*cdf0e10cSrcweir     if( startNextProperty() )
287*cdf0e10cSrcweir         maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir void AxBinaryPropertyReader::readStringProperty( OUString& orValue )
291*cdf0e10cSrcweir {
292*cdf0e10cSrcweir     if( startNextProperty() )
293*cdf0e10cSrcweir     {
294*cdf0e10cSrcweir         sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
295*cdf0e10cSrcweir         maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
296*cdf0e10cSrcweir     }
297*cdf0e10cSrcweir }
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir void AxBinaryPropertyReader::readStringArrayProperty( AxStringArray& orArray )
300*cdf0e10cSrcweir {
301*cdf0e10cSrcweir     if( startNextProperty() )
302*cdf0e10cSrcweir     {
303*cdf0e10cSrcweir         sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
304*cdf0e10cSrcweir         maLargeProps.push_back( ComplexPropVector::value_type( new StringArrayProperty( orArray, nSize ) ) );
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir }
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir void AxBinaryPropertyReader::readGuidProperty( ::rtl::OUString& orGuid )
309*cdf0e10cSrcweir {
310*cdf0e10cSrcweir     if( startNextProperty() )
311*cdf0e10cSrcweir         maLargeProps.push_back( ComplexPropVector::value_type( new GuidProperty( orGuid ) ) );
312*cdf0e10cSrcweir }
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir void AxBinaryPropertyReader::readFontProperty( AxFontData& orFontData )
315*cdf0e10cSrcweir {
316*cdf0e10cSrcweir     if( startNextProperty() )
317*cdf0e10cSrcweir     {
318*cdf0e10cSrcweir         sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
319*cdf0e10cSrcweir         if( ensureValid( nData == -1 ) )
320*cdf0e10cSrcweir             maStreamProps.push_back( ComplexPropVector::value_type( new FontProperty( orFontData ) ) );
321*cdf0e10cSrcweir     }
322*cdf0e10cSrcweir }
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir void AxBinaryPropertyReader::readPictureProperty( StreamDataSequence& orPicData )
325*cdf0e10cSrcweir {
326*cdf0e10cSrcweir     if( startNextProperty() )
327*cdf0e10cSrcweir     {
328*cdf0e10cSrcweir         sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
329*cdf0e10cSrcweir         if( ensureValid( nData == -1 ) )
330*cdf0e10cSrcweir             maStreamProps.push_back( ComplexPropVector::value_type( new PictureProperty( orPicData ) ) );
331*cdf0e10cSrcweir     }
332*cdf0e10cSrcweir }
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir bool AxBinaryPropertyReader::finalizeImport()
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir     // read large properties
337*cdf0e10cSrcweir     maInStrm.align( 4 );
338*cdf0e10cSrcweir     if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
339*cdf0e10cSrcweir     {
340*cdf0e10cSrcweir         for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
341*cdf0e10cSrcweir         {
342*cdf0e10cSrcweir             ensureValid( (*aIt)->readProperty( maInStrm ) );
343*cdf0e10cSrcweir             maInStrm.align( 4 );
344*cdf0e10cSrcweir         }
345*cdf0e10cSrcweir     }
346*cdf0e10cSrcweir     maInStrm.seek( mnPropsEnd );
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     // read stream properties (no stream alignment between properties!)
349*cdf0e10cSrcweir     if( ensureValid() && !maStreamProps.empty() )
350*cdf0e10cSrcweir         for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
351*cdf0e10cSrcweir             ensureValid( (*aIt)->readProperty( maInStrm ) );
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir     return mbValid;
354*cdf0e10cSrcweir }
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir bool AxBinaryPropertyReader::ensureValid( bool bCondition )
357*cdf0e10cSrcweir {
358*cdf0e10cSrcweir     mbValid = mbValid && bCondition && !maInStrm.isEof();
359*cdf0e10cSrcweir     return mbValid;
360*cdf0e10cSrcweir }
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir bool AxBinaryPropertyReader::startNextProperty()
363*cdf0e10cSrcweir {
364*cdf0e10cSrcweir     bool bHasProp = getFlag( mnPropFlags, mnNextProp );
365*cdf0e10cSrcweir     setFlag( mnPropFlags, mnNextProp, false );
366*cdf0e10cSrcweir     mnNextProp <<= 1;
367*cdf0e10cSrcweir     return ensureValid() && bHasProp;
368*cdf0e10cSrcweir }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir // ============================================================================
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir } // namespace ole
373*cdf0e10cSrcweir } // namespace oox
374