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

Generated by: LCOV version 1.11