LCOV - code coverage report
Current view: top level - sc/source/filter/inc - xestream.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 8 11 72.7 %
Date: 2015-06-13 12:38:46 Functions: 9 12 75.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_XESTREAM_HXX
      21             : #define INCLUDED_SC_SOURCE_FILTER_INC_XESTREAM_HXX
      22             : 
      23             : #include <com/sun/star/beans/NamedValue.hpp>
      24             : 
      25             : #include <map>
      26             : #include <stack>
      27             : #include <string>
      28             : #include <rtl/strbuf.hxx>
      29             : 
      30             : #include <oox/core/xmlfilterbase.hxx>
      31             : #include <oox/token/tokens.hxx>
      32             : #include <sax/fshelper.hxx>
      33             : 
      34             : #include "xlstream.hxx"
      35             : #include "xestring.hxx"
      36             : 
      37             : #include <filter/msfilter/mscodec.hxx>
      38             : #include <vector>
      39             : 
      40             : /* ============================================================================
      41             : Output stream class for Excel export
      42             : - CONTINUE record handling
      43             : ============================================================================ */
      44             : 
      45             : class XclExpRoot;
      46             : class XclExpBiff8Encrypter;
      47             : typedef boost::shared_ptr< XclExpBiff8Encrypter > XclExpEncrypterRef;
      48             : 
      49             : /** This class is used to export Excel record streams.
      50             :     @descr  An instance is constructed with an SvStream and the maximum size of Excel
      51             :     record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes).
      52             : 
      53             :     To start writing a record call StartRecord(). Parameters are the record identifier
      54             :     and any calculated record size. This is for optimizing the write process: if the real
      55             :     written data has the same size as the calculated, the stream will not seek back and
      56             :     update the record size field. But it is not mandatory to calculate a size. Each
      57             :     record must be closed by calling EndRecord(). This will check (and update) the record
      58             :     size field.
      59             : 
      60             :     If some data exceeds the record size limit, a CONTINUE record is started automatically
      61             :     and the new data will be written to this record.
      62             : 
      63             :     If specific data pieces must not be splitted, use SetSliceLen(). For instance:
      64             :     To write a sequence of 16-bit values, where 4 values form a unit and cannot be
      65             :     split, call SetSliceLen( 8 ) first (4*2 bytes == 8).
      66             : 
      67             :     To write unicode character arrays, call WriteUnicodeBuffer(). It creates CONTINUE
      68             :     records and repeats the unicode string flag byte automatically. This function is used
      69             :     for instance from the class XclExpString which can write complete unicode strings.
      70             : */
      71             : class XclExpStream
      72             : {
      73             : public:
      74             :     /** Constructs the Excel record export stream.
      75             :         @param rOutStrm  The system output stream to write to.
      76             :         @param nMaxRecSize  The maximum allowed size of record content (depending on BIFF type).
      77             :         If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */
      78             :                         XclExpStream(
      79             :                             SvStream& rOutStrm,
      80             :                             const XclExpRoot& rRoot,
      81             :                             sal_uInt16 nMaxRecSize = 0 );
      82             : 
      83             :                         ~XclExpStream();
      84             : 
      85             :     /** Returns the filter root data. */
      86         902 :     inline const XclExpRoot& GetRoot() const { return mrRoot; }
      87             : 
      88             :     /** Starts a new record: writes header data, stores calculated record size. */
      89             :     void                StartRecord( sal_uInt16 nRecId, sal_Size nRecSize );
      90             :     /** Checks and corrects real record length. Must be called every time a record is finished. */
      91             :     void                EndRecord();
      92             : 
      93             :     /** Returns the position inside of current record (starts by 0 in every CONTINUE). */
      94           7 :     inline sal_uInt16   GetRawRecPos() const { return mnCurrSize; }
      95             : 
      96             :     /** Returns the maximum size of a record. */
      97             :     inline sal_uInt16   GetMaxRecSize() const { return mnMaxRecSize; }
      98             :     /** Sets maximum record size (valid only for current record). */
      99             :     inline void         SetMaxRecSize( sal_uInt16 nMax ) { mnCurrMaxSize = nMax; }
     100             :     /** Sets maximum size of CONTINUE records (valid only for current record). */
     101             :     inline void         SetMaxContSize( sal_uInt16 nMax ) { mnMaxContSize = nMax; }
     102             : 
     103             :     /** Sets data slice length. 0 = no slices. */
     104             :     void                SetSliceSize( sal_uInt16 nSize );
     105             : 
     106             :     XclExpStream& operator<<( sal_Int8 nValue );
     107             :     XclExpStream& operator<<( sal_uInt8 nValue );
     108             :     XclExpStream& operator<<( sal_Int16 nValue );
     109             :     XclExpStream& operator<<( sal_uInt16 nValue );
     110             :     XclExpStream& operator<<( sal_Int32 nValue );
     111             :     XclExpStream& operator<<( sal_uInt32 nValue );
     112             :     XclExpStream& operator<<( float fValue );
     113             :     XclExpStream& operator<<( double fValue );
     114             : 
     115             :     /** Writes nBytes bytes from memory. */
     116             :     sal_Size            Write( const void* pData, sal_Size nBytes );
     117             :     /** Writes a sequence of nBytes zero bytes (respects slice setting). */
     118             :     void                WriteZeroBytes( sal_Size nBytes );
     119             : 
     120             :     void                WriteZeroBytesToRecord( sal_Size nBytes );
     121             : 
     122             :     /** Copies nBytes bytes from current position of the stream rInStrm.
     123             :         @descr  Omitting the second parameter means: read to end of stream. */
     124             :     void                CopyFromStream( SvStream& rInStrm, sal_uInt64 nBytes = STREAM_SEEK_TO_END );
     125             : 
     126             :     // *** unicode string export is realized with helper class XclExpString ***
     127             :     // (slice length setting has no effect here -> disabled automatically)
     128             : 
     129             :     /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
     130             :     void                WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags );
     131             : 
     132             :     // *** write 8-bit-strings ***
     133             :     // (slice length setting has no effect here -> disabled automatically)
     134             : 
     135             :     /** Writes string length field and OString buffer. */
     136             :     void                WriteByteString(
     137             :                             const OString& rString,
     138             :                             sal_uInt16 nMaxLen = 0x00FF,
     139             :                             bool b16BitCount = false );
     140             : 
     141             :     /** Writes 8-bit character buffer. */
     142             :     void                WriteCharBuffer( const ScfUInt8Vec& rBuffer );
     143             : 
     144             :     // *** SvStream access ***
     145             : 
     146             :     /** Sets position of system stream (only allowed outside of records). */
     147             :     sal_uInt64          SetSvStreamPos(sal_uInt64 nPos);
     148             :     /** Returns the absolute position of the system stream. */
     149          65 :     inline sal_uInt64   GetSvStreamPos() const { return mrStrm.Tell(); }
     150             : 
     151             :     void                SetEncrypter( XclExpEncrypterRef xEncrypter );
     152             : 
     153             :     bool                HasValidEncrypter() const;
     154             : 
     155             :     void                EnableEncryption( bool bEnable = true );
     156             : 
     157             :     void                DisableEncryption();
     158             : 
     159             : private:
     160             :     /** Writes header data, internal setup. */
     161             :     void                InitRecord( sal_uInt16 nRecId );
     162             :     /** Rewrites correct record length, if different from calculated. */
     163             :     void                UpdateRecSize();
     164             :     /** Recalculates mnCurrSize and mnSliceSize. */
     165             :     void                UpdateSizeVars( sal_Size nSize );
     166             :     /** Writes CONTINUE header, internal setup. */
     167             :     void                StartContinue();
     168             :     /** Refreshes counter vars, creates CONTINUE records. */
     169             :     void                PrepareWrite( sal_uInt16 nSize );
     170             :     /** Creates CONTINUE record at end of record.
     171             :         @return  Maximum data block size remaining. */
     172             :     sal_uInt16          PrepareWrite();
     173             : 
     174             :     /** Writes a raw sequence of zero bytes. */
     175             :     void                WriteRawZeroBytes( sal_Size nBytes );
     176             : 
     177             : private:
     178             :     SvStream&           mrStrm;         /// Reference to the system output stream.
     179             :     const XclExpRoot&   mrRoot;         /// Filter root data.
     180             : 
     181             :     bool                mbUseEncrypter;
     182             :     XclExpEncrypterRef  mxEncrypter;
     183             : 
     184             :                         // length data
     185             :     sal_uInt16          mnMaxRecSize;   /// Maximum size of record content.
     186             :     sal_uInt16          mnMaxContSize;  /// Maximum size of CONTINUE content.
     187             :     sal_uInt16          mnCurrMaxSize;  /// Current maximum, either mnMaxRecSize or mnMaxContSize.
     188             :     sal_uInt16          mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split).
     189             :     sal_uInt16          mnHeaderSize;   /// Record size written in last record header.
     190             :     sal_uInt16          mnCurrSize;     /// Count of bytes already written in current record.
     191             :     sal_uInt16          mnSliceSize;    /// Count of bytes already written in current slice.
     192             :     sal_Size            mnPredictSize;   /// Predicted size received from calling function.
     193             : 
     194             :                         // stream position data
     195             :     sal_Size            mnLastSizePos;  /// Stream position of size field in current header.
     196             :     bool                mbInRec;        /// true = currently writing inside of a record.
     197             : };
     198             : 
     199             : class XclExpBiff8Encrypter
     200             : {
     201             : public:
     202             :     explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot );
     203             :     ~XclExpBiff8Encrypter();
     204             : 
     205           0 :     bool IsValid() const { return mbValid; }
     206             : 
     207             :     void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const;
     208             :     void GetSalt( sal_uInt8 pnSalt[16] ) const;
     209             :     void GetDocId( sal_uInt8 pnDocId[16] ) const;
     210             : 
     211             :     void Encrypt( SvStream& rStrm, sal_uInt8  nData );
     212             :     void Encrypt( SvStream& rStrm, sal_uInt16 nData );
     213             :     void Encrypt( SvStream& rStrm, sal_uInt32 nData );
     214             : 
     215             :     void Encrypt( SvStream& rStrm, sal_Int8  nData );
     216             :     void Encrypt( SvStream& rStrm, sal_Int16 nData );
     217             :     void Encrypt( SvStream& rStrm, sal_Int32 nData );
     218             : 
     219             :     void Encrypt( SvStream& rStrm, float fValue );
     220             :     void Encrypt( SvStream& rStrm, double fValue );
     221             : 
     222             :     void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes );
     223             : 
     224             : private:
     225             :     void Init( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData );
     226             : 
     227             :     static sal_uInt32 GetBlockPos( sal_Size nStrmPos );
     228             :     static sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos );
     229             : 
     230             : private:
     231             :     ::msfilter::MSCodec_Std97 maCodec;      /// Crypto algorithm implementation.
     232             :     sal_uInt8           mpnDocId[16];
     233             :     sal_uInt8           mpnSalt[16];
     234             :     sal_uInt8           mpnSaltDigest[16];
     235             : 
     236             :     sal_uInt64          mnOldPos;      /// Last known stream position
     237             :     bool                mbValid;
     238             : };
     239             : 
     240             : // `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
     241             : #define XESTRING_TO_PSZ(s) \
     242             :     (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
     243             : 
     244             : class ScAddress;
     245             : class ScDocShell;
     246             : class ScDocument;
     247             : class ScFormulaCell;
     248             : class ScRange;
     249             : class ScRangeList;
     250             : class ScTokenArray;
     251             : struct XclAddress;
     252             : struct XclFontData;
     253             : struct XclRange;
     254             : class XclRangeList;
     255             : namespace sc { class CompileFormulaContext; }
     256             : 
     257             : class XclXmlUtils
     258             : {
     259             :     XclXmlUtils();
     260             :     ~XclXmlUtils();
     261             :     XclXmlUtils(const XclXmlUtils&) SAL_DELETED_FUNCTION;
     262             :     XclXmlUtils& operator=(const XclXmlUtils&) SAL_DELETED_FUNCTION;
     263             : public:
     264             :     static void                     GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& sType, OUString& rValue);
     265             :     static OUString          GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId );
     266             : 
     267             :     static OString ToOString( const Color& rColor );
     268             :     static OString ToOString( const OUString& s );
     269             :     static OString ToOString( const ScfUInt16Vec& rBuffer );
     270             :     static OStringBuffer& ToOString( OStringBuffer& s, const ScAddress& rRange );
     271             :     static OString ToOString( const ScRange& rRange );
     272             :     static OString ToOString( const ScRangeList& rRangeList );
     273             :     static OStringBuffer& ToOString( OStringBuffer& s, const XclAddress& rAddress );
     274             :     static OString ToOString( const XclExpString& s );
     275             :     static OString ToOString( const XclRange& rRange );
     276             :     static OString ToOString( const XclRangeList& rRangeList );
     277             : 
     278             :     static OUString ToOUString( const char* s );
     279             :     static OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
     280             :     static OUString ToOUString( sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray );
     281             :     static OUString ToOUString( const XclExpString& s );
     282             : 
     283             :     /**
     284             :      * @return const char* literal "true" for true value, or literal "false"
     285             :      *         for false value.
     286             :      */
     287             :     static const char* ToPsz( bool b );
     288             : 
     289             :     /**
     290             :      * @return literal "1" for true value, or literal "0" for false value.
     291             :      */
     292             :     static const char* ToPsz10( bool b );
     293             : 
     294             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue );
     295             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue );
     296             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue );
     297             :     static sax_fastparser::FSHelperPtr  WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nNameId );
     298             : };
     299             : 
     300             : class XclExpXmlStream : public oox::core::XmlFilterBase
     301             : {
     302             : public:
     303             :     XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rCC );
     304             :     virtual ~XclExpXmlStream();
     305             : 
     306             :     /** Returns the filter root data. */
     307        7283 :     inline const XclExpRoot& GetRoot() const { return *mpRoot; }
     308             : 
     309             :     sax_fastparser::FSHelperPtr& GetCurrentStream();
     310             :     void PushStream( sax_fastparser::FSHelperPtr aStream );
     311             :     void PopStream();
     312             : 
     313             :     sax_fastparser::FSHelperPtr     GetStreamForPath( const OUString& rPath );
     314             : 
     315             :     // FIXME: if written through this cannot be checked for well-formedness
     316        1527 :     sax_fastparser::FSHelperPtr&    WriteAttributes( sal_Int32 nAttribute, const char* value, FSEND_t )
     317        1527 :         { return WriteAttributesInternal( nAttribute, value, FSEND_internal ); }
     318           0 :     sax_fastparser::FSHelperPtr&    WriteAttributes( sal_Int32 nAttribute, const OString& value, FSEND_t )
     319           0 :         { return WriteAttributesInternal( nAttribute, value.getStr(), FSEND_internal ); }
     320             : 
     321             :     sax_fastparser::FSHelperPtr     CreateOutputStream (
     322             :                                         const OUString& sFullStream,
     323             :                                         const OUString& sRelativeStream,
     324             :                                         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation,
     325             :                                         const char* sContentType,
     326             :                                         const char* sRelationshipType,
     327             :                                         OUString* pRelationshipId = NULL );
     328             : 
     329             :     // ignore
     330             :     virtual bool exportDocument()
     331             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     332             : 
     333             :     // only needed for import; ignore
     334             :     virtual bool importDocument() throw() SAL_OVERRIDE;
     335             :     virtual oox::vml::Drawing* getVmlDrawing() SAL_OVERRIDE;
     336             :     virtual const oox::drawingml::Theme* getCurrentTheme() const SAL_OVERRIDE;
     337             :     virtual const oox::drawingml::table::TableStyleListPtr getTableStyles() SAL_OVERRIDE;
     338             :     virtual oox::drawingml::chart::ChartConverter* getChartConverter() SAL_OVERRIDE;
     339             : 
     340             :     /*
     341             :       Now create all the overloads in a typesafe way (i.e. without varargs) by creating a number of overloads
     342             :       up to a certain reasonable limit (feel free to raise it). This would be a lot easier with C++11 vararg templates.
     343             :     */
     344             :     // now overloads for 2 and more pairs
     345             :     #define SAX_ARGS_FUNC_DECL( argsdecl, argsuse ) \
     346             :         sax_fastparser::FSHelperPtr&    WriteAttributes( argsdecl, FSEND_t ) \
     347             :             { return WriteAttributesInternal( argsuse, FSEND_internal ); }
     348             :     #define SAX_ARGS_FUNC_NUM( decl1, decl2, use1, use2, convert, num ) \
     349             :         SAX_ARGS_FUNC_DECL( SAX_ARGS_ARG##num( decl1, decl2, ), SAX_ARGS_ARG##num( use1, use2, convert ))
     350             :     #define SAX_ARGS_FUNC_SUBST( type, convert, num ) \
     351             :         SAX_ARGS_FUNC_NUM( sal_Int32 attribute, type value, attribute, value, convert, num )
     352             :     #define SAX_ARGS_FUNC( arg, convert ) SAX_ARGS_FUNC_SUBST( arg, convert, 2 ) \
     353             :         SAX_ARGS_FUNC_SUBST( arg, convert, 3 ) SAX_ARGS_FUNC_SUBST( arg, convert, 4 ) \
     354             :         SAX_ARGS_FUNC_SUBST( arg, convert, 5 ) SAX_ARGS_FUNC_SUBST( arg, convert, 6 ) \
     355             :         SAX_ARGS_FUNC_SUBST( arg, convert, 7 ) SAX_ARGS_FUNC_SUBST( arg, convert, 8 ) \
     356             :         SAX_ARGS_FUNC_SUBST( arg, convert, 9 ) SAX_ARGS_FUNC_SUBST( arg, convert, 10 ) \
     357             :         SAX_ARGS_FUNC_SUBST( arg, convert, 11 ) SAX_ARGS_FUNC_SUBST( arg, convert, 12 ) \
     358             :         SAX_ARGS_FUNC_SUBST( arg, convert, 13 ) SAX_ARGS_FUNC_SUBST( arg, convert, 14 ) \
     359             :         SAX_ARGS_FUNC_SUBST( arg, convert, 15 ) SAX_ARGS_FUNC_SUBST( arg, convert, 16 ) \
     360             :         SAX_ARGS_FUNC_SUBST( arg, convert, 17 ) SAX_ARGS_FUNC_SUBST( arg, convert, 18 ) \
     361             :         SAX_ARGS_FUNC_SUBST( arg, convert, 19 ) SAX_ARGS_FUNC_SUBST( arg, convert, 20 ) \
     362             :         SAX_ARGS_FUNC_SUBST( arg, convert, 21 ) SAX_ARGS_FUNC_SUBST( arg, convert, 22 )
     363           7 :     SAX_ARGS_FUNC( const char*, )
     364           2 :     SAX_ARGS_FUNC( const OString&, .getStr() )
     365             :     #undef SAX_ARGS_FUNC_DECL
     366             :     #undef SAX_ARGS_FUNC_NUM
     367             :     #undef SAX_ARGS_FUNC_SUBST
     368             :     #undef SAX_ARGS_FUNC
     369             : 
     370             : private:
     371             :     virtual ::oox::ole::VbaProject* implCreateVbaProject() const SAL_OVERRIDE;
     372             :     virtual OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     373             :     ScDocShell *getDocShell();
     374             :     sax_fastparser::FSHelperPtr&    WriteAttributesInternal( sal_Int32 nAttribute, ... );
     375             : 
     376             :     typedef std::map< OUString,
     377             :         std::pair< OUString,
     378             :             sax_fastparser::FSHelperPtr > >     XclExpXmlPathToStateMap;
     379             : 
     380             :     const XclExpRoot*                           mpRoot;
     381             :     std::stack< sax_fastparser::FSHelperPtr >   maStreams;
     382             :     XclExpXmlPathToStateMap                     maOpenedStreamMap;
     383             : };
     384             : 
     385             : #endif
     386             : 
     387             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11