LCOV - code coverage report
Current view: top level - sc/source/filter/inc - biffinputstream.hxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 11 0.0 %
Date: 2014-04-14 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          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             : #ifndef OOX_XLS_BIFFINPUTSTREAM_HXX
      21             : #define OOX_XLS_BIFFINPUTSTREAM_HXX
      22             : 
      23             : #include <vector>
      24             : #include "oox/helper/binaryinputstream.hxx"
      25             : #include "biffhelper.hxx"
      26             : #include "biffcodec.hxx"
      27             : 
      28             : 
      29             : namespace oox {
      30             : namespace xls {
      31             : 
      32             : namespace prv {
      33             : 
      34             : /** Buffers the contents of a raw record and encapsulates stream decoding. */
      35           0 : class BiffInputRecordBuffer
      36             : {
      37             : public:
      38             :     explicit            BiffInputRecordBuffer( BinaryInputStream& rInStrm );
      39             : 
      40             :     /** Returns the wrapped binary base stream. */
      41             :     inline const BinaryInputStream& getBaseStream() const { return mrInStrm; }
      42             : 
      43             :     /** Sets a decoder object and decrypts buffered record data. */
      44             :     void                setDecoder( const BiffDecoderRef& rxDecoder );
      45             :     /** Returns the current decoder object. */
      46             :     inline BiffDecoderRef getDecoder() const { return mxDecoder; }
      47             :     /** Enables/disables usage of current decoder. */
      48             :     void                enableDecoder( bool bEnable );
      49             : 
      50             :     /** Restarts the stream at the passed position. Buffer is invalid until the
      51             :         next call of startRecord() or startNextRecord(). */
      52             :     void                restartAt( sal_Int64 nPos );
      53             : 
      54             :     /** Reads the record header at the passed position. */
      55             :     bool                startRecord( sal_Int64 nHeaderPos );
      56             :     /** Reads the next record header from the stream. */
      57             :     bool                startNextRecord();
      58             :     /** Returns the start position of the record header in the core stream. */
      59             :     sal_uInt16          getNextRecId();
      60             : 
      61             :     /** Returns the start position of the record header in the core stream. */
      62           0 :     inline sal_Int64    getRecHeaderPos() const { return mnHeaderPos; }
      63             :     /** Returns the current record identifier. */
      64           0 :     inline sal_uInt16   getRecId() const { return mnRecId; }
      65             :     /** Returns the current record size. */
      66           0 :     inline sal_uInt16   getRecSize() const { return mnRecSize; }
      67             :     /** Returns the current read position in the current record body. */
      68             :     inline sal_uInt16   getRecPos() const { return mnRecPos; }
      69             :     /** Returns the number of remaining bytes in the current record body. */
      70           0 :     inline sal_uInt16   getRecLeft() const { return mnRecSize - mnRecPos; }
      71             : 
      72             :     /** Reads nBytes bytes to the existing buffer opData. Must NOT overread the source buffer. */
      73             :     void                read( void* opData, sal_uInt16 nBytes );
      74             :     /** Ignores nBytes bytes. Must NOT overread the buffer. */
      75             :     void                skip( sal_uInt16 nBytes );
      76             : 
      77             : private:
      78             :     /** Updates data buffer from stream, if needed. */
      79             :     void                updateBuffer();
      80             :     /** Updates decoded data from original data. */
      81             :     void                updateDecoded();
      82             : 
      83             : private:
      84             :     typedef ::std::vector< sal_uInt8 > DataBuffer;
      85             : 
      86             :     BinaryInputStream&  mrInStrm;               /// Core input stream.
      87             :     DataBuffer          maOriginalData;         /// Original data read from stream.
      88             :     DataBuffer          maDecodedData;          /// Decoded data.
      89             :     DataBuffer*         mpCurrentData;          /// Points to data buffer currently in use.
      90             :     BiffDecoderRef      mxDecoder;              /// Decoder object.
      91             :     sal_Int64           mnHeaderPos;            /// Stream start position of current record header.
      92             :     sal_Int64           mnBodyPos;              /// Stream start position of current record body.
      93             :     sal_Int64           mnBufferBodyPos;        /// Stream start position of buffered data.
      94             :     sal_Int64           mnNextHeaderPos;        /// Stream start position of next record header.
      95             :     sal_uInt16          mnRecId;                /// Current record identifier.
      96             :     sal_uInt16          mnRecSize;              /// Current record size.
      97             :     sal_uInt16          mnRecPos;               /// Current position in record body.
      98             :     bool                mbValidHeader;          /// True = valid record header.
      99             : };
     100             : 
     101             : } // namespace prv
     102             : 
     103             : /** This class is used to read BIFF record streams.
     104             : 
     105             :     An instance is constructed with a BinaryInputStream object. The passed
     106             :     stream is reset to its start while constructing this stream.
     107             : 
     108             :     To start reading a record call startNextRecord(). Now it is possible to
     109             :     read all contents of the record using operator>>() or any of the read***()
     110             :     functions. If some data exceeds the record size limit, the stream looks for
     111             :     a following CONTINUE record and jumps automatically to it. It is NOT
     112             :     allowed that an atomic data type is split into two records (e.g. 4 bytes of
     113             :     a double in one record and the other 4 bytes in a following CONTINUE).
     114             : 
     115             :     Trying to read over the record limits results in a stream error. The
     116             :     isValid() function indicates that by returning false. From now on the data
     117             :     returned by the read functions is undefined. The error state will be reset,
     118             :     if the next record is started.
     119             : 
     120             :     The import stream supports decrypting the stream data. The contents of a
     121             :     record (not the record header) will be encrypted by Excel if the file has
     122             :     been stored with password protection. The functions setDecoder() and
     123             :     enableDecoder() control the usage of the decryption algorithms.
     124             :     setDecoder() sets a new decryption algorithm and initially enables it.
     125             :     enableDecoder( false ) may be used to stop the usage of the decryption
     126             :     temporarily (sometimes record contents are never encrypted, e.g. all BOF
     127             :     records or the stream position in SHEET records). Decryption will be
     128             :     reenabled automatically, if a new record is started with the function
     129             :     startNextRecord().
     130             : */
     131           0 : class BiffInputStream : public BinaryInputStream
     132             : {
     133             : public:
     134             :     /** Constructs the BIFF record stream using the passed binary stream.
     135             : 
     136             :         @param rInStream
     137             :             The base input stream. Must be seekable. Will be seeked to its
     138             :             start position.
     139             : 
     140             :         @param bContLookup  Automatic CONTINUE lookup on/off.
     141             :      */
     142             :     explicit            BiffInputStream(
     143             :                             BinaryInputStream& rInStream,
     144             :                             bool bContLookup = true );
     145             : 
     146             :     // record control ---------------------------------------------------------
     147             : 
     148             :     /** Sets stream pointer to the start of the next record content.
     149             : 
     150             :         Ignores all CONTINUE records of the current record, if automatic
     151             :         CONTINUE usage is switched on.
     152             : 
     153             :         @return  False = no record found (end of stream).
     154             :      */
     155             :     bool                startNextRecord();
     156             : 
     157             :     /** Sets stream pointer to the start of the content of the specified record.
     158             : 
     159             :         The handle of the current record can be received and stored using the
     160             :         function getRecHandle() for later usage with this function. The record
     161             :         handle is equivalent to the position of the underlying binary stream,
     162             :         thus the function can be used to perform a hard seek to a specific
     163             :         position, if it is sure that a record starts exactly at this position.
     164             : 
     165             :         @return  False = no record found (invalid handle passed).
     166             :      */
     167             :     bool                startRecordByHandle( sal_Int64 nRecHandle );
     168             : 
     169             :     /** Sets stream pointer before current record and invalidates stream.
     170             : 
     171             :         The next call to startNextRecord() will start again the current record.
     172             :         This can be used in situations where a loop or a function leaves on a
     173             :         specific record, but the parent context expects to start this record by
     174             :         itself. The stream is invalid as long as the first record has not been
     175             :         started (it is not allowed to call any other stream operation then).
     176             :      */
     177             :     void                rewindRecord();
     178             : 
     179             :     // decoder ----------------------------------------------------------------
     180             : 
     181             :     /** Sets a new decoder object.
     182             : 
     183             :         Enables decryption of record contents for the rest of the stream.
     184             :      */
     185             :     void                setDecoder( const BiffDecoderRef& rxDecoder );
     186             : 
     187             :     /** Enables/disables usage of current decoder.
     188             : 
     189             :         Decryption is reenabled automatically, if a new record is started using
     190             :         the function startNextRecord().
     191             :      */
     192             :     void                enableDecoder( bool bEnable = true );
     193             : 
     194             :     // stream/record state and info -------------------------------------------
     195             : 
     196             :     /** Returns the current record identifier. */
     197           0 :     inline sal_uInt16   getRecId() const { return mnRecId; }
     198             :     /** Returns the record identifier of the following record. */
     199             :     sal_uInt16          getNextRecId();
     200             : 
     201             :     /** Returns a unique handle for the current record that can be used with
     202             :         the function startRecordByHandle(). */
     203           0 :     inline sal_Int64    getRecHandle() const { return mnRecHandle; }
     204             : 
     205             :     // BinaryStreamBase interface (seeking) -----------------------------------
     206             : 
     207             :     /** Returns the data size of the whole record without record headers. */
     208             :     virtual sal_Int64   size() const SAL_OVERRIDE;
     209             :     /** Returns the position inside of the whole record content. */
     210             :     virtual sal_Int64   tell() const SAL_OVERRIDE;
     211             :     /** Seeks in record content to the specified position. */
     212             :     virtual void        seek( sal_Int64 nRecPos ) SAL_OVERRIDE;
     213             :     /** Closes the input stream but not the wrapped stream. */
     214             :     virtual void        close() SAL_OVERRIDE;
     215             : 
     216             :     // BinaryInputStream interface (stream read access) -----------------------
     217             : 
     218             :     /** Reads nBytes bytes to the passed sequence.
     219             :         @return  Number of bytes really read. */
     220             :     virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
     221             :     /** Reads nBytes bytes and copies them to the passed buffer opMem.
     222             :         @return  Number of bytes really read. */
     223             :     virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
     224             :     /** Seeks forward inside the current record. */
     225             :     virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) SAL_OVERRIDE;
     226             : 
     227             :     /** Stream operator for integral and floating-point types. */
     228             :     template< typename Type >
     229           0 :     inline BiffInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
     230             : 
     231             :     // byte strings -----------------------------------------------------------
     232             : 
     233             :     /** Reads 8/16 bit string length and character array, and returns the string.
     234             :         @param b16BitLen
     235             :             True = Read 16-bit string length field before the character array.
     236             :             False = Read 8-bit string length field before the character array.
     237             :         @param bAllowNulChars
     238             :             True = NUL characters are inserted into the imported string.
     239             :             False = NUL characters are replaced by question marks (default).
     240             :      */
     241             :     OString      readByteString( bool b16BitLen, bool bAllowNulChars = false );
     242             : 
     243             :     /** Reads 8/16 bit string length and character array, and returns a Unicode string.
     244             :         @param b16BitLen
     245             :             True = Read 16-bit string length field before the character array.
     246             :             False = Read 8-bit string length field before the character array.
     247             :         @param eTextEnc  The text encoding used to create the Unicode string.
     248             :         @param bAllowNulChars
     249             :             True = NUL characters are inserted into the imported string.
     250             :             False = NUL characters are replaced by question marks (default).
     251             :      */
     252             :     OUString     readByteStringUC( bool b16BitLen, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );
     253             : 
     254             :     // Unicode strings --------------------------------------------------------
     255             : 
     256             :     /** Reads nChars characters of a BIFF8 string, and returns the string.
     257             :         @param nChars  Number of characters to read from the stream.
     258             :         @param b16BitChars
     259             :             True = The character array contains 16-bit characters.
     260             :             False = The character array contains truncated 8-bit characters.
     261             :         @param bAllowNulChars
     262             :             True = NUL characters are inserted into the imported string.
     263             :             False = NUL characters are replaced by question marks (default).
     264             :      */
     265             :     OUString     readUniStringChars( sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars = false );
     266             : 
     267             :     /** Reads 8-bit flags, extended header, nChar characters, extended data of
     268             :         a BIFF8 string, and returns the string.
     269             :         @param nChars  Number of characters to read from the stream.
     270             :         @param bAllowNulChars
     271             :             True = NUL characters are inserted into the imported string.
     272             :             False = NUL characters are replaced by question marks (default).
     273             :      */
     274             :     OUString     readUniStringBody( sal_uInt16 nChars, bool bAllowNulChars = false );
     275             : 
     276             :     /** Reads 16-bit character count, 8-bit flags, extended header, character
     277             :         array, extended data of a BIFF8 string, and returns the string.
     278             :         @param bAllowNulChars
     279             :             True = NUL characters are inserted into the imported string.
     280             :             False = NUL characters are replaced by question marks (default).
     281             :      */
     282             :     OUString     readUniString( bool bAllowNulChars = false );
     283             : 
     284             : 
     285             : private:
     286             :     /** Initializes all members after base stream has been seeked to new record. */
     287             :     void                setupRecord();
     288             :     /** Restarts the current record from the beginning. */
     289             :     void                restartRecord( bool bInvalidateRecSize );
     290             :     /** Sets stream pointer before specified record and invalidates stream. */
     291             :     void                rewindToRecord( sal_Int64 nRecHandle );
     292             :     /** Returns true, if stream was able to start a valid record. */
     293           0 :     inline bool         isInRecord() const { return mnRecHandle >= 0; }
     294             : 
     295             :     /** Returns true, if the passed ID is real or alternative continuation record ID. */
     296             :     bool                isContinueId( sal_uInt16 nRecId ) const;
     297             :     /** Goes to start of the next CONTINUE record.
     298             :         @descr  Stream must be located at the end of a raw record, and handling
     299             :         of CONTINUE records must be enabled.
     300             :         @return  True if next CONTINUE record has been found and initialized. */
     301             :     bool                jumpToNextContinue();
     302             :     /** Goes to start of the next CONTINUE record while reading strings.
     303             :         @descr  Stream must be located at the end of a raw record. If reading
     304             :         has been started in a CONTINUE record, jumps to an existing following
     305             :         CONTINUE record, even if handling of CONTINUE records is disabled (this
     306             :         is a special handling for TXO string data). Reads additional Unicode
     307             :         flag byte at start of the new raw record and sets or resets rb16BitChars.
     308             :         @return  True if next CONTINUE record has been found and initialized. */
     309             :     bool                jumpToNextStringContinue( bool& rb16BitChars );
     310             :     /** Calculates the complete length of the current record including CONTINUE
     311             :         records, stores the length in mnComplRecSize. */
     312             :     void                calcRecordLength();
     313             : 
     314             :     /** Returns the maximum size of raw data possible to read in one block. */
     315             :     sal_uInt16          getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const;
     316             : 
     317             :     /** Reads the BIFF8 Unicode string header fields. */
     318             :     void                readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize );
     319             : 
     320             : private:
     321             :     prv::BiffInputRecordBuffer maRecBuffer; /// Raw record data buffer.
     322             : 
     323             :     sal_Int64           mnRecHandle;        /// Handle of current record.
     324             :     sal_uInt16          mnRecId;            /// Identifier of current record (not the CONTINUE ID).
     325             :     sal_uInt16          mnAltContId;        /// Alternative identifier for content continuation records.
     326             : 
     327             :     sal_Int64           mnCurrRecSize;      /// Helper for record size and position.
     328             :     sal_Int64           mnComplRecSize;     /// Size of complete record data (with CONTINUEs).
     329             :     bool                mbHasComplRec;      /// True = mnComplRecSize is valid.
     330             : 
     331             :     bool                mbCont;             /// True = automatic CONTINUE lookup enabled.
     332             : };
     333             : 
     334             : class BiffInputStreamPos
     335             : {
     336             : public:
     337             :     explicit            BiffInputStreamPos( BiffInputStream& rStrm );
     338             : 
     339             :     bool                restorePosition();
     340             : 
     341           0 :     inline BiffInputStream& getStream() { return mrStrm; }
     342             : 
     343             : private:
     344             :     BiffInputStream&    mrStrm;
     345             :     sal_Int64           mnRecHandle;
     346             :     sal_Int64           mnRecPos;
     347             : };
     348             : 
     349             : /** Stores the current position of the passed stream on construction and
     350             :     restores it automatically on destruction. */
     351             : class BiffInputStreamPosGuard : private BiffInputStreamPos
     352             : {
     353             : public:
     354             :     explicit            BiffInputStreamPosGuard( BiffInputStream& rStrm );
     355             :                         ~BiffInputStreamPosGuard();
     356             : };
     357             : 
     358             : } // namespace xls
     359             : } // namespace oox
     360             : 
     361             : #endif
     362             : 
     363             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10