Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "biffinputstream.hxx"
30 : :
31 : : #include <algorithm>
32 : : #include <rtl/ustrbuf.hxx>
33 : :
34 : : namespace oox {
35 : : namespace xls {
36 : :
37 : : // ============================================================================
38 : :
39 : : using ::rtl::OString;
40 : : using ::rtl::OStringToOUString;
41 : : using ::rtl::OUString;
42 : : using ::rtl::OUStringBuffer;
43 : :
44 : : // ============================================================================
45 : :
46 : : namespace prv {
47 : :
48 : 0 : BiffInputRecordBuffer::BiffInputRecordBuffer( BinaryInputStream& rInStrm ) :
49 : : mrInStrm( rInStrm ),
50 : : mpCurrentData( 0 ),
51 : : mnHeaderPos( -1 ),
52 : : mnBodyPos( 0 ),
53 : : mnBufferBodyPos( 0 ),
54 : : mnNextHeaderPos( 0 ),
55 : : mnRecId( BIFF_ID_UNKNOWN ),
56 : : mnRecSize( 0 ),
57 : : mnRecPos( 0 ),
58 [ # # ][ # # ]: 0 : mbValidHeader( false )
59 : : {
60 : : OSL_ENSURE( mrInStrm.isSeekable(), "BiffInputRecordBuffer::BiffInputRecordBuffer - stream must be seekable" );
61 [ # # ]: 0 : mrInStrm.seekToStart();
62 [ # # ]: 0 : maOriginalData.reserve( SAL_MAX_UINT16 );
63 [ # # ]: 0 : maDecodedData.reserve( SAL_MAX_UINT16 );
64 [ # # ]: 0 : enableDecoder( false ); // updates mpCurrentData
65 : 0 : }
66 : :
67 : 0 : void BiffInputRecordBuffer::restartAt( sal_Int64 nPos )
68 : : {
69 : 0 : mnHeaderPos = -1;
70 : 0 : mnBodyPos = mnBufferBodyPos = 0;
71 : 0 : mnNextHeaderPos = nPos;
72 : 0 : mnRecId = BIFF_ID_UNKNOWN;
73 : 0 : mnRecSize = mnRecPos = 0;
74 : 0 : mbValidHeader = false;
75 : 0 : }
76 : :
77 : 0 : void BiffInputRecordBuffer::setDecoder( const BiffDecoderRef& rxDecoder )
78 : : {
79 : 0 : mxDecoder = rxDecoder;
80 : 0 : enableDecoder( true );
81 : 0 : updateDecoded();
82 : 0 : }
83 : :
84 : 0 : void BiffInputRecordBuffer::enableDecoder( bool bEnable )
85 : : {
86 [ # # ][ # # ]: 0 : mpCurrentData = (bEnable && mxDecoder.get() && mxDecoder->isValid()) ? &maDecodedData : &maOriginalData;
[ # # ]
87 : 0 : }
88 : :
89 : 0 : bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos )
90 : : {
91 [ # # ][ # # ]: 0 : mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.size());
92 [ # # ]: 0 : if( mbValidHeader )
93 : : {
94 : 0 : mnHeaderPos = nHeaderPos;
95 : 0 : mrInStrm.seek( nHeaderPos );
96 : 0 : mrInStrm >> mnRecId >> mnRecSize;
97 : 0 : mnBodyPos = mrInStrm.tell();
98 : 0 : mnNextHeaderPos = mnBodyPos + mnRecSize;
99 [ # # ][ # # ]: 0 : mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.size());
100 : : }
101 [ # # ]: 0 : if( !mbValidHeader )
102 : : {
103 : 0 : mnHeaderPos = mnBodyPos = -1;
104 : 0 : mnNextHeaderPos = 0;
105 : 0 : mnRecId = BIFF_ID_UNKNOWN;
106 : 0 : mnRecSize = 0;
107 : : }
108 : 0 : mnRecPos = 0;
109 : 0 : return mbValidHeader;
110 : : }
111 : :
112 : 0 : bool BiffInputRecordBuffer::startNextRecord()
113 : : {
114 : 0 : return startRecord( mnNextHeaderPos );
115 : : }
116 : :
117 : 0 : sal_uInt16 BiffInputRecordBuffer::getNextRecId()
118 : : {
119 : 0 : sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
120 [ # # ][ # # ]: 0 : if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.size()) )
[ # # ][ # # ]
121 : : {
122 [ # # ]: 0 : mrInStrm.seek( mnNextHeaderPos );
123 [ # # ]: 0 : mrInStrm >> nRecId;
124 : : }
125 : 0 : return nRecId;
126 : : }
127 : :
128 : 0 : void BiffInputRecordBuffer::read( void* opData, sal_uInt16 nBytes )
129 : : {
130 : 0 : updateBuffer();
131 : : OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::read - nothing to read" );
132 : : OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::read - buffer overflow" );
133 : 0 : memcpy( opData, &(*mpCurrentData)[ mnRecPos ], nBytes );
134 : 0 : mnRecPos = mnRecPos + nBytes;
135 : 0 : }
136 : :
137 : 0 : void BiffInputRecordBuffer::skip( sal_uInt16 nBytes )
138 : : {
139 : : OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::skip - nothing to skip" );
140 : : OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::skip - buffer overflow" );
141 : 0 : mnRecPos = mnRecPos + nBytes;
142 : 0 : }
143 : :
144 : 0 : void BiffInputRecordBuffer::updateBuffer()
145 : : {
146 : : OSL_ENSURE( mbValidHeader, "BiffInputRecordBuffer::updateBuffer - invalid access" );
147 [ # # ]: 0 : if( mnBodyPos != mnBufferBodyPos )
148 : : {
149 : 0 : mrInStrm.seek( mnBodyPos );
150 : 0 : maOriginalData.resize( mnRecSize );
151 [ # # ]: 0 : if( mnRecSize > 0 )
152 : 0 : mrInStrm.readMemory( &maOriginalData.front(), static_cast< sal_Int32 >( mnRecSize ) );
153 : 0 : mnBufferBodyPos = mnBodyPos;
154 : 0 : updateDecoded();
155 : : }
156 : 0 : }
157 : :
158 : 0 : void BiffInputRecordBuffer::updateDecoded()
159 : : {
160 [ # # ][ # # ]: 0 : if( mxDecoder.get() && mxDecoder->isValid() )
[ # # ]
161 : : {
162 : 0 : maDecodedData.resize( mnRecSize );
163 [ # # ]: 0 : if( mnRecSize > 0 )
164 : 0 : mxDecoder->decode( &maDecodedData.front(), &maOriginalData.front(), mnBodyPos, mnRecSize );
165 : : }
166 : 0 : }
167 : :
168 : : } // namespace prv
169 : :
170 : : // ============================================================================
171 : :
172 : 0 : BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) :
173 : : BinaryStreamBase( true ),
174 : : maRecBuffer( rInStream ),
175 : : mnRecHandle( -1 ),
176 : : mnRecId( BIFF_ID_UNKNOWN ),
177 : : mnAltContId( BIFF_ID_UNKNOWN ),
178 : : mnCurrRecSize( 0 ),
179 : : mnComplRecSize( 0 ),
180 : : mbHasComplRec( false ),
181 [ # # ][ # # ]: 0 : mbCont( bContLookup )
[ # # ][ # # ]
182 : : {
183 : 0 : mbEof = true; // EOF will be true if stream is not inside a record
184 : 0 : }
185 : :
186 : : // record control -------------------------------------------------------------
187 : :
188 : 0 : bool BiffInputStream::startNextRecord()
189 : : {
190 : 0 : bool bValidRec = false;
191 : : /* #i4266# ignore zero records (id==len==0) (e.g. the application
192 : : "Crystal Report" writes zero records between other records) */
193 : 0 : bool bIsZeroRec = false;
194 [ # # ]: 0 : do
[ # # # # ]
[ # # ][ # # ]
195 : : {
196 : : // record header is never encrypted
197 : 0 : maRecBuffer.enableDecoder( false );
198 : : // read header of next raw record, returns false at end of stream
199 : 0 : bValidRec = maRecBuffer.startNextRecord();
200 : : // ignore record, if identifier and size are zero
201 [ # # ][ # # ]: 0 : bIsZeroRec = (maRecBuffer.getRecId() == 0) && (maRecBuffer.getRecSize() == 0);
202 : : }
203 : 0 : while( bValidRec && ((mbCont && isContinueId( maRecBuffer.getRecId() )) || bIsZeroRec) );
204 : :
205 : : // setup other class members
206 : 0 : setupRecord();
207 : 0 : return isInRecord();
208 : : }
209 : :
210 : 0 : bool BiffInputStream::startRecordByHandle( sal_Int64 nRecHandle )
211 : : {
212 : 0 : rewindToRecord( nRecHandle );
213 : 0 : return startNextRecord();
214 : : }
215 : :
216 : 0 : void BiffInputStream::rewindRecord()
217 : : {
218 : 0 : rewindToRecord( mnRecHandle );
219 : 0 : }
220 : :
221 : : // decoder --------------------------------------------------------------------
222 : :
223 : 0 : void BiffInputStream::setDecoder( const BiffDecoderRef& rxDecoder )
224 : : {
225 : 0 : maRecBuffer.setDecoder( rxDecoder );
226 : 0 : }
227 : :
228 : 0 : void BiffInputStream::enableDecoder( bool bEnable )
229 : : {
230 : 0 : maRecBuffer.enableDecoder( bEnable );
231 : 0 : }
232 : :
233 : : // stream/record state and info -----------------------------------------------
234 : :
235 : 0 : sal_uInt16 BiffInputStream::getNextRecId()
236 : : {
237 : 0 : sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
238 [ # # ]: 0 : if( isInRecord() )
239 : : {
240 : 0 : sal_Int64 nCurrPos = tell(); // save current position in record
241 [ # # ]: 0 : while( jumpToNextContinue() ) {} // skip following CONTINUE records
242 [ # # ]: 0 : if( maRecBuffer.startNextRecord() ) // read header of next record
243 : 0 : nRecId = maRecBuffer.getRecId();
244 : 0 : seek( nCurrPos ); // restore position, seek() resets old mbValid state
245 : : }
246 : 0 : return nRecId;
247 : : }
248 : :
249 : : // BinaryStreamBase interface (seeking) ---------------------------------------
250 : :
251 : 0 : sal_Int64 BiffInputStream::size() const
252 : : {
253 [ # # ]: 0 : if( !mbHasComplRec )
254 : 0 : const_cast< BiffInputStream* >( this )->calcRecordLength();
255 : 0 : return mnComplRecSize;
256 : : }
257 : :
258 : 0 : sal_Int64 BiffInputStream::tell() const
259 : : {
260 [ # # ]: 0 : return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft());
261 : : }
262 : :
263 : 0 : void BiffInputStream::seek( sal_Int64 nRecPos )
264 : : {
265 [ # # ]: 0 : if( isInRecord() )
266 : : {
267 [ # # ][ # # ]: 0 : if( mbEof || (nRecPos < tell()) )
[ # # ]
268 : 0 : restartRecord( false );
269 [ # # ][ # # ]: 0 : if( !mbEof && (nRecPos > tell()) )
[ # # ]
270 : 0 : skip( static_cast< sal_Int32 >( nRecPos - tell() ) );
271 : : }
272 : 0 : }
273 : :
274 : 0 : void BiffInputStream::close()
275 : : {
276 : 0 : }
277 : :
278 : : // BinaryInputStream interface (stream read access) ---------------------------
279 : :
280 : 0 : sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
281 : : {
282 : 0 : sal_Int32 nRet = 0;
283 [ # # ]: 0 : if( !mbEof )
284 : : {
285 [ # # ][ # # ]: 0 : orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
286 [ # # ]: 0 : if( nBytes > 0 )
287 : 0 : nRet = readMemory( orData.getArray(), nBytes, nAtomSize );
288 : : }
289 : 0 : return nRet;
290 : : }
291 : :
292 : 0 : sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
293 : : {
294 : 0 : sal_Int32 nRet = 0;
295 [ # # ][ # # ]: 0 : if( !mbEof && opMem && (nBytes > 0) )
[ # # ]
296 : : {
297 : 0 : sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( opMem );
298 : 0 : sal_Int32 nBytesLeft = nBytes;
299 : :
300 [ # # ][ # # ]: 0 : while( !mbEof && (nBytesLeft > 0) )
[ # # ]
301 : : {
302 : 0 : sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
303 : : // check nReadSize, stream may already be located at end of a raw record
304 [ # # ]: 0 : if( nReadSize > 0 )
305 : : {
306 : 0 : maRecBuffer.read( pnBuffer, nReadSize );
307 : 0 : nRet += nReadSize;
308 : 0 : pnBuffer += nReadSize;
309 : 0 : nBytesLeft -= nReadSize;
310 : : }
311 [ # # ]: 0 : if( nBytesLeft > 0 )
312 : 0 : jumpToNextContinue();
313 : : OSL_ENSURE( !mbEof, "BiffInputStream::readMemory - record overread" );
314 : : }
315 : : }
316 : 0 : return nRet;
317 : : }
318 : :
319 : 0 : void BiffInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
320 : : {
321 : 0 : sal_Int32 nBytesLeft = nBytes;
322 [ # # ][ # # ]: 0 : while( !mbEof && (nBytesLeft > 0) )
[ # # ]
323 : : {
324 : 0 : sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
325 : : // check nSkipSize, stream may already be located at end of a raw record
326 [ # # ]: 0 : if( nSkipSize > 0 )
327 : : {
328 : 0 : maRecBuffer.skip( nSkipSize );
329 : 0 : nBytesLeft -= nSkipSize;
330 : : }
331 [ # # ]: 0 : if( nBytesLeft > 0 )
332 : 0 : jumpToNextContinue();
333 : : OSL_ENSURE( !mbEof, "BiffInputStream::skip - record overread" );
334 : : }
335 : 0 : }
336 : :
337 : : // byte strings ---------------------------------------------------------------
338 : :
339 : 0 : OString BiffInputStream::readByteString( bool b16BitLen, bool bAllowNulChars )
340 : : {
341 [ # # ]: 0 : sal_Int32 nStrLen = b16BitLen ? readuInt16() : readuInt8();
342 : 0 : return readCharArray( nStrLen, bAllowNulChars );
343 : : }
344 : :
345 : 0 : OUString BiffInputStream::readByteStringUC( bool b16BitLen, rtl_TextEncoding eTextEnc, bool bAllowNulChars )
346 : : {
347 [ # # ]: 0 : return OStringToOUString( readByteString( b16BitLen, bAllowNulChars ), eTextEnc );
348 : : }
349 : :
350 : : // Unicode strings ------------------------------------------------------------
351 : :
352 : 0 : OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars )
353 : : {
354 : 0 : OUStringBuffer aBuffer;
355 [ # # ]: 0 : aBuffer.ensureCapacity( nChars );
356 : :
357 : : /* This function has to react on CONTINUE records which repeat the flags
358 : : field in their first byte and may change the 8bit/16bit character mode,
359 : : thus a plain call to readCompressedUnicodeArray() cannot be used here. */
360 : 0 : sal_Int32 nCharsLeft = nChars;
361 [ # # ][ # # ]: 0 : while( !mbEof && (nCharsLeft > 0) )
[ # # ]
362 : : {
363 : : /* Read the character array from the remaining part of the current raw
364 : : record. First, calculate the maximum number of characters that can
365 : : be read without triggering to start a following CONTINUE record. */
366 [ # # ][ # # ]: 0 : sal_Int32 nRawChars = b16BitChars ? (getMaxRawReadSize( nCharsLeft * 2, 2 ) / 2) : getMaxRawReadSize( nCharsLeft, 1 );
[ # # ]
367 [ # # ][ # # ]: 0 : aBuffer.append( readCompressedUnicodeArray( nRawChars, !b16BitChars, bAllowNulChars ) );
368 : :
369 : : /* Prepare for next CONTINUE record. Calling jumpToNextStringContinue()
370 : : reads the leading byte in the following CONTINUE record and updates
371 : : the b16BitChars flag. */
372 : 0 : nCharsLeft -= nRawChars;
373 [ # # ]: 0 : if( nCharsLeft > 0 )
374 [ # # ]: 0 : jumpToNextStringContinue( b16BitChars );
375 : : }
376 : :
377 [ # # ]: 0 : return aBuffer.makeStringAndClear();
378 : : }
379 : :
380 : 0 : OUString BiffInputStream::readUniStringBody( sal_uInt16 nChars, bool bAllowNulChars )
381 : : {
382 : : bool b16BitChars;
383 : : sal_Int32 nAddSize;
384 [ # # ]: 0 : readUniStringHeader( b16BitChars, nAddSize );
385 [ # # ]: 0 : OUString aString = readUniStringChars( nChars, b16BitChars, bAllowNulChars );
386 [ # # ]: 0 : skip( nAddSize );
387 : 0 : return aString;
388 : : }
389 : :
390 : 0 : OUString BiffInputStream::readUniString( bool bAllowNulChars )
391 : : {
392 : 0 : return readUniStringBody( readuInt16(), bAllowNulChars );
393 : : }
394 : :
395 : : // private --------------------------------------------------------------------
396 : :
397 : 0 : void BiffInputStream::setupRecord()
398 : : {
399 : : // initialize class members
400 : 0 : mnRecHandle = maRecBuffer.getRecHeaderPos();
401 : 0 : mnRecId = maRecBuffer.getRecId();
402 : 0 : mnAltContId = BIFF_ID_UNKNOWN;
403 : 0 : mnCurrRecSize = mnComplRecSize = maRecBuffer.getRecSize();
404 : 0 : mbHasComplRec = !mbCont;
405 : 0 : mbEof = !isInRecord();
406 : : // enable decoder in new record
407 : 0 : enableDecoder( true );
408 : 0 : }
409 : :
410 : 0 : void BiffInputStream::restartRecord( bool bInvalidateRecSize )
411 : : {
412 [ # # ]: 0 : if( isInRecord() )
413 : : {
414 : 0 : maRecBuffer.startRecord( getRecHandle() );
415 : 0 : mnCurrRecSize = maRecBuffer.getRecSize();
416 [ # # ]: 0 : if( bInvalidateRecSize )
417 : : {
418 : 0 : mnComplRecSize = mnCurrRecSize;
419 : 0 : mbHasComplRec = !mbCont;
420 : : }
421 : 0 : mbEof = false;
422 : : }
423 : 0 : }
424 : :
425 : 0 : void BiffInputStream::rewindToRecord( sal_Int64 nRecHandle )
426 : : {
427 [ # # ]: 0 : if( nRecHandle >= 0 )
428 : : {
429 : 0 : maRecBuffer.restartAt( nRecHandle );
430 : 0 : mnRecHandle = -1;
431 : 0 : mbEof = true; // as long as the record is not started
432 : : }
433 : 0 : }
434 : :
435 : 0 : bool BiffInputStream::isContinueId( sal_uInt16 nRecId ) const
436 : : {
437 [ # # ][ # # ]: 0 : return (nRecId == BIFF_ID_CONT) || (nRecId == mnAltContId);
438 : : }
439 : :
440 : 0 : bool BiffInputStream::jumpToNextContinue()
441 : : {
442 [ # # ][ # # ]: 0 : mbEof = mbEof || !mbCont || !isContinueId( maRecBuffer.getNextRecId() ) || !maRecBuffer.startNextRecord();
[ # # ][ # # ]
443 [ # # ]: 0 : if( !mbEof )
444 : 0 : mnCurrRecSize += maRecBuffer.getRecSize();
445 : 0 : return !mbEof;
446 : : }
447 : :
448 : 0 : bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars )
449 : : {
450 : : OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - alignment error" );
451 : :
452 [ # # ][ # # ]: 0 : if( mbCont && (getRemaining() > 0) )
[ # # ][ # # ]
453 : : {
454 [ # # ]: 0 : jumpToNextContinue();
455 : : }
456 [ # # ]: 0 : else if( mnRecId == BIFF_ID_CONT )
457 : : {
458 : : /* CONTINUE handling is off, but we have started reading in a CONTINUE
459 : : record -> start next CONTINUE for TXO import. We really start a new
460 : : record here - no chance to return to string origin. */
461 [ # # ][ # # ]: 0 : mbEof = mbEof || (maRecBuffer.getNextRecId() != BIFF_ID_CONT) || !maRecBuffer.startNextRecord();
[ # # ][ # # ]
[ # # ]
462 [ # # ]: 0 : if( !mbEof )
463 [ # # ]: 0 : setupRecord();
464 : : }
465 : :
466 : : // trying to read the flags invalidates stream, if no CONTINUE record has been found
467 : : sal_uInt8 nFlags;
468 [ # # ]: 0 : readValue( nFlags );
469 : 0 : rb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
470 : 0 : return !mbEof;
471 : : }
472 : :
473 : 0 : void BiffInputStream::calcRecordLength()
474 : : {
475 : 0 : sal_Int64 nCurrPos = tell(); // save current position in record
476 [ # # ]: 0 : while( jumpToNextContinue() ) {} // jumpToNextContinue() adds up mnCurrRecSize
477 : 0 : mnComplRecSize = mnCurrRecSize;
478 : 0 : mbHasComplRec = true;
479 : 0 : seek( nCurrPos ); // restore position, seek() resets old mbValid state
480 : 0 : }
481 : :
482 : 0 : sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const
483 : : {
484 : 0 : sal_uInt16 nMaxSize = getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() );
485 [ # # ][ # # ]: 0 : if( (0 < nMaxSize) && (nMaxSize < nBytes) && (nAtomSize > 1) )
[ # # ]
486 : : {
487 : : // check that remaining data in record buffer is a multiple of the passed atom size
488 : 0 : sal_uInt16 nPadding = static_cast< sal_uInt16 >( nMaxSize % nAtomSize );
489 : : OSL_ENSURE( nPadding == 0, "BiffInputStream::getMaxRawReadSize - alignment error" );
490 : 0 : nMaxSize = nMaxSize - nPadding;
491 : : }
492 : 0 : return nMaxSize;
493 : : }
494 : :
495 : 0 : void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize )
496 : : {
497 [ # # ]: 0 : sal_uInt8 nFlags = readuInt8();
498 : : OSL_ENSURE( !getFlag( nFlags, BIFF_STRF_UNKNOWN ), "BiffInputStream::readUniStringHeader - unknown flags" );
499 : 0 : orb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
500 [ # # ][ # # ]: 0 : sal_uInt16 nFontCount = getFlag( nFlags, BIFF_STRF_RICH ) ? readuInt16() : 0;
501 [ # # ][ # # ]: 0 : sal_Int32 nPhoneticSize = getFlag( nFlags, BIFF_STRF_PHONETIC ) ? readInt32() : 0;
502 [ # # ]: 0 : ornAddSize = 4 * nFontCount + ::std::max< sal_Int32 >( 0, nPhoneticSize );
503 : 0 : }
504 : :
505 : : // ============================================================================
506 : :
507 : 0 : BiffInputStreamPos::BiffInputStreamPos( BiffInputStream& rStrm ) :
508 : : mrStrm( rStrm ),
509 : 0 : mnRecHandle( rStrm.getRecHandle() ),
510 : 0 : mnRecPos( rStrm.tell() )
511 : : {
512 : 0 : }
513 : :
514 : 0 : bool BiffInputStreamPos::restorePosition()
515 : : {
516 : 0 : bool bValidRec = mrStrm.startRecordByHandle( mnRecHandle );
517 [ # # ]: 0 : if( bValidRec )
518 : 0 : mrStrm.seek( mnRecPos );
519 [ # # ][ # # ]: 0 : return bValidRec && !mrStrm.isEof();
520 : : }
521 : :
522 : : // ============================================================================
523 : :
524 : 0 : BiffInputStreamPosGuard::BiffInputStreamPosGuard( BiffInputStream& rStrm ) :
525 : 0 : BiffInputStreamPos( rStrm )
526 : : {
527 : 0 : }
528 : :
529 : 0 : BiffInputStreamPosGuard::~BiffInputStreamPosGuard()
530 : : {
531 : 0 : restorePosition();
532 : 0 : }
533 : :
534 : : // ============================================================================
535 : :
536 : : } // namespace xls
537 [ + - ][ + - ]: 24 : } // namespace oox
538 : :
539 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|