1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski #ifndef SC_XISTREAM_HXX 25*b1cdbd2cSJim Jagielski #define SC_XISTREAM_HXX 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <comphelper/docpasswordhelper.hxx> 28*b1cdbd2cSJim Jagielski #include <filter/msfilter/mscodec.hxx> 29*b1cdbd2cSJim Jagielski #include "xlstream.hxx" 30*b1cdbd2cSJim Jagielski #include "xlconst.hxx" 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski class XclImpRoot; 33*b1cdbd2cSJim Jagielski 34*b1cdbd2cSJim Jagielski /* ============================================================================ 35*b1cdbd2cSJim Jagielski Input stream class for Excel import 36*b1cdbd2cSJim Jagielski - CONTINUE record handling 37*b1cdbd2cSJim Jagielski - ByteString and UniString support 38*b1cdbd2cSJim Jagielski - Decryption 39*b1cdbd2cSJim Jagielski ============================================================================ */ 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski // ============================================================================ 42*b1cdbd2cSJim Jagielski // Decryption 43*b1cdbd2cSJim Jagielski // ============================================================================ 44*b1cdbd2cSJim Jagielski 45*b1cdbd2cSJim Jagielski class XclImpDecrypter; 46*b1cdbd2cSJim Jagielski typedef ScfRef< XclImpDecrypter > XclImpDecrypterRef; 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski /** Base class for BIFF stream decryption. */ 49*b1cdbd2cSJim Jagielski class XclImpDecrypter : public ::comphelper::IDocPasswordVerifier 50*b1cdbd2cSJim Jagielski { 51*b1cdbd2cSJim Jagielski public: 52*b1cdbd2cSJim Jagielski explicit XclImpDecrypter(); 53*b1cdbd2cSJim Jagielski virtual ~XclImpDecrypter(); 54*b1cdbd2cSJim Jagielski 55*b1cdbd2cSJim Jagielski /** Returns the current error code of the decrypter. */ GetError() const56*b1cdbd2cSJim Jagielski inline ErrCode GetError() const { return mnError; } 57*b1cdbd2cSJim Jagielski /** Returns true, if the decoder has been initialized correctly. */ IsValid() const58*b1cdbd2cSJim Jagielski inline bool IsValid() const { return mnError == ERRCODE_NONE; } 59*b1cdbd2cSJim Jagielski 60*b1cdbd2cSJim Jagielski /** Creates a (ref-counted) copy of this decrypter object. */ 61*b1cdbd2cSJim Jagielski XclImpDecrypterRef Clone() const; 62*b1cdbd2cSJim Jagielski 63*b1cdbd2cSJim Jagielski /** Implementation of the ::comphelper::IDocPasswordVerifier interface */ 64*b1cdbd2cSJim Jagielski virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ); 65*b1cdbd2cSJim Jagielski virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski /** Updates the decrypter on start of a new record or after seeking stream. */ 68*b1cdbd2cSJim Jagielski void Update( SvStream& rStrm, sal_uInt16 nRecSize ); 69*b1cdbd2cSJim Jagielski /** Reads and decrypts nBytes bytes and stores data into the existing(!) buffer pData. 70*b1cdbd2cSJim Jagielski @return Count of bytes really read. */ 71*b1cdbd2cSJim Jagielski sal_uInt16 Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes ); 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski protected: 74*b1cdbd2cSJim Jagielski /** Protected copy c'tor for OnClone(). */ 75*b1cdbd2cSJim Jagielski explicit XclImpDecrypter( const XclImpDecrypter& rSrc ); 76*b1cdbd2cSJim Jagielski 77*b1cdbd2cSJim Jagielski private: 78*b1cdbd2cSJim Jagielski /** Implementation of cloning this object. */ 79*b1cdbd2cSJim Jagielski virtual XclImpDecrypter* OnClone() const = 0; 80*b1cdbd2cSJim Jagielski /** Derived classes implement password verification and initialization of 81*b1cdbd2cSJim Jagielski the decoder. */ 82*b1cdbd2cSJim Jagielski virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > 83*b1cdbd2cSJim Jagielski OnVerifyPassword( const ::rtl::OUString& rPassword ) = 0; 84*b1cdbd2cSJim Jagielski virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0; 85*b1cdbd2cSJim Jagielski 86*b1cdbd2cSJim Jagielski /** Implementation of updating the decrypter. */ 87*b1cdbd2cSJim Jagielski virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) = 0; 88*b1cdbd2cSJim Jagielski /** Implementation of the decryption. */ 89*b1cdbd2cSJim Jagielski virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ) = 0; 90*b1cdbd2cSJim Jagielski 91*b1cdbd2cSJim Jagielski private: 92*b1cdbd2cSJim Jagielski ErrCode mnError; /// Decrypter error code. 93*b1cdbd2cSJim Jagielski sal_Size mnOldPos; /// Last known stream position. 94*b1cdbd2cSJim Jagielski sal_uInt16 mnRecSize; /// Current record size. 95*b1cdbd2cSJim Jagielski }; 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski // ---------------------------------------------------------------------------- 98*b1cdbd2cSJim Jagielski 99*b1cdbd2cSJim Jagielski /** Decrypts BIFF5 stream contents. */ 100*b1cdbd2cSJim Jagielski class XclImpBiff5Decrypter : public XclImpDecrypter 101*b1cdbd2cSJim Jagielski { 102*b1cdbd2cSJim Jagielski public: 103*b1cdbd2cSJim Jagielski explicit XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ); 104*b1cdbd2cSJim Jagielski 105*b1cdbd2cSJim Jagielski private: 106*b1cdbd2cSJim Jagielski /** Private copy c'tor for OnClone(). */ 107*b1cdbd2cSJim Jagielski explicit XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ); 108*b1cdbd2cSJim Jagielski 109*b1cdbd2cSJim Jagielski /** Implementation of cloning this object. */ 110*b1cdbd2cSJim Jagielski virtual XclImpBiff5Decrypter* OnClone() const; 111*b1cdbd2cSJim Jagielski /** Implements password verification and initialization of the decoder. */ 112*b1cdbd2cSJim Jagielski virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > 113*b1cdbd2cSJim Jagielski OnVerifyPassword( const ::rtl::OUString& rPassword ); 114*b1cdbd2cSJim Jagielski virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); 115*b1cdbd2cSJim Jagielski /** Implementation of updating the decrypter. */ 116*b1cdbd2cSJim Jagielski virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); 117*b1cdbd2cSJim Jagielski /** Implementation of the decryption. */ 118*b1cdbd2cSJim Jagielski virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ); 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski private: 121*b1cdbd2cSJim Jagielski ::msfilter::MSCodec_XorXLS95 maCodec; /// Crypto algorithm implementation. 122*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; 123*b1cdbd2cSJim Jagielski sal_uInt16 mnKey; 124*b1cdbd2cSJim Jagielski sal_uInt16 mnHash; 125*b1cdbd2cSJim Jagielski }; 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski // ---------------------------------------------------------------------------- 128*b1cdbd2cSJim Jagielski 129*b1cdbd2cSJim Jagielski /** Decrypts BIFF8 stream contents using the given document identifier. */ 130*b1cdbd2cSJim Jagielski class XclImpBiff8Decrypter : public XclImpDecrypter 131*b1cdbd2cSJim Jagielski { 132*b1cdbd2cSJim Jagielski public: 133*b1cdbd2cSJim Jagielski explicit XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ], 134*b1cdbd2cSJim Jagielski sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ); 135*b1cdbd2cSJim Jagielski 136*b1cdbd2cSJim Jagielski private: 137*b1cdbd2cSJim Jagielski /** Private copy c'tor for OnClone(). */ 138*b1cdbd2cSJim Jagielski explicit XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ); 139*b1cdbd2cSJim Jagielski 140*b1cdbd2cSJim Jagielski /** Implementation of cloning this object. */ 141*b1cdbd2cSJim Jagielski virtual XclImpBiff8Decrypter* OnClone() const; 142*b1cdbd2cSJim Jagielski /** Implements password verification and initialization of the decoder. */ 143*b1cdbd2cSJim Jagielski virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > 144*b1cdbd2cSJim Jagielski OnVerifyPassword( const ::rtl::OUString& rPassword ); 145*b1cdbd2cSJim Jagielski virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); 146*b1cdbd2cSJim Jagielski /** Implementation of updating the decrypter. */ 147*b1cdbd2cSJim Jagielski virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); 148*b1cdbd2cSJim Jagielski /** Implementation of the decryption. */ 149*b1cdbd2cSJim Jagielski virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ); 150*b1cdbd2cSJim Jagielski 151*b1cdbd2cSJim Jagielski /** Returns the block number corresponding to the passed stream position. */ 152*b1cdbd2cSJim Jagielski sal_uInt32 GetBlock( sal_Size nStrmPos ) const; 153*b1cdbd2cSJim Jagielski /** Returns the block offset corresponding to the passed stream position. */ 154*b1cdbd2cSJim Jagielski sal_uInt16 GetOffset( sal_Size nStrmPos ) const; 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski private: 157*b1cdbd2cSJim Jagielski ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation. 158*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; 159*b1cdbd2cSJim Jagielski ::std::vector< sal_uInt8 > maSalt; 160*b1cdbd2cSJim Jagielski ::std::vector< sal_uInt8 > maVerifier; 161*b1cdbd2cSJim Jagielski ::std::vector< sal_uInt8 > maVerifierHash; 162*b1cdbd2cSJim Jagielski }; 163*b1cdbd2cSJim Jagielski 164*b1cdbd2cSJim Jagielski // ============================================================================ 165*b1cdbd2cSJim Jagielski // Stream 166*b1cdbd2cSJim Jagielski // ============================================================================ 167*b1cdbd2cSJim Jagielski 168*b1cdbd2cSJim Jagielski /** This class represents an Excel stream position. 169*b1cdbd2cSJim Jagielski @descr It contains the relevant data for a stream position inside of a record 170*b1cdbd2cSJim Jagielski (including CONTINUE records). */ 171*b1cdbd2cSJim Jagielski class XclImpStreamPos 172*b1cdbd2cSJim Jagielski { 173*b1cdbd2cSJim Jagielski public: 174*b1cdbd2cSJim Jagielski /** Constructs an invalid stream position data object. */ 175*b1cdbd2cSJim Jagielski explicit XclImpStreamPos(); 176*b1cdbd2cSJim Jagielski 177*b1cdbd2cSJim Jagielski /** Sets the stream position data to the passed values. */ 178*b1cdbd2cSJim Jagielski void Set( const SvStream& rStrm, sal_Size nNextPos, sal_Size nCurrSize, 179*b1cdbd2cSJim Jagielski sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft, 180*b1cdbd2cSJim Jagielski bool bValid ); 181*b1cdbd2cSJim Jagielski 182*b1cdbd2cSJim Jagielski /** Writes the contained stream position data to the given variables. */ 183*b1cdbd2cSJim Jagielski void Get( SvStream& rStrm, sal_Size& rnNextPos, sal_Size& rnCurrSize, 184*b1cdbd2cSJim Jagielski sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft, 185*b1cdbd2cSJim Jagielski bool& rbValid ) const; 186*b1cdbd2cSJim Jagielski 187*b1cdbd2cSJim Jagielski /** Returns the stored stream position. */ GetPos() const188*b1cdbd2cSJim Jagielski inline sal_Size GetPos() const { return mnPos; } 189*b1cdbd2cSJim Jagielski 190*b1cdbd2cSJim Jagielski private: 191*b1cdbd2cSJim Jagielski sal_Size mnPos; /// Absolute position of the stream. 192*b1cdbd2cSJim Jagielski sal_Size mnNextPos; /// Absolute position of next record. 193*b1cdbd2cSJim Jagielski sal_Size mnCurrSize; /// Current calculated size of the record. 194*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs). 195*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs). 196*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs). 197*b1cdbd2cSJim Jagielski bool mbValid; /// Read state: false = record overread. 198*b1cdbd2cSJim Jagielski }; 199*b1cdbd2cSJim Jagielski 200*b1cdbd2cSJim Jagielski // ============================================================================ 201*b1cdbd2cSJim Jagielski 202*b1cdbd2cSJim Jagielski /** This class is used to import record oriented streams. 203*b1cdbd2cSJim Jagielski @descr An instance is constructed with an SvStream. The SvStream stream is 204*b1cdbd2cSJim Jagielski reset to its start while constructing this stream. 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski To start reading a record call StartNextRecord(). Now it is possible to 207*b1cdbd2cSJim Jagielski read all contents of the record using operator>>() or any of the Read***() 208*b1cdbd2cSJim Jagielski functions. If some data exceeds the record size limit, the stream looks for 209*b1cdbd2cSJim Jagielski a following CONTINUE record and jumps automatically to it. It is NOT 210*b1cdbd2cSJim Jagielski allowed that an atomic data type is split into two records (i.e. 4 bytes of 211*b1cdbd2cSJim Jagielski a double in one record and the other 4 bytes in a following CONTINUE). 212*b1cdbd2cSJim Jagielski 213*b1cdbd2cSJim Jagielski Trying to read over the record limits results in a stream error. The 214*b1cdbd2cSJim Jagielski IsValid() function indicates that with returning false. From now on it is 215*b1cdbd2cSJim Jagielski undefined what data the read functions will return. The error state will be 216*b1cdbd2cSJim Jagielski reset, if the record is reset (with the method ResetRecord()) or if the 217*b1cdbd2cSJim Jagielski next record is started. 218*b1cdbd2cSJim Jagielski 219*b1cdbd2cSJim Jagielski To switch off the automatic lookup of CONTINUE records, use ResetRecord() 220*b1cdbd2cSJim Jagielski with false parameter. This is useful i.e. on import of Escher objects, 221*b1cdbd2cSJim Jagielski where sometimes solely CONTINUE records will occur. The automatic lookup 222*b1cdbd2cSJim Jagielski keeps switched off until the method ResetRecord() is called with parameter 223*b1cdbd2cSJim Jagielski true. All other settings done on the stream (i.e. alternative CONTINUE 224*b1cdbd2cSJim Jagielski record identifier, enabled decryption, NUL substitution character) will be 225*b1cdbd2cSJim Jagielski reset to default values, if a new record is started. 226*b1cdbd2cSJim Jagielski 227*b1cdbd2cSJim Jagielski The import stream supports decrypting the stream data. The contents of a 228*b1cdbd2cSJim Jagielski record (not the record header) will be encrypted by Excel if the file has 229*b1cdbd2cSJim Jagielski been stored with password protection. The functions SetDecrypter(), 230*b1cdbd2cSJim Jagielski EnableDecryption(), and DisableDecryption() control the usage of the 231*b1cdbd2cSJim Jagielski decryption algorithms. SetDecrypter() sets a new decryption algorithm and 232*b1cdbd2cSJim Jagielski initially enables it. DisableDecryption() may be used to stop the usage of 233*b1cdbd2cSJim Jagielski the decryption temporarily (sometimes record contents are never encrypted, 234*b1cdbd2cSJim Jagielski i.e. all BOF records or the stream position in BOUNDSHEET). Decryption will 235*b1cdbd2cSJim Jagielski be reenabled automatically, if a new record is started with the function 236*b1cdbd2cSJim Jagielski StartNextRecord(). 237*b1cdbd2cSJim Jagielski 238*b1cdbd2cSJim Jagielski It is possible to store several stream positions inside a record (including 239*b1cdbd2cSJim Jagielski its CONTINUE records). The positions are stored on a stack, which can be 240*b1cdbd2cSJim Jagielski controlled with the functions PushPosition(), PopPosition() and 241*b1cdbd2cSJim Jagielski RejectPosition(). The stack will be cleared whenever a new record is 242*b1cdbd2cSJim Jagielski started with the function StartNextRecord(). 243*b1cdbd2cSJim Jagielski 244*b1cdbd2cSJim Jagielski Additionally a single global stream position can be stored which keeps 245*b1cdbd2cSJim Jagielski valid during the whole import process (methods StoreGlobalPosition(), 246*b1cdbd2cSJim Jagielski SeekGlobalPosition() and DeleteGlobalPosition()). This is the only way to 247*b1cdbd2cSJim Jagielski jump back to a previous record (that is a real jump without return). 248*b1cdbd2cSJim Jagielski */ 249*b1cdbd2cSJim Jagielski class XclImpStream 250*b1cdbd2cSJim Jagielski { 251*b1cdbd2cSJim Jagielski public: 252*b1cdbd2cSJim Jagielski /** Detects the BIFF version of the passed workbook stream. */ 253*b1cdbd2cSJim Jagielski static XclBiff DetectBiffVersion( SvStream& rStrm ); 254*b1cdbd2cSJim Jagielski 255*b1cdbd2cSJim Jagielski /** Constructs the Excel record import stream using a TOOLS stream object. 256*b1cdbd2cSJim Jagielski @param rInStrm The system input stream. Will be set to its start position. 257*b1cdbd2cSJim Jagielski Must exist as long as this object exists. 258*b1cdbd2cSJim Jagielski @param bContLookup Automatic CONTINUE lookup on/off. */ 259*b1cdbd2cSJim Jagielski explicit XclImpStream( 260*b1cdbd2cSJim Jagielski SvStream& rInStrm, 261*b1cdbd2cSJim Jagielski const XclImpRoot& rRoot, 262*b1cdbd2cSJim Jagielski bool bContLookup = true ); 263*b1cdbd2cSJim Jagielski 264*b1cdbd2cSJim Jagielski ~XclImpStream(); 265*b1cdbd2cSJim Jagielski 266*b1cdbd2cSJim Jagielski /** Returns the filter root data. */ GetRoot() const267*b1cdbd2cSJim Jagielski inline const XclImpRoot& GetRoot() const { return mrRoot; } 268*b1cdbd2cSJim Jagielski 269*b1cdbd2cSJim Jagielski /** Sets stream pointer to the start of the next record content. 270*b1cdbd2cSJim Jagielski @descr Ignores all CONTINUE records of the current record, if automatic 271*b1cdbd2cSJim Jagielski CONTINUE usage is switched on. 272*b1cdbd2cSJim Jagielski @return false = no record found (end of stream). */ 273*b1cdbd2cSJim Jagielski bool StartNextRecord(); 274*b1cdbd2cSJim Jagielski /** Sets stream pointer to the start of the record content for the record 275*b1cdbd2cSJim Jagielski at the passed absolute stream position. 276*b1cdbd2cSJim Jagielski @return false = no record found (end of stream). */ 277*b1cdbd2cSJim Jagielski bool StartNextRecord( sal_Size nNextRecPos ); 278*b1cdbd2cSJim Jagielski /** Sets stream pointer to begin of record content. 279*b1cdbd2cSJim Jagielski @param bContLookup Automatic CONTINUE lookup on/off. In difference 280*b1cdbd2cSJim Jagielski to other stream settings, this setting is persistent until next call of 281*b1cdbd2cSJim Jagielski this function (because it is wanted to receive the next CONTINUE 282*b1cdbd2cSJim Jagielski records separately). 283*b1cdbd2cSJim Jagielski @param nAltContId Sets an alternative record ID for content 284*b1cdbd2cSJim Jagielski continuation. This value is reset automatically when a new record is 285*b1cdbd2cSJim Jagielski started with StartNextRecord(). */ 286*b1cdbd2cSJim Jagielski void ResetRecord( bool bContLookup, 287*b1cdbd2cSJim Jagielski sal_uInt16 nAltContId = EXC_ID_UNKNOWN ); 288*b1cdbd2cSJim Jagielski /** Sets stream pointer before current record and invalidates stream. 289*b1cdbd2cSJim Jagielski @descr The next call to StartNextRecord() will start again the current 290*b1cdbd2cSJim Jagielski record. This can be used in situations where a loop or a function 291*b1cdbd2cSJim Jagielski leaves on a specific record, but the parent context expects to start 292*b1cdbd2cSJim Jagielski this record by itself. The stream is invalid as long as the first 293*b1cdbd2cSJim Jagielski record has not been started (it is not allowed to call any other stream 294*b1cdbd2cSJim Jagielski operation then). */ 295*b1cdbd2cSJim Jagielski void RewindRecord(); 296*b1cdbd2cSJim Jagielski 297*b1cdbd2cSJim Jagielski /** Enables decryption of record contents for the rest of the stream. */ 298*b1cdbd2cSJim Jagielski void SetDecrypter( XclImpDecrypterRef xDecrypter ); 299*b1cdbd2cSJim Jagielski /** Sets decrypter from another stream. */ 300*b1cdbd2cSJim Jagielski void CopyDecrypterFrom( const XclImpStream& rStrm ); 301*b1cdbd2cSJim Jagielski /** Returns true, if a valid decrypter is set at the stream. */ 302*b1cdbd2cSJim Jagielski bool HasValidDecrypter() const; 303*b1cdbd2cSJim Jagielski /** Switches usage of current decryption algorithm on/off. 304*b1cdbd2cSJim Jagielski @descr Encryption is re-enabled automatically, if a new record is 305*b1cdbd2cSJim Jagielski started using the function StartNextRecord(). */ 306*b1cdbd2cSJim Jagielski void EnableDecryption( bool bEnable = true ); 307*b1cdbd2cSJim Jagielski /** Switches usage of current decryption algorithm off. 308*b1cdbd2cSJim Jagielski @descr This is a record-local setting. The function StartNextRecord() 309*b1cdbd2cSJim Jagielski always enables decryption. */ DisableDecryption()310*b1cdbd2cSJim Jagielski inline void DisableDecryption() { EnableDecryption( false ); } 311*b1cdbd2cSJim Jagielski 312*b1cdbd2cSJim Jagielski /** Pushes current position on user position stack. 313*b1cdbd2cSJim Jagielski @descr This stack is emptied when starting a new record with 314*b1cdbd2cSJim Jagielski StartNextRecord(). The decryption state (enabled/disabled) is not 315*b1cdbd2cSJim Jagielski pushed onto the stack. */ 316*b1cdbd2cSJim Jagielski void PushPosition(); 317*b1cdbd2cSJim Jagielski /** Seeks to last position from user position stack. 318*b1cdbd2cSJim Jagielski @descr This position will be removed from the stack. */ 319*b1cdbd2cSJim Jagielski void PopPosition(); 320*b1cdbd2cSJim Jagielski //UNUSED2008-05 /** Removes last position from user position stack, but does not seek to it. */ 321*b1cdbd2cSJim Jagielski //UNUSED2008-05 void RejectPosition(); 322*b1cdbd2cSJim Jagielski 323*b1cdbd2cSJim Jagielski /** Stores current position. This position keeps valid in all records. */ 324*b1cdbd2cSJim Jagielski void StoreGlobalPosition(); 325*b1cdbd2cSJim Jagielski /** Seeks to the stored global user position. */ 326*b1cdbd2cSJim Jagielski void SeekGlobalPosition(); 327*b1cdbd2cSJim Jagielski /** Invalidates global user position. */ DeleteGlobalPosition()328*b1cdbd2cSJim Jagielski inline void DeleteGlobalPosition() { mbHasGlobPos = false; } 329*b1cdbd2cSJim Jagielski 330*b1cdbd2cSJim Jagielski /** Returns record reading state: false = record overread. */ IsValid() const331*b1cdbd2cSJim Jagielski inline bool IsValid() const { return mbValid; } 332*b1cdbd2cSJim Jagielski /** Returns the current record ID. */ GetRecId() const333*b1cdbd2cSJim Jagielski inline sal_uInt16 GetRecId() const { return mnRecId; } 334*b1cdbd2cSJim Jagielski /** Returns the position inside of the whole record content. */ 335*b1cdbd2cSJim Jagielski sal_Size GetRecPos() const; 336*b1cdbd2cSJim Jagielski /** Returns the data size of the whole record without record headers. */ 337*b1cdbd2cSJim Jagielski sal_Size GetRecSize(); 338*b1cdbd2cSJim Jagielski /** Returns remaining data size of the whole record without record headers. */ 339*b1cdbd2cSJim Jagielski sal_Size GetRecLeft(); 340*b1cdbd2cSJim Jagielski /** Returns the record ID of the following record. */ 341*b1cdbd2cSJim Jagielski sal_uInt16 GetNextRecId(); 342*b1cdbd2cSJim Jagielski 343*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_Int8& rnValue ); 344*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_uInt8& rnValue ); 345*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_Int16& rnValue ); 346*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_uInt16& rnValue ); 347*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_Int32& rnValue ); 348*b1cdbd2cSJim Jagielski XclImpStream& operator>>( sal_uInt32& rnValue ); 349*b1cdbd2cSJim Jagielski XclImpStream& operator>>( float& rfValue ); 350*b1cdbd2cSJim Jagielski XclImpStream& operator>>( double& rfValue ); 351*b1cdbd2cSJim Jagielski 352*b1cdbd2cSJim Jagielski sal_Int8 ReadInt8(); 353*b1cdbd2cSJim Jagielski sal_uInt8 ReaduInt8(); 354*b1cdbd2cSJim Jagielski sal_Int16 ReadInt16(); 355*b1cdbd2cSJim Jagielski sal_uInt16 ReaduInt16(); 356*b1cdbd2cSJim Jagielski sal_Int32 ReadInt32(); 357*b1cdbd2cSJim Jagielski sal_uInt32 ReaduInt32(); 358*b1cdbd2cSJim Jagielski float ReadFloat(); 359*b1cdbd2cSJim Jagielski double ReadDouble(); 360*b1cdbd2cSJim Jagielski 361*b1cdbd2cSJim Jagielski /** Reads nBytes bytes to the existing(!) buffer pData. 362*b1cdbd2cSJim Jagielski @return Count of bytes really read. */ 363*b1cdbd2cSJim Jagielski sal_Size Read( void* pData, sal_Size nBytes ); 364*b1cdbd2cSJim Jagielski /** Copies nBytes bytes to rOutStrm. 365*b1cdbd2cSJim Jagielski @return Count of bytes really written. */ 366*b1cdbd2cSJim Jagielski sal_Size CopyToStream( SvStream& rOutStrm, sal_Size nBytes ); 367*b1cdbd2cSJim Jagielski 368*b1cdbd2cSJim Jagielski /** Copies the entire record to rOutStrm. The current record position keeps unchanged. 369*b1cdbd2cSJim Jagielski @return Count of bytes really written. */ 370*b1cdbd2cSJim Jagielski sal_Size CopyRecordToStream( SvStream& rOutStrm ); 371*b1cdbd2cSJim Jagielski 372*b1cdbd2cSJim Jagielski /** Seeks absolute in record content to the specified position. 373*b1cdbd2cSJim Jagielski @descr The value 0 means start of record, independent from physical stream position. */ 374*b1cdbd2cSJim Jagielski void Seek( sal_Size nPos ); 375*b1cdbd2cSJim Jagielski /** Seeks forward inside the current record. */ 376*b1cdbd2cSJim Jagielski void Ignore( sal_Size nBytes ); 377*b1cdbd2cSJim Jagielski 378*b1cdbd2cSJim Jagielski // *** special string functions *** --------------------------------------- 379*b1cdbd2cSJim Jagielski 380*b1cdbd2cSJim Jagielski // *** read/ignore unicode strings *** ------------------------------------ 381*b1cdbd2cSJim Jagielski /* - look for CONTINUE records even if CONTINUE handling disabled 382*b1cdbd2cSJim Jagielski (only if inside of a CONTINUE record - for TXO import) 383*b1cdbd2cSJim Jagielski - no overread assertions (for Applix wrong string length export bug) 384*b1cdbd2cSJim Jagielski 385*b1cdbd2cSJim Jagielski structure of an Excel unicode string: 386*b1cdbd2cSJim Jagielski (1) 2 byte character count 387*b1cdbd2cSJim Jagielski (2) 1 byte flags (16-bit-characters, rich string, far east string) 388*b1cdbd2cSJim Jagielski (3) [2 byte rich string format run count] 389*b1cdbd2cSJim Jagielski (4) [4 byte far east data size] 390*b1cdbd2cSJim Jagielski (5) character array 391*b1cdbd2cSJim Jagielski (6) [4 * (rich string format run count) byte] 392*b1cdbd2cSJim Jagielski (7) [(far east data size) byte] 393*b1cdbd2cSJim Jagielski header = (1), (2) 394*b1cdbd2cSJim Jagielski ext. header = (3), (4) 395*b1cdbd2cSJim Jagielski ext. data = (6), (7) 396*b1cdbd2cSJim Jagielski */ 397*b1cdbd2cSJim Jagielski 398*b1cdbd2cSJim Jagielski /** Reads ext. header, detects 8/16 bit mode, sets all ext. info. 399*b1cdbd2cSJim Jagielski @return Total size of ext. data. */ 400*b1cdbd2cSJim Jagielski sal_Size ReadUniStringExtHeader( 401*b1cdbd2cSJim Jagielski bool& rb16Bit, bool& rbRich, bool& rbFareast, 402*b1cdbd2cSJim Jagielski sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags ); 403*b1cdbd2cSJim Jagielski /** Seeks to begin of character array, detects 8/16 bit mode. 404*b1cdbd2cSJim Jagielski @return Total size of ext. data. */ 405*b1cdbd2cSJim Jagielski sal_Size ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags ); 406*b1cdbd2cSJim Jagielski 407*b1cdbd2cSJim Jagielski /** Sets a replacement character for NUL characters. 408*b1cdbd2cSJim Jagielski @descr NUL characters must be replaced, because Tools strings cannot 409*b1cdbd2cSJim Jagielski handle them. The substitution character is reset to '?' automatically, 410*b1cdbd2cSJim Jagielski if a new record is started using the function StartNextRecord(). 411*b1cdbd2cSJim Jagielski @param cNulSubst The character to use for NUL replacement. It is 412*b1cdbd2cSJim Jagielski possible to specify NUL here. in this case strings are terminated when 413*b1cdbd2cSJim Jagielski the first NUL occurs during string import. */ SetNulSubstChar(sal_Unicode cNulSubst='?')414*b1cdbd2cSJim Jagielski inline void SetNulSubstChar( sal_Unicode cNulSubst = '?' ) { mcNulSubst = cNulSubst; } 415*b1cdbd2cSJim Jagielski 416*b1cdbd2cSJim Jagielski /** Reads nChars characters and returns the string. */ 417*b1cdbd2cSJim Jagielski String ReadRawUniString( sal_uInt16 nChars, bool b16Bit ); 418*b1cdbd2cSJim Jagielski /** Reads ext. header, nChar characters, ext. data and returns the string. */ 419*b1cdbd2cSJim Jagielski String ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags ); 420*b1cdbd2cSJim Jagielski /** Reads 8 bit flags, ext. header, nChar characters, ext. data and returns the string. */ 421*b1cdbd2cSJim Jagielski String ReadUniString( sal_uInt16 nChars ); 422*b1cdbd2cSJim Jagielski /** Reads 16 bit character count, 8 bit flags, ext. header, character array, 423*b1cdbd2cSJim Jagielski ext. data and returns the string. */ 424*b1cdbd2cSJim Jagielski String ReadUniString(); 425*b1cdbd2cSJim Jagielski 426*b1cdbd2cSJim Jagielski /** Ignores nChars characters. */ 427*b1cdbd2cSJim Jagielski void IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit ); 428*b1cdbd2cSJim Jagielski /** Ignores ext. header, nChar characters, ext. data. */ 429*b1cdbd2cSJim Jagielski void IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags ); 430*b1cdbd2cSJim Jagielski /** Ignores 8 bit flags, ext. header, nChar characters, ext. data. */ 431*b1cdbd2cSJim Jagielski void IgnoreUniString( sal_uInt16 nChars ); 432*b1cdbd2cSJim Jagielski /** Ignores 16 bit character count, 8 bit flags, ext. header, character array, ext. data. */ 433*b1cdbd2cSJim Jagielski void IgnoreUniString(); 434*b1cdbd2cSJim Jagielski 435*b1cdbd2cSJim Jagielski // *** read/ignore 8-bit-strings, store in String *** --------------------- 436*b1cdbd2cSJim Jagielski 437*b1cdbd2cSJim Jagielski /** Reads nChar byte characters and returns the string. */ 438*b1cdbd2cSJim Jagielski String ReadRawByteString( sal_uInt16 nChars ); 439*b1cdbd2cSJim Jagielski /** Reads 8/16 bit string length, character array and returns the string. */ 440*b1cdbd2cSJim Jagielski String ReadByteString( bool b16BitLen ); 441*b1cdbd2cSJim Jagielski 442*b1cdbd2cSJim Jagielski // *** SvStream functions *** --------------------------------------------- 443*b1cdbd2cSJim Jagielski 444*b1cdbd2cSJim Jagielski /** Returns the absolute stream position. */ GetSvStreamPos() const445*b1cdbd2cSJim Jagielski inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); } 446*b1cdbd2cSJim Jagielski /** Returns the stream size. */ GetSvStreamSize() const447*b1cdbd2cSJim Jagielski inline sal_Size GetSvStreamSize() const { return mnStreamSize; } 448*b1cdbd2cSJim Jagielski 449*b1cdbd2cSJim Jagielski private: 450*b1cdbd2cSJim Jagielski /** Stores current stream position into rPos. */ 451*b1cdbd2cSJim Jagielski void StorePosition( XclImpStreamPos& rPos ); 452*b1cdbd2cSJim Jagielski /** Restores stream position contained in rPos. */ 453*b1cdbd2cSJim Jagielski void RestorePosition( const XclImpStreamPos& rPos ); 454*b1cdbd2cSJim Jagielski 455*b1cdbd2cSJim Jagielski /** Seeks to next raw record header and reads record ID and size. 456*b1cdbd2cSJim Jagielski @descr This is a "raw" function, means that stream members are 457*b1cdbd2cSJim Jagielski inconsistent after return. Does only change mnRawRecId, mnRawRecSize, 458*b1cdbd2cSJim Jagielski and the base stream position, but no other members. 459*b1cdbd2cSJim Jagielski @return false = No record header found (end of stream). */ 460*b1cdbd2cSJim Jagielski bool ReadNextRawRecHeader(); 461*b1cdbd2cSJim Jagielski 462*b1cdbd2cSJim Jagielski /** Initializes the decrypter to read a new record. */ 463*b1cdbd2cSJim Jagielski void SetupDecrypter(); 464*b1cdbd2cSJim Jagielski /** Initializes all members after base stream has been seeked to new raw record. */ 465*b1cdbd2cSJim Jagielski void SetupRawRecord(); 466*b1cdbd2cSJim Jagielski /** Initializes all members after base stream has been seeked to new record. */ 467*b1cdbd2cSJim Jagielski void SetupRecord(); 468*b1cdbd2cSJim Jagielski 469*b1cdbd2cSJim Jagielski /** Returns true, if the passed ID is real or alternative continuation record ID. */ 470*b1cdbd2cSJim Jagielski bool IsContinueId( sal_uInt16 nRecId ) const; 471*b1cdbd2cSJim Jagielski 472*b1cdbd2cSJim Jagielski /** Goes to start of the next CONTINUE record. 473*b1cdbd2cSJim Jagielski @descr Stream must be located at the end of a raw record, and handling 474*b1cdbd2cSJim Jagielski of CONTINUE records must be enabled. 475*b1cdbd2cSJim Jagielski @return Copy of mbValid. */ 476*b1cdbd2cSJim Jagielski bool JumpToNextContinue(); 477*b1cdbd2cSJim Jagielski /** Goes to start of the next CONTINUE record while reading strings. 478*b1cdbd2cSJim Jagielski @descr Stream must be located at the end of a raw record. If reading 479*b1cdbd2cSJim Jagielski has been started in a CONTINUE record, jumps to an existing following 480*b1cdbd2cSJim Jagielski CONTINUE record, even if handling of CONTINUE records is disabled (This 481*b1cdbd2cSJim Jagielski is a special handling for TXO string data). Reads additional Unicode 482*b1cdbd2cSJim Jagielski flag byte at start of the new raw record and sets or resets rb16Bit. 483*b1cdbd2cSJim Jagielski @return Copy of mbValid. */ 484*b1cdbd2cSJim Jagielski bool JumpToNextStringContinue( bool& rb16Bit ); 485*b1cdbd2cSJim Jagielski 486*b1cdbd2cSJim Jagielski /** Ensures that reading nBytes bytes is possible with next stream access. 487*b1cdbd2cSJim Jagielski @descr Stream must be located at the end of a raw record, and handling 488*b1cdbd2cSJim Jagielski of CONTINUE records must be enabled. 489*b1cdbd2cSJim Jagielski @return Copy of mbValid. */ 490*b1cdbd2cSJim Jagielski bool EnsureRawReadSize( sal_uInt16 nBytes ); 491*b1cdbd2cSJim Jagielski /** Returns the maximum size of raw data possible to read in one block. */ 492*b1cdbd2cSJim Jagielski sal_uInt16 GetMaxRawReadSize( sal_Size nBytes ) const; 493*b1cdbd2cSJim Jagielski 494*b1cdbd2cSJim Jagielski /** Reads and decrypts nBytes bytes to the existing(!) buffer pData. 495*b1cdbd2cSJim Jagielski @return Count of bytes really read. */ 496*b1cdbd2cSJim Jagielski sal_uInt16 ReadRawData( void* pData, sal_uInt16 nBytes ); 497*b1cdbd2cSJim Jagielski 498*b1cdbd2cSJim Jagielski /** Reads 8 bit/16 bit string length. */ ReadByteStrLen(bool b16BitLen)499*b1cdbd2cSJim Jagielski inline sal_uInt16 ReadByteStrLen( bool b16BitLen ) 500*b1cdbd2cSJim Jagielski { return b16BitLen ? ReaduInt16() : ReaduInt8(); } 501*b1cdbd2cSJim Jagielski 502*b1cdbd2cSJim Jagielski private: 503*b1cdbd2cSJim Jagielski typedef ::std::vector< XclImpStreamPos > XclImpStreamPosStack; 504*b1cdbd2cSJim Jagielski 505*b1cdbd2cSJim Jagielski SvStream& mrStrm; /// Reference to the system input stream. 506*b1cdbd2cSJim Jagielski const XclImpRoot& mrRoot; /// Filter root data. 507*b1cdbd2cSJim Jagielski 508*b1cdbd2cSJim Jagielski XclImpDecrypterRef mxDecrypter; /// Provides methods to decrypt data. 509*b1cdbd2cSJim Jagielski 510*b1cdbd2cSJim Jagielski XclImpStreamPos maFirstRec; /// Start position of current record. 511*b1cdbd2cSJim Jagielski XclImpStreamPosStack maPosStack; /// Stack for record positions. 512*b1cdbd2cSJim Jagielski 513*b1cdbd2cSJim Jagielski XclImpStreamPos maGlobPos; /// User defined position elsewhere in stream. 514*b1cdbd2cSJim Jagielski sal_uInt16 mnGlobRecId; /// Record ID for user defined position. 515*b1cdbd2cSJim Jagielski bool mbGlobValidRec; /// Was user position a valid record? 516*b1cdbd2cSJim Jagielski bool mbHasGlobPos; /// Is user position defined? 517*b1cdbd2cSJim Jagielski 518*b1cdbd2cSJim Jagielski sal_Size mnStreamSize; /// Size of system stream. 519*b1cdbd2cSJim Jagielski sal_Size mnNextRecPos; /// Start of next record header. 520*b1cdbd2cSJim Jagielski sal_Size mnCurrRecSize; /// Helper for record position. 521*b1cdbd2cSJim Jagielski sal_Size mnComplRecSize; /// Size of complete record data (with CONTINUEs). 522*b1cdbd2cSJim Jagielski bool mbHasComplRec; /// true = mnComplRecSize is valid. 523*b1cdbd2cSJim Jagielski 524*b1cdbd2cSJim Jagielski sal_uInt16 mnRecId; /// Current record ID (not the CONTINUE ID). 525*b1cdbd2cSJim Jagielski sal_uInt16 mnAltContId; /// Alternative record ID for content continuation. 526*b1cdbd2cSJim Jagielski 527*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecId; /// Current raw record ID (including CONTINUEs). 528*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecSize; /// Current raw record size (without following CONTINUEs). 529*b1cdbd2cSJim Jagielski sal_uInt16 mnRawRecLeft; /// Bytes left in current raw record (without following CONTINUEs). 530*b1cdbd2cSJim Jagielski 531*b1cdbd2cSJim Jagielski sal_Unicode mcNulSubst; /// Replacement for NUL characters. 532*b1cdbd2cSJim Jagielski 533*b1cdbd2cSJim Jagielski bool mbCont; /// Automatic CONTINUE lookup on/off. 534*b1cdbd2cSJim Jagielski bool mbUseDecr; /// Usage of decryption. 535*b1cdbd2cSJim Jagielski bool mbValidRec; /// false = No more records to read. 536*b1cdbd2cSJim Jagielski bool mbValid; /// false = Record overread. 537*b1cdbd2cSJim Jagielski }; 538*b1cdbd2cSJim Jagielski 539*b1cdbd2cSJim Jagielski // ============================================================================ 540*b1cdbd2cSJim Jagielski 541*b1cdbd2cSJim Jagielski #endif 542*b1cdbd2cSJim Jagielski 543