Line data Source code
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 :
20 :
21 : #include <comphelper/docpasswordhelper.hxx>
22 : #include <comphelper/sequenceashashmap.hxx>
23 :
24 : #include "xistream.hxx"
25 : #include "xlstring.hxx"
26 : #include "xiroot.hxx"
27 :
28 : #include <vector>
29 :
30 :
31 : using namespace ::com::sun::star;
32 :
33 : // ============================================================================
34 : // Decryption
35 : // ============================================================================
36 :
37 0 : XclImpDecrypter::XclImpDecrypter() :
38 : mnError( EXC_ENCR_ERROR_UNSUPP_CRYPT ),
39 : mnOldPos( STREAM_SEEK_TO_END ),
40 0 : mnRecSize( 0 )
41 : {
42 0 : }
43 :
44 0 : XclImpDecrypter::XclImpDecrypter( const XclImpDecrypter& rSrc ) :
45 : ::comphelper::IDocPasswordVerifier(),
46 : mnError( rSrc.mnError ),
47 : mnOldPos( STREAM_SEEK_TO_END ),
48 0 : mnRecSize( 0 )
49 : {
50 0 : }
51 :
52 0 : XclImpDecrypter::~XclImpDecrypter()
53 : {
54 0 : }
55 :
56 0 : XclImpDecrypterRef XclImpDecrypter::Clone() const
57 : {
58 0 : XclImpDecrypterRef xNewDecr;
59 0 : if( IsValid() )
60 0 : xNewDecr.reset( OnClone() );
61 0 : return xNewDecr;
62 : }
63 :
64 0 : ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
65 : {
66 0 : o_rEncryptionData = OnVerifyPassword( rPassword );
67 0 : mnError = o_rEncryptionData.getLength() ? ERRCODE_NONE : ERRCODE_ABORT;
68 0 : return o_rEncryptionData.getLength() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
69 : }
70 :
71 0 : ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
72 : {
73 0 : bool bValid = OnVerifyEncryptionData( rEncryptionData );
74 0 : mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT;
75 0 : return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
76 : }
77 :
78 0 : void XclImpDecrypter::Update( SvStream& rStrm, sal_uInt16 nRecSize )
79 : {
80 0 : if( IsValid() )
81 : {
82 0 : sal_Size nNewPos = rStrm.Tell();
83 0 : if( (mnOldPos != nNewPos) || (mnRecSize != nRecSize) )
84 : {
85 0 : OnUpdate( mnOldPos, nNewPos, nRecSize );
86 0 : mnOldPos = nNewPos;
87 0 : mnRecSize = nRecSize;
88 : }
89 : }
90 0 : }
91 :
92 0 : sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes )
93 : {
94 0 : sal_uInt16 nRet = 0;
95 0 : if( pData && nBytes )
96 : {
97 0 : if( IsValid() )
98 : {
99 0 : Update( rStrm, mnRecSize );
100 0 : nRet = OnRead( rStrm, reinterpret_cast< sal_uInt8* >( pData ), nBytes );
101 0 : mnOldPos = rStrm.Tell();
102 : }
103 : else
104 0 : nRet = static_cast< sal_uInt16 >( rStrm.Read( pData, nBytes ) );
105 : }
106 0 : return nRet;
107 : }
108 :
109 : // ----------------------------------------------------------------------------
110 :
111 0 : XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) :
112 : mnKey( nKey ),
113 0 : mnHash( nHash )
114 : {
115 0 : }
116 :
117 0 : XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) :
118 : XclImpDecrypter( rSrc ),
119 : maEncryptionData( rSrc.maEncryptionData ),
120 : mnKey( rSrc.mnKey ),
121 0 : mnHash( rSrc.mnHash )
122 : {
123 0 : if( IsValid() )
124 0 : maCodec.InitCodec( maEncryptionData );
125 0 : }
126 :
127 0 : XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const
128 : {
129 0 : return new XclImpBiff5Decrypter( *this );
130 : }
131 :
132 0 : uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const OUString& rPassword )
133 : {
134 0 : maEncryptionData.realloc( 0 );
135 :
136 : /* Convert password to a byte string. TODO: this needs some finetuning
137 : according to the spec... */
138 0 : OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
139 0 : sal_Int32 nLen = aBytePassword.getLength();
140 0 : if( (0 < nLen) && (nLen < 16) )
141 : {
142 : // init codec
143 0 : maCodec.InitKey( (sal_uInt8*)aBytePassword.getStr() );
144 :
145 0 : if ( maCodec.VerifyKey( mnKey, mnHash ) )
146 : {
147 0 : maEncryptionData = maCodec.GetEncryptionData();
148 :
149 : // since the export uses Std97 encryption always we have to request it here
150 0 : ::std::vector< sal_uInt16 > aPassVect( 16 );
151 0 : ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
152 0 : for( sal_Int32 nInd = 0; nInd < nLen; ++nInd, ++aIt )
153 0 : *aIt = static_cast< sal_uInt16 >( rPassword.getStr()[nInd] );
154 :
155 0 : uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
156 : OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the senquence!" );
157 :
158 0 : ::msfilter::MSCodec_Std97 aCodec97;
159 0 : aCodec97.InitKey( &aPassVect.front(), (sal_uInt8*)aDocId.getConstArray() );
160 :
161 : // merge the EncryptionData, there should be no conflicts
162 0 : ::comphelper::SequenceAsHashMap aEncryptionHash( maEncryptionData );
163 0 : aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) );
164 0 : aEncryptionHash >> maEncryptionData;
165 : }
166 : }
167 :
168 0 : return maEncryptionData;
169 : }
170 :
171 0 : bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
172 : {
173 0 : maEncryptionData.realloc( 0 );
174 :
175 0 : if( rEncryptionData.getLength() )
176 : {
177 : // init codec
178 0 : maCodec.InitCodec( rEncryptionData );
179 :
180 0 : if ( maCodec.VerifyKey( mnKey, mnHash ) )
181 0 : maEncryptionData = rEncryptionData;
182 : }
183 :
184 0 : return maEncryptionData.getLength();
185 : }
186 :
187 0 : void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize )
188 : {
189 0 : maCodec.InitCipher();
190 0 : maCodec.Skip( (nNewStrmPos + nRecSize) & 0x0F );
191 0 : }
192 :
193 0 : sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
194 : {
195 0 : sal_uInt16 nRet = static_cast< sal_uInt16 >( rStrm.Read( pnData, nBytes ) );
196 0 : maCodec.Decode( pnData, nRet );
197 0 : return nRet;
198 : }
199 :
200 : // ----------------------------------------------------------------------------
201 :
202 0 : XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
203 : sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
204 : maSalt( pnSalt, pnSalt + 16 ),
205 : maVerifier( pnVerifier, pnVerifier + 16 ),
206 0 : maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
207 : {
208 0 : }
209 :
210 0 : XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) :
211 : XclImpDecrypter( rSrc ),
212 : maEncryptionData( rSrc.maEncryptionData ),
213 : maSalt( rSrc.maSalt ),
214 : maVerifier( rSrc.maVerifier ),
215 0 : maVerifierHash( rSrc.maVerifierHash )
216 : {
217 0 : if( IsValid() )
218 0 : maCodec.InitCodec( maEncryptionData );
219 0 : }
220 :
221 0 : XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const
222 : {
223 0 : return new XclImpBiff8Decrypter( *this );
224 : }
225 :
226 0 : uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const OUString& rPassword )
227 : {
228 0 : maEncryptionData.realloc( 0 );
229 :
230 0 : sal_Int32 nLen = rPassword.getLength();
231 0 : if( (0 < nLen) && (nLen < 16) )
232 : {
233 : // copy string to sal_uInt16 array
234 0 : ::std::vector< sal_uInt16 > aPassVect( 16 );
235 0 : const sal_Unicode* pcChar = rPassword.getStr();
236 0 : const sal_Unicode* pcCharEnd = pcChar + nLen;
237 0 : ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
238 0 : for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
239 0 : *aIt = static_cast< sal_uInt16 >( *pcChar );
240 :
241 : // init codec
242 0 : maCodec.InitKey( &aPassVect.front(), &maSalt.front() );
243 0 : if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
244 0 : maEncryptionData = maCodec.GetEncryptionData();
245 : }
246 :
247 0 : return maEncryptionData;
248 : }
249 :
250 0 : bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
251 : {
252 0 : maEncryptionData.realloc( 0 );
253 :
254 0 : if( rEncryptionData.getLength() )
255 : {
256 : // init codec
257 0 : maCodec.InitCodec( rEncryptionData );
258 :
259 0 : if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
260 0 : maEncryptionData = rEncryptionData;
261 : }
262 :
263 0 : return maEncryptionData.getLength();
264 : }
265 :
266 0 : void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ )
267 : {
268 0 : if( nNewStrmPos != nOldStrmPos )
269 : {
270 0 : sal_uInt32 nOldBlock = GetBlock( nOldStrmPos );
271 0 : sal_uInt16 nOldOffset = GetOffset( nOldStrmPos );
272 :
273 0 : sal_uInt32 nNewBlock = GetBlock( nNewStrmPos );
274 0 : sal_uInt16 nNewOffset = GetOffset( nNewStrmPos );
275 :
276 : /* Rekey cipher, if block changed or if previous offset in same block. */
277 0 : if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
278 : {
279 0 : maCodec.InitCipher( nNewBlock );
280 0 : nOldOffset = 0; // reset nOldOffset for next if() statement
281 : }
282 :
283 : /* Seek to correct offset. */
284 0 : if( nNewOffset > nOldOffset )
285 0 : maCodec.Skip( nNewOffset - nOldOffset );
286 : }
287 0 : }
288 :
289 0 : sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
290 : {
291 0 : sal_uInt16 nRet = 0;
292 :
293 0 : sal_uInt8* pnCurrData = pnData;
294 0 : sal_uInt16 nBytesLeft = nBytes;
295 0 : while( nBytesLeft )
296 : {
297 0 : sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - GetOffset( rStrm.Tell() );
298 0 : sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
299 :
300 : // read the block from stream
301 0 : nRet = nRet + static_cast< sal_uInt16 >( rStrm.Read( pnCurrData, nDecBytes ) );
302 : // decode the block inplace
303 0 : maCodec.Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
304 0 : if( GetOffset( rStrm.Tell() ) == 0 )
305 0 : maCodec.InitCipher( GetBlock( rStrm.Tell() ) );
306 :
307 0 : pnCurrData += nDecBytes;
308 0 : nBytesLeft = nBytesLeft - nDecBytes;
309 : }
310 :
311 0 : return nRet;
312 : }
313 :
314 0 : sal_uInt32 XclImpBiff8Decrypter::GetBlock( sal_Size nStrmPos ) const
315 : {
316 0 : return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
317 : }
318 :
319 0 : sal_uInt16 XclImpBiff8Decrypter::GetOffset( sal_Size nStrmPos ) const
320 : {
321 0 : return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
322 : }
323 :
324 : // ============================================================================
325 : // Stream
326 : // ============================================================================
327 :
328 8596 : XclImpStreamPos::XclImpStreamPos() :
329 : mnPos( STREAM_SEEK_TO_BEGIN ),
330 : mnNextPos( STREAM_SEEK_TO_BEGIN ),
331 : mnCurrSize( 0 ),
332 : mnRawRecId( EXC_ID_UNKNOWN ),
333 : mnRawRecSize( 0 ),
334 : mnRawRecLeft( 0 ),
335 8596 : mbValid( false )
336 : {
337 8596 : }
338 :
339 899314 : void XclImpStreamPos::Set(
340 : const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize,
341 : sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
342 : bool bValid )
343 : {
344 899314 : mnPos = rStrm.Tell();
345 899314 : mnNextPos = nNextPos;
346 899314 : mnCurrSize = nCurrSize;
347 899314 : mnRawRecId = nRawRecId;
348 899314 : mnRawRecSize = nRawRecSize;
349 899314 : mnRawRecLeft = nRawRecLeft;
350 899314 : mbValid = bValid;
351 899314 : }
352 :
353 9335 : void XclImpStreamPos::Get(
354 : SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize,
355 : sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
356 : bool& rbValid ) const
357 : {
358 9335 : rStrm.Seek( mnPos );
359 9335 : rnNextPos = mnNextPos;
360 9335 : rnCurrSize = mnCurrSize;
361 9335 : rnRawRecId = mnRawRecId;
362 9335 : rnRawRecSize = mnRawRecSize;
363 9335 : rnRawRecLeft = mnRawRecLeft;
364 9335 : rbValid = mbValid;
365 9335 : }
366 :
367 : // ============================================================================
368 :
369 47 : XclBiff XclImpStream::DetectBiffVersion( SvStream& rStrm )
370 : {
371 47 : XclBiff eBiff = EXC_BIFF_UNKNOWN;
372 :
373 47 : rStrm.Seek( STREAM_SEEK_TO_BEGIN );
374 : sal_uInt16 nBofId, nBofSize;
375 47 : rStrm >> nBofId >> nBofSize;
376 :
377 47 : if( (4 <= nBofSize) && (nBofSize <= 16) ) switch( nBofId )
378 : {
379 : case EXC_ID2_BOF:
380 0 : eBiff = EXC_BIFF2;
381 0 : break;
382 : case EXC_ID3_BOF:
383 0 : eBiff = EXC_BIFF3;
384 0 : break;
385 : case EXC_ID4_BOF:
386 0 : eBiff = EXC_BIFF4;
387 0 : break;
388 : case EXC_ID5_BOF:
389 : {
390 : sal_uInt16 nVersion;
391 46 : rStrm >> nVersion;
392 : // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
393 46 : switch( nVersion & 0xFF00 )
394 : {
395 0 : case 0: eBiff = EXC_BIFF5; break; // #i44031# #i62752#
396 0 : case EXC_BOF_BIFF2: eBiff = EXC_BIFF2; break;
397 0 : case EXC_BOF_BIFF3: eBiff = EXC_BIFF3; break;
398 0 : case EXC_BOF_BIFF4: eBiff = EXC_BIFF4; break;
399 0 : case EXC_BOF_BIFF5: eBiff = EXC_BIFF5; break;
400 46 : case EXC_BOF_BIFF8: eBiff = EXC_BIFF8; break;
401 : default: OSL_TRACE( "XclImpStream::DetectBiffVersion - unknown BIFF version: 0x%04hX", nVersion );
402 : }
403 : }
404 46 : break;
405 : }
406 47 : return eBiff;
407 : }
408 :
409 131 : XclImpStream::XclImpStream( SvStream& rInStrm, const XclImpRoot& rRoot, bool bContLookup ) :
410 : mrStrm( rInStrm ),
411 : mrRoot( rRoot ),
412 : mnGlobRecId( EXC_ID_UNKNOWN ),
413 : mbGlobValidRec( false ),
414 : mbHasGlobPos( false ),
415 : mnNextRecPos( STREAM_SEEK_TO_BEGIN ),
416 : mnCurrRecSize( 0 ),
417 : mnComplRecSize( 0 ),
418 : mbHasComplRec( false ),
419 : mnRecId( EXC_ID_UNKNOWN ),
420 : mnAltContId( EXC_ID_UNKNOWN ),
421 : mnRawRecId( EXC_ID_UNKNOWN ),
422 : mnRawRecSize( 0 ),
423 : mnRawRecLeft( 0 ),
424 : mcNulSubst( '?' ),
425 : mbCont( bContLookup ),
426 : mbUseDecr( false ),
427 : mbValidRec( false ),
428 131 : mbValid( false )
429 : {
430 131 : mrStrm.Seek( STREAM_SEEK_TO_END );
431 131 : mnStreamSize = mrStrm.Tell();
432 131 : mrStrm.Seek( STREAM_SEEK_TO_BEGIN );
433 : OSL_ENSURE( mnStreamSize < STREAM_SEEK_TO_END, "XclImpStream::XclImpStream - stream error" );
434 131 : }
435 :
436 131 : XclImpStream::~XclImpStream()
437 : {
438 131 : }
439 :
440 890779 : bool XclImpStream::StartNextRecord()
441 : {
442 890779 : maPosStack.clear();
443 :
444 : /* #i4266# Counter to ignore zero records (id==len==0) (i.e. the application
445 : "Crystal Report" writes zero records between other records) */
446 890779 : sal_Size nZeroRecCount = 5;
447 890779 : bool bIsZeroRec = false;
448 :
449 890828 : do
450 : {
451 890828 : mbValidRec = ReadNextRawRecHeader();
452 890828 : bIsZeroRec = (mnRawRecId == 0) && (mnRawRecSize == 0);
453 890828 : if( bIsZeroRec ) --nZeroRecCount;
454 890828 : mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
455 : }
456 890828 : while( mbValidRec && ((mbCont && IsContinueId( mnRawRecId )) || (bIsZeroRec && nZeroRecCount)) );
457 :
458 890779 : mbValidRec = mbValidRec && !bIsZeroRec;
459 890779 : mbValid = mbValidRec;
460 890779 : SetupRecord();
461 :
462 890779 : return mbValidRec;
463 : }
464 :
465 156 : bool XclImpStream::StartNextRecord( sal_Size nNextRecPos )
466 : {
467 156 : mnNextRecPos = nNextRecPos;
468 156 : return StartNextRecord();
469 : }
470 :
471 445 : void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
472 : {
473 445 : if( mbValidRec )
474 : {
475 445 : maPosStack.clear();
476 445 : RestorePosition( maFirstRec );
477 445 : mnCurrRecSize = mnComplRecSize = mnRawRecSize;
478 445 : mbHasComplRec = !bContLookup;
479 445 : mbCont = bContLookup;
480 445 : mnAltContId = nAltContId;
481 445 : EnableDecryption();
482 : }
483 445 : }
484 :
485 0 : void XclImpStream::RewindRecord()
486 : {
487 0 : mnNextRecPos = maFirstRec.GetPos();
488 0 : mbValid = mbValidRec = false;
489 0 : }
490 :
491 1 : void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter )
492 : {
493 1 : mxDecrypter = xDecrypter;
494 1 : EnableDecryption();
495 1 : SetupDecrypter();
496 1 : }
497 :
498 1 : void XclImpStream::CopyDecrypterFrom( const XclImpStream& rStrm )
499 : {
500 1 : XclImpDecrypterRef xNewDecr;
501 1 : if( rStrm.mxDecrypter )
502 0 : xNewDecr = rStrm.mxDecrypter->Clone();
503 1 : SetDecrypter( xNewDecr );
504 1 : }
505 :
506 891461 : bool XclImpStream::HasValidDecrypter() const
507 : {
508 891461 : return mxDecrypter && mxDecrypter->IsValid();
509 : }
510 :
511 891820 : void XclImpStream::EnableDecryption( bool bEnable )
512 : {
513 891820 : mbUseDecr = bEnable && HasValidDecrypter();
514 891820 : }
515 :
516 : // ----------------------------------------------------------------------------
517 :
518 8202 : void XclImpStream::PushPosition()
519 : {
520 8202 : maPosStack.push_back( XclImpStreamPos() );
521 8202 : StorePosition( maPosStack.back() );
522 8202 : }
523 :
524 8202 : void XclImpStream::PopPosition()
525 : {
526 : OSL_ENSURE( !maPosStack.empty(), "XclImpStream::PopPosition - stack empty" );
527 8202 : if( !maPosStack.empty() )
528 : {
529 8202 : RestorePosition( maPosStack.back() );
530 8202 : maPosStack.pop_back();
531 : }
532 8202 : }
533 :
534 201 : void XclImpStream::StoreGlobalPosition()
535 : {
536 201 : StorePosition( maGlobPos );
537 201 : mnGlobRecId = mnRecId;
538 201 : mbGlobValidRec = mbValidRec;
539 201 : mbHasGlobPos = true;
540 201 : }
541 :
542 201 : void XclImpStream::SeekGlobalPosition()
543 : {
544 : OSL_ENSURE( mbHasGlobPos, "XclImpStream::SeekGlobalPosition - no position stored" );
545 201 : if( mbHasGlobPos )
546 : {
547 201 : RestorePosition( maGlobPos );
548 201 : mnRecId = mnGlobRecId;
549 201 : mnComplRecSize = mnCurrRecSize;
550 201 : mbHasComplRec = !mbCont;
551 201 : mbValidRec = mbGlobValidRec;
552 : }
553 201 : }
554 :
555 72263 : sal_Size XclImpStream::GetRecPos() const
556 : {
557 72263 : return mbValid ? (mnCurrRecSize - mnRawRecLeft) : EXC_REC_SEEK_TO_END;
558 : }
559 :
560 42397 : sal_Size XclImpStream::GetRecSize()
561 : {
562 42397 : if( !mbHasComplRec )
563 : {
564 4693 : PushPosition();
565 4693 : while( JumpToNextContinue() ) ; // JumpToNextContinue() adds up mnCurrRecSize
566 4693 : mnComplRecSize = mnCurrRecSize;
567 4693 : mbHasComplRec = true;
568 4693 : PopPosition();
569 : }
570 42397 : return mnComplRecSize;
571 : }
572 :
573 42075 : sal_Size XclImpStream::GetRecLeft()
574 : {
575 42075 : return mbValid ? (GetRecSize() - GetRecPos()) : 0;
576 : }
577 :
578 2425 : sal_uInt16 XclImpStream::GetNextRecId()
579 : {
580 2425 : sal_uInt16 nRecId = EXC_ID_UNKNOWN;
581 2425 : if( mbValidRec )
582 : {
583 2425 : PushPosition();
584 2425 : while( JumpToNextContinue() ) ; // skip following CONTINUE records
585 2425 : if( mnNextRecPos < mnStreamSize )
586 : {
587 2425 : mrStrm.Seek( mnNextRecPos );
588 2425 : mrStrm >> nRecId;
589 : }
590 2425 : PopPosition();
591 : }
592 2425 : return nRecId;
593 : }
594 :
595 156 : sal_uInt16 XclImpStream::PeekRecId( sal_Size nPos )
596 : {
597 156 : sal_uInt16 nRecId = EXC_ID_UNKNOWN;
598 156 : if (mbValidRec && nPos < mnStreamSize)
599 : {
600 156 : sal_Size nCurPos = mrStrm.Tell();
601 156 : mrStrm.Seek(nPos);
602 156 : mrStrm >> nRecId;
603 156 : mrStrm.Seek(nCurPos);
604 : }
605 156 : return nRecId;
606 : }
607 :
608 : // ----------------------------------------------------------------------------
609 :
610 0 : XclImpStream& XclImpStream::operator>>( sal_Int8& rnValue )
611 : {
612 0 : if( EnsureRawReadSize( 1 ) )
613 : {
614 0 : if( mbUseDecr )
615 0 : mxDecrypter->Read( mrStrm, &rnValue, 1 );
616 : else
617 0 : mrStrm >> rnValue;
618 0 : --mnRawRecLeft;
619 : }
620 0 : return *this;
621 : }
622 :
623 89729 : XclImpStream& XclImpStream::operator>>( sal_uInt8& rnValue )
624 : {
625 89729 : if( EnsureRawReadSize( 1 ) )
626 : {
627 87909 : if( mbUseDecr )
628 0 : mxDecrypter->Read( mrStrm, &rnValue, 1 );
629 : else
630 87909 : mrStrm >> rnValue;
631 87909 : --mnRawRecLeft;
632 : }
633 89729 : return *this;
634 : }
635 :
636 1249 : XclImpStream& XclImpStream::operator>>( sal_Int16& rnValue )
637 : {
638 1249 : if( EnsureRawReadSize( 2 ) )
639 : {
640 1249 : if( mbUseDecr )
641 : {
642 : SVBT16 pnBuffer;
643 0 : mxDecrypter->Read( mrStrm, pnBuffer, 2 );
644 0 : rnValue = static_cast< sal_Int16 >( SVBT16ToShort( pnBuffer ) );
645 : }
646 : else
647 1249 : mrStrm >> rnValue;
648 1249 : mnRawRecLeft -= 2;
649 : }
650 1249 : return *this;
651 : }
652 :
653 1586413 : XclImpStream& XclImpStream::operator>>( sal_uInt16& rnValue )
654 : {
655 1586413 : if( EnsureRawReadSize( 2 ) )
656 : {
657 1586413 : if( mbUseDecr )
658 : {
659 : SVBT16 pnBuffer;
660 0 : mxDecrypter->Read( mrStrm, pnBuffer, 2 );
661 0 : rnValue = SVBT16ToShort( pnBuffer );
662 : }
663 : else
664 1586413 : mrStrm >> rnValue;
665 1586413 : mnRawRecLeft -= 2;
666 : }
667 1586413 : return *this;
668 : }
669 :
670 14759 : XclImpStream& XclImpStream::operator>>( sal_Int32& rnValue )
671 : {
672 14759 : if( EnsureRawReadSize( 4 ) )
673 : {
674 14759 : if( mbUseDecr )
675 : {
676 : SVBT32 pnBuffer;
677 0 : mxDecrypter->Read( mrStrm, pnBuffer, 4 );
678 0 : rnValue = static_cast< sal_Int32 >( SVBT32ToUInt32( pnBuffer ) );
679 : }
680 : else
681 14759 : mrStrm >> rnValue;
682 14759 : mnRawRecLeft -= 4;
683 : }
684 14759 : return *this;
685 : }
686 :
687 17175 : XclImpStream& XclImpStream::operator>>( sal_uInt32& rnValue )
688 : {
689 17175 : if( EnsureRawReadSize( 4 ) )
690 : {
691 17175 : if( mbUseDecr )
692 : {
693 : SVBT32 pnBuffer;
694 0 : mxDecrypter->Read( mrStrm, pnBuffer, 4 );
695 0 : rnValue = SVBT32ToUInt32( pnBuffer );
696 : }
697 : else
698 17175 : mrStrm >> rnValue;
699 17175 : mnRawRecLeft -= 4;
700 : }
701 17175 : return *this;
702 : }
703 :
704 0 : XclImpStream& XclImpStream::operator>>( float& rfValue )
705 : {
706 0 : if( EnsureRawReadSize( 4 ) )
707 : {
708 0 : if( mbUseDecr )
709 : {
710 : SVBT32 pnBuffer;
711 0 : mxDecrypter->Read( mrStrm, pnBuffer, 4 );
712 0 : sal_uInt32 nValue = SVBT32ToUInt32( pnBuffer );
713 0 : memcpy( &rfValue, &nValue, 4 );
714 : }
715 : else
716 0 : mrStrm >> rfValue;
717 0 : mnRawRecLeft -= 4;
718 : }
719 0 : return *this;
720 : }
721 :
722 5650 : XclImpStream& XclImpStream::operator>>( double& rfValue )
723 : {
724 5650 : if( EnsureRawReadSize( 8 ) )
725 : {
726 5650 : if( mbUseDecr )
727 : {
728 : SVBT64 pnBuffer;
729 0 : mxDecrypter->Read( mrStrm, pnBuffer, 8 );
730 0 : rfValue = SVBT64ToDouble( pnBuffer );
731 : }
732 : else
733 5650 : mrStrm >> rfValue;
734 5650 : mnRawRecLeft -= 8;
735 : }
736 5650 : return *this;
737 : }
738 :
739 6120 : sal_uInt8 XclImpStream::ReaduInt8()
740 : {
741 6120 : sal_uInt8 nValue(0);
742 6120 : operator>>( nValue );
743 6120 : return nValue;
744 : }
745 :
746 992 : sal_Int16 XclImpStream::ReadInt16()
747 : {
748 992 : sal_Int16 nValue(0);
749 992 : operator>>( nValue );
750 992 : return nValue;
751 : }
752 :
753 225783 : sal_uInt16 XclImpStream::ReaduInt16()
754 : {
755 225783 : sal_uInt16 nValue(0);
756 225783 : operator>>( nValue );
757 225783 : return nValue;
758 : }
759 :
760 0 : sal_Int32 XclImpStream::ReadInt32()
761 : {
762 0 : sal_Int32 nValue(0);
763 0 : operator>>( nValue );
764 0 : return nValue;
765 : }
766 :
767 417 : sal_uInt32 XclImpStream::ReaduInt32()
768 : {
769 417 : sal_uInt32 nValue(0);
770 417 : operator>>( nValue );
771 417 : return nValue;
772 : }
773 :
774 154 : double XclImpStream::ReadDouble()
775 : {
776 154 : double fValue(0.0);
777 154 : operator>>( fValue );
778 154 : return fValue;
779 : }
780 :
781 435 : sal_Size XclImpStream::Read( void* pData, sal_Size nBytes )
782 : {
783 435 : sal_Size nRet = 0;
784 435 : if( mbValid && pData && (nBytes > 0) )
785 : {
786 435 : sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( pData );
787 435 : sal_Size nBytesLeft = nBytes;
788 :
789 1306 : while( mbValid && (nBytesLeft > 0) )
790 : {
791 436 : sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
792 436 : sal_uInt16 nReadRet = ReadRawData( pnBuffer, nReadSize );
793 436 : nRet += nReadRet;
794 436 : mbValid = (nReadSize == nReadRet);
795 : OSL_ENSURE( mbValid, "XclImpStream::Read - stream read error" );
796 436 : pnBuffer += nReadRet;
797 436 : nBytesLeft -= nReadRet;
798 436 : if( mbValid && (nBytesLeft > 0) )
799 1 : JumpToNextContinue();
800 : OSL_ENSURE( mbValid, "XclImpStream::Read - record overread" );
801 : }
802 : }
803 435 : return nRet;
804 : }
805 :
806 332 : sal_Size XclImpStream::CopyToStream( SvStream& rOutStrm, sal_Size nBytes )
807 : {
808 332 : sal_Size nRet = 0;
809 332 : if( mbValid && (nBytes > 0) )
810 : {
811 332 : const sal_Size nMaxBuffer = 4096;
812 332 : sal_uInt8* pnBuffer = new sal_uInt8[ ::std::min( nBytes, nMaxBuffer ) ];
813 332 : sal_Size nBytesLeft = nBytes;
814 :
815 999 : while( mbValid && (nBytesLeft > 0) )
816 : {
817 335 : sal_Size nReadSize = ::std::min( nBytesLeft, nMaxBuffer );
818 335 : nRet += Read( pnBuffer, nReadSize );
819 : // writing more bytes than read results in invalid memory access
820 : SAL_WARN_IF(nRet != nReadSize, "sc", "read less bytes than requested");
821 335 : rOutStrm.Write( pnBuffer, nReadSize );
822 335 : nBytesLeft -= nReadSize;
823 : }
824 :
825 332 : delete[] pnBuffer;
826 : }
827 332 : return nRet;
828 : }
829 :
830 237 : sal_Size XclImpStream::CopyRecordToStream( SvStream& rOutStrm )
831 : {
832 237 : sal_Size nRet = 0;
833 237 : if( mbValidRec )
834 : {
835 237 : PushPosition();
836 237 : RestorePosition( maFirstRec );
837 237 : nRet = CopyToStream( rOutStrm, GetRecSize() );
838 237 : PopPosition();
839 : }
840 237 : return nRet;
841 : }
842 :
843 2765 : void XclImpStream::Seek( sal_Size nPos )
844 : {
845 2765 : if( mbValidRec )
846 : {
847 2765 : sal_Size nCurrPos = GetRecPos();
848 2765 : if( !mbValid || (nPos < nCurrPos) ) // from invalid state or backward
849 : {
850 118 : RestorePosition( maFirstRec );
851 118 : Ignore( nPos );
852 : }
853 2647 : else if( nPos > nCurrPos ) // forward
854 : {
855 46 : Ignore( nPos - nCurrPos );
856 : }
857 : }
858 2765 : }
859 :
860 414293 : void XclImpStream::Ignore( sal_Size nBytes )
861 : {
862 : // implementation similar to Read(), but without really reading anything
863 414293 : sal_Size nBytesLeft = nBytes;
864 1235744 : while( mbValid && (nBytesLeft > 0) )
865 : {
866 407158 : sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
867 407158 : mrStrm.SeekRel( nReadSize );
868 407158 : mnRawRecLeft = mnRawRecLeft - nReadSize;
869 407158 : nBytesLeft -= nReadSize;
870 407158 : if( nBytesLeft > 0 )
871 2 : JumpToNextContinue();
872 : OSL_ENSURE( mbValid, "XclImpStream::Ignore - record overread" );
873 : }
874 414293 : }
875 :
876 : // ----------------------------------------------------------------------------
877 :
878 7083 : sal_Size XclImpStream::ReadUniStringExtHeader(
879 : bool& rb16Bit, bool& rbRich, bool& rbFareast,
880 : sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags )
881 : {
882 : OSL_ENSURE( !::get_flag( nFlags, EXC_STRF_UNKNOWN ), "XclImpStream::ReadUniStringExt - unknown flags" );
883 7083 : rb16Bit = ::get_flag( nFlags, EXC_STRF_16BIT );
884 7083 : rbRich = ::get_flag( nFlags, EXC_STRF_RICH );
885 7083 : rbFareast = ::get_flag( nFlags, EXC_STRF_FAREAST );
886 7083 : rnFormatRuns = rbRich ? ReaduInt16() : 0;
887 7083 : rnExtInf = rbFareast ? ReaduInt32() : 0;
888 7083 : return rnExtInf + 4 * rnFormatRuns;
889 : }
890 :
891 5134 : sal_Size XclImpStream::ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags )
892 : {
893 : bool bRich, bFareast;
894 : sal_uInt16 nCrun;
895 : sal_uInt32 nExtInf;
896 5134 : return ReadUniStringExtHeader( rb16Bit, bRich, bFareast, nCrun, nExtInf, nFlags );
897 : }
898 :
899 : // ----------------------------------------------------------------------------
900 :
901 7091 : String XclImpStream::ReadRawUniString( sal_uInt16 nChars, bool b16Bit )
902 : {
903 7091 : String aRet;
904 7091 : sal_uInt16 nCharsLeft = nChars;
905 : sal_uInt16 nReadSize;
906 :
907 7091 : sal_Unicode* pcBuffer = new sal_Unicode[ nCharsLeft + 1 ];
908 :
909 21267 : while( IsValid() && (nCharsLeft > 0) )
910 : {
911 7085 : if( b16Bit )
912 : {
913 1377 : nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
914 : OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
915 : "XclImpStream::ReadRawUniString - missing a byte" );
916 : }
917 : else
918 5708 : nReadSize = GetMaxRawReadSize( nCharsLeft );
919 :
920 7085 : sal_Unicode* pcUniChar = pcBuffer;
921 7085 : sal_Unicode* pcEndChar = pcBuffer + nReadSize;
922 :
923 7085 : if( b16Bit )
924 : {
925 : sal_uInt16 nReadChar;
926 31826 : for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
927 : {
928 30449 : operator>>( nReadChar );
929 30449 : (*pcUniChar) = (nReadChar == EXC_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
930 : }
931 : }
932 : else
933 : {
934 : sal_uInt8 nReadChar;
935 49597 : for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
936 : {
937 43889 : operator>>( nReadChar );
938 43889 : (*pcUniChar) = (nReadChar == EXC_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
939 : }
940 : }
941 :
942 7085 : *pcEndChar = '\0';
943 7085 : aRet.Append( pcBuffer );
944 :
945 7085 : nCharsLeft = nCharsLeft - nReadSize;
946 7085 : if( nCharsLeft > 0 )
947 3 : JumpToNextStringContinue( b16Bit );
948 : }
949 :
950 7091 : delete[] pcBuffer;
951 7091 : return aRet;
952 : }
953 :
954 5134 : String XclImpStream::ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
955 : {
956 : bool b16Bit;
957 5134 : sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
958 5134 : String aRet( ReadRawUniString( nChars, b16Bit ) );
959 5134 : Ignore( nExtSize );
960 5134 : return aRet;
961 : }
962 :
963 5134 : String XclImpStream::ReadUniString( sal_uInt16 nChars )
964 : {
965 5134 : return ReadUniString( nChars, ReaduInt8() );
966 : }
967 :
968 1522 : String XclImpStream::ReadUniString()
969 : {
970 1522 : return ReadUniString( ReaduInt16() );
971 : }
972 :
973 0 : void XclImpStream::IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit )
974 : {
975 0 : sal_uInt16 nCharsLeft = nChars;
976 : sal_uInt16 nReadSize;
977 :
978 0 : while( IsValid() && (nCharsLeft > 0) )
979 : {
980 0 : if( b16Bit )
981 : {
982 0 : nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
983 : OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
984 : "XclImpStream::IgnoreRawUniString - missing a byte" );
985 0 : Ignore( nReadSize * 2 );
986 : }
987 : else
988 : {
989 0 : nReadSize = GetMaxRawReadSize( nCharsLeft );
990 0 : Ignore( nReadSize );
991 : }
992 :
993 0 : nCharsLeft = nCharsLeft - nReadSize;
994 0 : if( nCharsLeft > 0 )
995 0 : JumpToNextStringContinue( b16Bit );
996 : }
997 0 : }
998 :
999 0 : void XclImpStream::IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
1000 : {
1001 : bool b16Bit;
1002 0 : sal_Size nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
1003 0 : IgnoreRawUniString( nChars, b16Bit );
1004 0 : Ignore( nExtSize );
1005 0 : }
1006 :
1007 0 : void XclImpStream::IgnoreUniString( sal_uInt16 nChars )
1008 : {
1009 0 : IgnoreUniString( nChars, ReaduInt8() );
1010 0 : }
1011 :
1012 : // ----------------------------------------------------------------------------
1013 :
1014 0 : String XclImpStream::ReadRawByteString( sal_uInt16 nChars )
1015 : {
1016 0 : sal_Char* pcBuffer = new sal_Char[ nChars + 1 ];
1017 0 : sal_uInt16 nCharsRead = ReadRawData( pcBuffer, nChars );
1018 0 : pcBuffer[ nCharsRead ] = '\0';
1019 0 : String aRet( pcBuffer, mrRoot.GetTextEncoding() );
1020 0 : delete[] pcBuffer;
1021 0 : return aRet;
1022 : }
1023 :
1024 0 : String XclImpStream::ReadByteString( bool b16BitLen )
1025 : {
1026 0 : return ReadRawByteString( ReadByteStrLen( b16BitLen ) );
1027 : }
1028 :
1029 : // private --------------------------------------------------------------------
1030 :
1031 899314 : void XclImpStream::StorePosition( XclImpStreamPos& rPos )
1032 : {
1033 899314 : rPos.Set( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
1034 899314 : }
1035 :
1036 9335 : void XclImpStream::RestorePosition( const XclImpStreamPos& rPos )
1037 : {
1038 9335 : rPos.Get( mrStrm, mnNextRecPos, mnCurrRecSize, mnRawRecId, mnRawRecSize, mnRawRecLeft, mbValid );
1039 9335 : SetupDecrypter();
1040 9335 : }
1041 :
1042 897467 : bool XclImpStream::ReadNextRawRecHeader()
1043 : {
1044 897467 : sal_Size nSeekedPos = mrStrm.Seek( mnNextRecPos );
1045 897467 : bool bRet = (nSeekedPos == mnNextRecPos) && (mnNextRecPos + 4 <= mnStreamSize);
1046 897467 : if( bRet )
1047 : {
1048 897380 : mrStrm >> mnRawRecId >> mnRawRecSize;
1049 897380 : bRet = mrStrm.good();
1050 : }
1051 897467 : return bRet;
1052 : }
1053 :
1054 900122 : void XclImpStream::SetupDecrypter()
1055 : {
1056 900122 : if( mxDecrypter )
1057 0 : mxDecrypter->Update( mrStrm, mnRawRecSize );
1058 900122 : }
1059 :
1060 890786 : void XclImpStream::SetupRawRecord()
1061 : {
1062 : // pre: mnRawRecSize contains current raw record size
1063 : // pre: mrStrm points to start of raw record data
1064 890786 : mnNextRecPos = mrStrm.Tell() + mnRawRecSize;
1065 890786 : mnRawRecLeft = mnRawRecSize;
1066 890786 : mnCurrRecSize += mnRawRecSize;
1067 890786 : SetupDecrypter(); // decrypter works on raw record level
1068 890786 : }
1069 :
1070 890779 : void XclImpStream::SetupRecord()
1071 : {
1072 890779 : mnRecId = mnRawRecId;
1073 890779 : mnAltContId = EXC_ID_UNKNOWN;
1074 890779 : mnCurrRecSize = 0;
1075 890779 : mnComplRecSize = mnRawRecSize;
1076 890779 : mbHasComplRec = !mbCont;
1077 890779 : SetupRawRecord();
1078 890779 : SetNulSubstChar();
1079 890779 : EnableDecryption();
1080 890779 : StorePosition( maFirstRec );
1081 890779 : }
1082 :
1083 897125 : bool XclImpStream::IsContinueId( sal_uInt16 nRecId ) const
1084 : {
1085 897125 : return (nRecId == EXC_ID_CONT) || (nRecId == mnAltContId);
1086 : }
1087 :
1088 7129 : bool XclImpStream::JumpToNextContinue()
1089 : {
1090 7129 : mbValid = mbValid && mbCont && ReadNextRawRecHeader() && IsContinueId( mnRawRecId );
1091 7129 : if( mbValid ) // do not setup a following non-CONTINUE record
1092 7 : SetupRawRecord();
1093 7129 : return mbValid;
1094 : }
1095 :
1096 3 : bool XclImpStream::JumpToNextStringContinue( bool& rb16Bit )
1097 : {
1098 : OSL_ENSURE( mnRawRecLeft == 0, "XclImpStream::JumpToNextStringContinue - unexpected garbage" );
1099 :
1100 3 : if( mbCont && (GetRecLeft() > 0) )
1101 : {
1102 3 : JumpToNextContinue();
1103 : }
1104 0 : else if( mnRecId == EXC_ID_CONT )
1105 : {
1106 : // CONTINUE handling is off, but we have started reading in a CONTINUE record
1107 : // -> start next CONTINUE for TXO import
1108 0 : mbValidRec = ReadNextRawRecHeader() && ((mnRawRecId != 0) || (mnRawRecSize > 0));
1109 0 : mbValid = mbValidRec && (mnRawRecId == EXC_ID_CONT);
1110 : // we really start a new record here - no chance to return to string origin
1111 0 : if( mbValid )
1112 0 : SetupRecord();
1113 : }
1114 : else
1115 0 : mbValid = false;
1116 :
1117 3 : if( mbValid )
1118 2 : rb16Bit = ::get_flag( ReaduInt8(), EXC_STRF_16BIT );
1119 3 : return mbValid;
1120 : }
1121 :
1122 1714975 : bool XclImpStream::EnsureRawReadSize( sal_uInt16 nBytes )
1123 : {
1124 1714975 : if( mbValid && nBytes )
1125 : {
1126 1713156 : while( mbValid && !mnRawRecLeft ) JumpToNextContinue();
1127 1713156 : mbValid = mbValid && (nBytes <= mnRawRecLeft);
1128 : OSL_ENSURE( mbValid, "XclImpStream::EnsureRawReadSize - record overread" );
1129 : }
1130 1714975 : return mbValid;
1131 : }
1132 :
1133 413302 : sal_uInt16 XclImpStream::GetMaxRawReadSize( sal_Size nBytes ) const
1134 : {
1135 413302 : return static_cast< sal_uInt16 >( ::std::min< sal_Size >( nBytes, mnRawRecLeft ) );
1136 : }
1137 :
1138 436 : sal_uInt16 XclImpStream::ReadRawData( void* pData, sal_uInt16 nBytes )
1139 : {
1140 : OSL_ENSURE( (nBytes <= mnRawRecLeft), "XclImpStream::ReadRawData - record overread" );
1141 436 : sal_uInt16 nRet = 0;
1142 436 : if( mbUseDecr )
1143 0 : nRet = mxDecrypter->Read( mrStrm, pData, nBytes );
1144 : else
1145 436 : nRet = static_cast< sal_uInt16 >( mrStrm.Read( pData, nBytes ) );
1146 436 : mnRawRecLeft = mnRawRecLeft - nRet;
1147 436 : return nRet;
1148 : }
1149 :
1150 : // ============================================================================
1151 :
1152 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|