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

Generated by: LCOV version 1.10