diff options
Diffstat (limited to 'sc/source/filter/inc/xestream.hxx')
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx new file mode 100644 index 000000000000..8792f26c6582 --- /dev/null +++ b/sc/source/filter/inc/xestream.hxx @@ -0,0 +1,357 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xestream.hxx,v $ + * $Revision: 1.8.30.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// ============================================================================ + +#ifndef SC_XESTREAM_HXX +#define SC_XESTREAM_HXX + +#include <map> +#include <stack> +#include <string> + +#include <oox/core/xmlfilterbase.hxx> +#include <sax/fshelper.hxx> + +#include "xlstream.hxx" +#include "xestring.hxx" + +/* ============================================================================ +Output stream class for Excel export +- CONTINUE record handling +- ByteString and UniString support +============================================================================ */ + +class XclExpRoot; + +/** This class is used to export Excel record streams. + @descr An instance is constructed with an SvStream and the maximum size of Excel + record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes). + + To start writing a record call StartRecord(). Parameters are the record identifier + and any calculated record size. This is for optimizing the write process: if the real + written data has the same size as the calculated, the stream will not seek back and + update the record size field. But it is not mandatory to calculate a size. Each + record must be closed by calling EndRecord(). This will check (and update) the record + size field. + + If some data exceeds the record size limit, a CONTINUE record is started automatically + and the new data will be written to this record. + + If specific data pieces must not be splitted, use SetSliceLen(). For instance: + To write a sequence of 16-bit values, where 4 values form a unit and cannot be + split, call SetSliceLen( 8 ) first (4*2 bytes == 8). + + To write unicode character arrays, call WriteUnicodeBuffer(). It creates CONTINUE + records and repeats the unicode string flag byte automatically. This function is used + for instance from the class XclExpString which can write complete unicode strings. +*/ +class XclExpStream +{ +public: + /** Constructs the Excel record export stream. + @param rOutStrm The system output stream to write to. + @param nMaxRecSize The maximum allowed size of record content (depending on BIFF type). + If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */ + XclExpStream( + SvStream& rOutStrm, + const XclExpRoot& rRoot, + sal_uInt16 nMaxRecSize = 0 ); + + ~XclExpStream(); + + /** Returns the filter root data. */ + inline const XclExpRoot& GetRoot() const { return mrRoot; } + + /** Starts a new record: writes header data, stores calculated record size. */ + void StartRecord( sal_uInt16 nRecId, sal_Size nRecSize ); + /** Checks and corrects real record length. Must be called everytime a record is finished. */ + void EndRecord(); + + /** Returns the position inside of current record (starts by 0 in every CONTINUE). */ + inline sal_uInt16 GetRawRecPos() const { return mnCurrSize; } + + /** Returns the maximum size of a record. */ + inline sal_uInt16 GetMaxRecSize() const { return mnMaxRecSize; } + /** Sets maximum record size (valid only for current record). */ + inline void SetMaxRecSize( sal_uInt16 nMax ) { mnCurrMaxSize = nMax; } + /** Sets maximum size of CONTINUE records (valid only for current record). */ + inline void SetMaxContSize( sal_uInt16 nMax ) { mnMaxContSize = nMax; } + + /** Sets data slice length. 0 = no slices. */ + void SetSliceSize( sal_uInt16 nSize ); + + inline XclExpStream& operator<<( sal_Int8 nValue ); + inline XclExpStream& operator<<( sal_uInt8 nValue ); + inline XclExpStream& operator<<( sal_Int16 nValue ); + inline XclExpStream& operator<<( sal_uInt16 nValue ); + inline XclExpStream& operator<<( sal_Int32 nValue ); + inline XclExpStream& operator<<( sal_uInt32 nValue ); + inline XclExpStream& operator<<( float fValue ); + inline XclExpStream& operator<<( double fValue ); + + /** Writes nBytes bytes from memory. */ + sal_Size Write( const void* pData, sal_Size nBytes ); + /** Writes a sequence of nBytes zero bytes (respects slice setting). */ + void WriteZeroBytes( sal_Size nBytes ); + /** Copies nBytes bytes from current position of the stream rInStrm. + @descr Omitting the second parameter means: read to end of stream. */ + sal_Size CopyFromStream( SvStream& rInStrm, sal_Size nBytes = STREAM_SEEK_TO_END ); + + // *** unicode string export is realized with helper class XclExpString *** + // (slice length setting has no effect here -> disabled automatically) + +//UNUSED2008-05 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */ +//UNUSED2008-05 void WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_Size nChars, sal_uInt8 nFlags ); + + /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */ + void WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags ); + + // *** write 8-bit-strings *** + // (slice length setting has no effect here -> disabled automatically) + +//UNUSED2008-05 /** Writes ByteString buffer (without string length field). */ +//UNUSED2008-05 void WriteByteStringBuffer( +//UNUSED2008-05 const ByteString& rString, +//UNUSED2008-05 sal_uInt16 nMaxLen = 0x00FF ); + + /** Writes string length field and ByteString buffer. */ + void WriteByteString( + const ByteString& rString, + sal_uInt16 nMaxLen = 0x00FF, + bool b16BitCount = false ); + + /** Writes 8-bit character buffer. */ + void WriteCharBuffer( const ScfUInt8Vec& rBuffer ); + + // *** SvStream access *** + + /** Sets position of system stream (only allowed outside of records). */ + sal_Size SetSvStreamPos( sal_Size nPos ); + /** Returns the absolute position of the system stream. */ + inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); } + +private: + /** Writes header data, internal setup. */ + void InitRecord( sal_uInt16 nRecId ); + /** Rewrites correct record length, if different from calculated. */ + void UpdateRecSize(); + /** Recalculates mnCurrSize and mnSliceSize. */ + void UpdateSizeVars( sal_Size nSize ); + /** Writes CONTINUE header, internal setup. */ + void StartContinue(); + /** Refreshes counter vars, creates CONTINUE records. */ + void PrepareWrite( sal_uInt16 nSize ); + /** Creates CONTINUE record at end of record. + @return Maximum data block size remaining. */ + sal_uInt16 PrepareWrite(); + + /** Writes a raw sequence of zero bytes. */ + void WriteRawZeroBytes( sal_Size nBytes ); + +private: + SvStream& mrStrm; /// Reference to the system output stream. + const XclExpRoot& mrRoot; /// Filter root data. + + // length data + sal_uInt16 mnMaxRecSize; /// Maximum size of record content. + sal_uInt16 mnMaxContSize; /// Maximum size of CONTINUE content. + sal_uInt16 mnCurrMaxSize; /// Current maximum, either mnMaxRecSize or mnMaxContSize. + sal_uInt16 mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split). + sal_uInt16 mnHeaderSize; /// Record size written in last record header. + sal_uInt16 mnCurrSize; /// Count of bytes already written in current record. + sal_uInt16 mnSliceSize; /// Count of bytes already written in current slice. + sal_Size mnPredictSize; /// Predicted size received from calling function. + + // stream position data + sal_Size mnLastSizePos; /// Stream position of size field in current header. + bool mbInRec; /// true = currently writing inside of a record. +}; + +// ---------------------------------------------------------------------------- + +inline XclExpStream& XclExpStream::operator<<( sal_Int8 nValue ) +{ + PrepareWrite( 1 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue ) +{ + PrepareWrite( 1 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( sal_Int16 nValue ) +{ + PrepareWrite( 2 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue ) +{ + PrepareWrite( 2 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( sal_Int32 nValue ) +{ + PrepareWrite( 4 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue ) +{ + PrepareWrite( 4 ); + mrStrm << nValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( float fValue ) +{ + PrepareWrite( 4 ); + mrStrm << fValue; + return *this; +} + +inline XclExpStream& XclExpStream::operator<<( double fValue ) +{ + PrepareWrite( 8 ); + mrStrm << fValue; + return *this; +} + + +// ============================================================================ + +// ---------------------------------------------------------------------------- + + +// ============================================================================ + +// `s.GetChar(0) != 0` needed because some strings on export only contain NULL. +#define XESTRING_TO_PSZ(s) \ + (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL) + +class ScAddress; +class ScDocument; +class ScRange; +class ScRangeList; +class ScTokenArray; +struct XclAddress; +struct XclFontData; +class XclRangeList; + +class XclXmlUtils +{ + XclXmlUtils(); + ~XclXmlUtils(); + XclXmlUtils(const XclXmlUtils&); + XclXmlUtils& operator=(const XclXmlUtils&); +public: + static ::rtl::OUString GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId ); + + static ::rtl::OString ToOString( const Color& rColor ); + static ::rtl::OString ToOString( const ::rtl::OUString& s ); + static ::rtl::OString ToOString( const ScfUInt16Vec& rBuffer ); + static ::rtl::OString ToOString( const String& s ); + static ::rtl::OString ToOString( const ScAddress& rRange ); + static ::rtl::OString ToOString( const ScRange& rRange ); + static ::rtl::OString ToOString( const ScRangeList& rRangeList ); + static ::rtl::OString ToOString( const XclAddress& rAddress ); + static ::rtl::OString ToOString( const XclExpString& s ); + static ::rtl::OString ToOString( const XclRangeList& rRangeList ); + + static ::rtl::OUString ToOUString( const char* s ); + static ::rtl::OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 ); + static ::rtl::OUString ToOUString( const String& s ); + static ::rtl::OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray ); + static ::rtl::OUString ToOUString( const XclExpString& s ); + static const char* ToPsz( bool b ); +}; + +class XclExpXmlStream : public oox::core::XmlFilterBase +{ +public: + XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr, SvStream& rStrm, const XclExpRoot& rRoot ); + virtual ~XclExpXmlStream(); + + /** Returns the filter root data. */ + inline const XclExpRoot& GetRoot() const { return mrRoot; } + + sax_fastparser::FSHelperPtr& GetCurrentStream(); + void PushStream( sax_fastparser::FSHelperPtr aStream ); + void PopStream(); + + ::rtl::OUString GetIdForPath( const ::rtl::OUString& rPath ); + sax_fastparser::FSHelperPtr GetStreamForPath( const ::rtl::OUString& rPath ); + + sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, ... ); + sax_fastparser::FSHelperPtr& WriteFontData( const XclFontData& rFontData, sal_Int32 nNameId ); + + sax_fastparser::FSHelperPtr CreateOutputStream ( + const ::rtl::OUString& sFullStream, + const ::rtl::OUString& sRelativeStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation, + const char* sContentType, + const char* sRelationshipType, + ::rtl::OUString* pRelationshipId = NULL ); + + // ignore + virtual bool exportDocument() throw(); + + // only needed for import; ignore + virtual bool importDocument() throw(); + virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; + virtual const oox::vml::DrawingPtr getDrawings(); + virtual const oox::drawingml::Theme* getCurrentTheme() const; + virtual const oox::drawingml::table::TableStyleListPtr getTableStyles(); + virtual oox::drawingml::chart::ChartConverter& getChartConverter(); + + void Trace( const char* format, ...); +private: + virtual ::rtl::OUString implGetImplementationName() const; + + typedef std::map< ::rtl::OUString, + std::pair< ::rtl::OUString, + sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap; + + const XclExpRoot& mrRoot; /// Filter root data. + std::stack< sax_fastparser::FSHelperPtr > maStreams; + XclExpXmlPathToStateMap maOpenedStreamMap; +}; + +#endif + |