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

Generated by: LCOV version 1.10