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