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