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

Generated by: LCOV version 1.10