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