LCOV - code coverage report
Current view: top level - sc/source/filter/inc - xestream.hxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 7 0.0 %
Date: 2014-04-14 Functions: 0 8 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 SC_XESTREAM_HXX
      21             : #define SC_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           0 :     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 everytime a record is finished. */
      90             :     void                EndRecord();
      91             : 
      92             :     /** Returns the position inside of current record (starts by 0 in every CONTINUE). */
      93           0 :     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           0 :     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             :     bool IsValid() const;
     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             : 
     240             : 
     241             : 
     242             : // `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
     243             : #define XESTRING_TO_PSZ(s) \
     244             :     (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
     245             : 
     246             : class ScAddress;
     247             : class ScDocShell;
     248             : class ScDocument;
     249             : class ScFormulaCell;
     250             : class ScRange;
     251             : class ScRangeList;
     252             : class ScTokenArray;
     253             : struct XclAddress;
     254             : struct XclFontData;
     255             : struct XclRange;
     256             : class XclRangeList;
     257             : 
     258             : class XclXmlUtils
     259             : {
     260             :     XclXmlUtils();
     261             :     ~XclXmlUtils();
     262             :     XclXmlUtils(const XclXmlUtils&);
     263             :     XclXmlUtils& operator=(const XclXmlUtils&);
     264             : public:
     265             :     static void                     GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& sType, OUString& rValue);
     266             :     static OUString          GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId );
     267             : 
     268             :     static OString ToOString( const Color& rColor );
     269             :     static OString ToOString( const OUString& s );
     270             :     static OString ToOString( const ScfUInt16Vec& rBuffer );
     271             :     static OString ToOString( const ScAddress& rRange );
     272             :     static OString ToOString( const ScRange& rRange );
     273             :     static OString ToOString( const ScRangeList& rRangeList );
     274             :     static OString ToOString( const XclAddress& rAddress );
     275             :     static OString ToOString( const XclExpString& s );
     276             :     static OString ToOString( const XclRange& rRange );
     277             :     static OString ToOString( const XclRangeList& rRangeList );
     278             : 
     279             :     static OUString ToOUString( const char* s );
     280             :     static OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
     281             :     static OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, const ScTokenArray* pTokenArray );
     282             :     static OUString ToOUString( const XclExpString& s );
     283             :     static const char* ToPsz( bool b );
     284             : 
     285             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue );
     286             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue );
     287             :     static sax_fastparser::FSHelperPtr  WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue );
     288             :     static sax_fastparser::FSHelperPtr  WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nNameId );
     289             : };
     290             : 
     291             : class XclExpXmlStream : public oox::core::XmlFilterBase
     292             : {
     293             : public:
     294             :     XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rCC );
     295             :     virtual ~XclExpXmlStream();
     296             : 
     297             :     /** Returns the filter root data. */
     298           0 :     inline const XclExpRoot& GetRoot() const { return *mpRoot; }
     299             : 
     300             :     sax_fastparser::FSHelperPtr& GetCurrentStream();
     301             :     void PushStream( sax_fastparser::FSHelperPtr aStream );
     302             :     void PopStream();
     303             : 
     304             :     sax_fastparser::FSHelperPtr     GetStreamForPath( const OUString& rPath );
     305             : 
     306             :     // FIXME: if written through this cannot be checked for well-formedness
     307           0 :     sax_fastparser::FSHelperPtr&    WriteAttributes( sal_Int32 nAttribute, const char* value, FSEND_t )
     308           0 :         { return WriteAttributesInternal( nAttribute, value, FSEND_internal ); }
     309             :     sax_fastparser::FSHelperPtr&    WriteAttributes( sal_Int32 nAttribute, const OString& value, FSEND_t )
     310             :         { return WriteAttributesInternal( nAttribute, value.getStr(), FSEND_internal ); }
     311             : 
     312             :     sax_fastparser::FSHelperPtr     CreateOutputStream (
     313             :                                         const OUString& sFullStream,
     314             :                                         const OUString& sRelativeStream,
     315             :                                         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation,
     316             :                                         const char* sContentType,
     317             :                                         const char* sRelationshipType,
     318             :                                         OUString* pRelationshipId = NULL );
     319             : 
     320             :     // ignore
     321             :     virtual bool exportDocument() throw (std::exception) SAL_OVERRIDE;
     322             : 
     323             :     // only needed for import; ignore
     324             :     virtual bool importDocument() throw() SAL_OVERRIDE;
     325             :     virtual oox::vml::Drawing* getVmlDrawing() SAL_OVERRIDE;
     326             :     virtual const oox::drawingml::Theme* getCurrentTheme() const SAL_OVERRIDE;
     327             :     virtual const oox::drawingml::table::TableStyleListPtr getTableStyles() SAL_OVERRIDE;
     328             :     virtual oox::drawingml::chart::ChartConverter* getChartConverter() SAL_OVERRIDE;
     329             : 
     330             :     /*
     331             :       Now create all the overloads in a typesafe way (i.e. without varargs) by creating a number of overloads
     332             :       up to a certain reasonable limit (feel free to raise it). This would be a lot easier with C++11 vararg templates.
     333             :     */
     334             :     // now overloads for 2 and more pairs
     335             :     #define SAX_ARGS_FUNC_DECL( argsdecl, argsuse ) \
     336             :         sax_fastparser::FSHelperPtr&    WriteAttributes( argsdecl, FSEND_t ) \
     337             :             { return WriteAttributesInternal( argsuse, FSEND_internal ); }
     338             :     #define SAX_ARGS_FUNC_NUM( decl1, decl2, use1, use2, convert, num ) \
     339             :         SAX_ARGS_FUNC_DECL( SAX_ARGS_ARG##num( decl1, decl2, ), SAX_ARGS_ARG##num( use1, use2, convert ))
     340             :     #define SAX_ARGS_FUNC_SUBST( type, convert, num ) \
     341             :         SAX_ARGS_FUNC_NUM( sal_Int32 attribute, type value, attribute, value, convert, num )
     342             :     #define SAX_ARGS_FUNC( arg, convert ) SAX_ARGS_FUNC_SUBST( arg, convert, 2 ) \
     343             :         SAX_ARGS_FUNC_SUBST( arg, convert, 3 ) SAX_ARGS_FUNC_SUBST( arg, convert, 4 ) \
     344             :         SAX_ARGS_FUNC_SUBST( arg, convert, 5 ) SAX_ARGS_FUNC_SUBST( arg, convert, 6 ) \
     345             :         SAX_ARGS_FUNC_SUBST( arg, convert, 7 ) SAX_ARGS_FUNC_SUBST( arg, convert, 8 ) \
     346             :         SAX_ARGS_FUNC_SUBST( arg, convert, 9 ) SAX_ARGS_FUNC_SUBST( arg, convert, 10 ) \
     347             :         SAX_ARGS_FUNC_SUBST( arg, convert, 11 ) SAX_ARGS_FUNC_SUBST( arg, convert, 12 ) \
     348             :         SAX_ARGS_FUNC_SUBST( arg, convert, 13 ) SAX_ARGS_FUNC_SUBST( arg, convert, 14 ) \
     349             :         SAX_ARGS_FUNC_SUBST( arg, convert, 15 ) SAX_ARGS_FUNC_SUBST( arg, convert, 16 ) \
     350             :         SAX_ARGS_FUNC_SUBST( arg, convert, 17 ) SAX_ARGS_FUNC_SUBST( arg, convert, 18 ) \
     351             :         SAX_ARGS_FUNC_SUBST( arg, convert, 19 ) SAX_ARGS_FUNC_SUBST( arg, convert, 20 ) \
     352             :         SAX_ARGS_FUNC_SUBST( arg, convert, 21 ) SAX_ARGS_FUNC_SUBST( arg, convert, 22 )
     353           0 :     SAX_ARGS_FUNC( const char*, )
     354             :     SAX_ARGS_FUNC( const OString&, .getStr() )
     355             :     #undef SAX_ARGS_FUNC_DECL
     356             :     #undef SAX_ARGS_FUNC_NUM
     357             :     #undef SAX_ARGS_FUNC_SUBST
     358             :     #undef SAX_ARGS_FUNC
     359             : 
     360             : private:
     361             :     virtual ::oox::ole::VbaProject* implCreateVbaProject() const SAL_OVERRIDE;
     362             :     virtual OUString implGetImplementationName() const SAL_OVERRIDE;
     363             :     ScDocShell *getDocShell();
     364             :     sax_fastparser::FSHelperPtr&    WriteAttributesInternal( sal_Int32 nAttribute, ... );
     365             : 
     366             :     typedef std::map< OUString,
     367             :         std::pair< OUString,
     368             :             sax_fastparser::FSHelperPtr > >     XclExpXmlPathToStateMap;
     369             : 
     370             :     const XclExpRoot*                           mpRoot;
     371             :     std::stack< sax_fastparser::FSHelperPtr >   maStreams;
     372             :     XclExpXmlPathToStateMap                     maOpenedStreamMap;
     373             : };
     374             : 
     375             : #endif
     376             : 
     377             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10