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