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

Generated by: LCOV version 1.10