LCOV - code coverage report
Current view: top level - sc/source/filter/inc - biffinputstream.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 11 0.0 %
Date: 2012-08-25 Functions: 0 17 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 12 0.0 %

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

Generated by: LCOV version 1.10