1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xestream.hxx,v $
10 * $Revision: 1.8.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // ============================================================================
33 #ifndef SC_XESTREAM_HXX
34 #define SC_XESTREAM_HXX
40 #include <oox/core/xmlfilterbase.hxx>
41 #include <sax/fshelper.hxx>
43 #include "xlstream.hxx"
44 #include "xestring.hxx"
46 #include <svx/mscodec.hxx>
49 /* ============================================================================
50 Output stream class for Excel export
51 - CONTINUE record handling
52 - ByteString and UniString support
53 ============================================================================ */
56 class XclExpBiff8Encrypter
;
57 typedef ScfRef
< XclExpBiff8Encrypter
> XclExpEncrypterRef
;
59 /** This class is used to export Excel record streams.
60 @descr An instance is constructed with an SvStream and the maximum size of Excel
61 record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes).
63 To start writing a record call StartRecord(). Parameters are the record identifier
64 and any calculated record size. This is for optimizing the write process: if the real
65 written data has the same size as the calculated, the stream will not seek back and
66 update the record size field. But it is not mandatory to calculate a size. Each
67 record must be closed by calling EndRecord(). This will check (and update) the record
70 If some data exceeds the record size limit, a CONTINUE record is started automatically
71 and the new data will be written to this record.
73 If specific data pieces must not be splitted, use SetSliceLen(). For instance:
74 To write a sequence of 16-bit values, where 4 values form a unit and cannot be
75 split, call SetSliceLen( 8 ) first (4*2 bytes == 8).
77 To write unicode character arrays, call WriteUnicodeBuffer(). It creates CONTINUE
78 records and repeats the unicode string flag byte automatically. This function is used
79 for instance from the class XclExpString which can write complete unicode strings.
84 /** Constructs the Excel record export stream.
85 @param rOutStrm The system output stream to write to.
86 @param nMaxRecSize The maximum allowed size of record content (depending on BIFF type).
87 If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */
90 const XclExpRoot
& rRoot
,
91 sal_uInt16 nMaxRecSize
= 0 );
95 /** Returns the filter root data. */
96 inline const XclExpRoot
& GetRoot() const { return mrRoot
; }
98 /** Starts a new record: writes header data, stores calculated record size. */
99 void StartRecord( sal_uInt16 nRecId
, sal_Size nRecSize
);
100 /** Checks and corrects real record length. Must be called everytime a record is finished. */
103 /** Returns the position inside of current record (starts by 0 in every CONTINUE). */
104 inline sal_uInt16
GetRawRecPos() const { return mnCurrSize
; }
106 /** Returns the maximum size of a record. */
107 inline sal_uInt16
GetMaxRecSize() const { return mnMaxRecSize
; }
108 /** Sets maximum record size (valid only for current record). */
109 inline void SetMaxRecSize( sal_uInt16 nMax
) { mnCurrMaxSize
= nMax
; }
110 /** Sets maximum size of CONTINUE records (valid only for current record). */
111 inline void SetMaxContSize( sal_uInt16 nMax
) { mnMaxContSize
= nMax
; }
113 /** Sets data slice length. 0 = no slices. */
114 void SetSliceSize( sal_uInt16 nSize
);
116 XclExpStream
& operator<<( sal_Int8 nValue
);
117 XclExpStream
& operator<<( sal_uInt8 nValue
);
118 XclExpStream
& operator<<( sal_Int16 nValue
);
119 XclExpStream
& operator<<( sal_uInt16 nValue
);
120 XclExpStream
& operator<<( sal_Int32 nValue
);
121 XclExpStream
& operator<<( sal_uInt32 nValue
);
122 XclExpStream
& operator<<( float fValue
);
123 XclExpStream
& operator<<( double fValue
);
125 /** Writes nBytes bytes from memory. */
126 sal_Size
Write( const void* pData
, sal_Size nBytes
);
127 /** Writes a sequence of nBytes zero bytes (respects slice setting). */
128 void WriteZeroBytes( sal_Size nBytes
);
130 void WriteZeroBytesToRecord( sal_Size nBytes
);
132 /** Copies nBytes bytes from current position of the stream rInStrm.
133 @descr Omitting the second parameter means: read to end of stream. */
134 sal_Size
CopyFromStream( SvStream
& rInStrm
, sal_Size nBytes
= STREAM_SEEK_TO_END
);
136 // *** unicode string export is realized with helper class XclExpString ***
137 // (slice length setting has no effect here -> disabled automatically)
139 //UNUSED2008-05 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
140 //UNUSED2008-05 void WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_Size nChars, sal_uInt8 nFlags );
142 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
143 void WriteUnicodeBuffer( const ScfUInt16Vec
& rBuffer
, sal_uInt8 nFlags
);
145 // *** write 8-bit-strings ***
146 // (slice length setting has no effect here -> disabled automatically)
148 //UNUSED2008-05 /** Writes ByteString buffer (without string length field). */
149 //UNUSED2008-05 void WriteByteStringBuffer(
150 //UNUSED2008-05 const ByteString& rString,
151 //UNUSED2008-05 sal_uInt16 nMaxLen = 0x00FF );
153 /** Writes string length field and ByteString buffer. */
154 void WriteByteString(
155 const ByteString
& rString
,
156 sal_uInt16 nMaxLen
= 0x00FF,
157 bool b16BitCount
= false );
159 /** Writes 8-bit character buffer. */
160 void WriteCharBuffer( const ScfUInt8Vec
& rBuffer
);
162 // *** SvStream access ***
164 /** Sets position of system stream (only allowed outside of records). */
165 sal_Size
SetSvStreamPos( sal_Size nPos
);
166 /** Returns the absolute position of the system stream. */
167 inline sal_Size
GetSvStreamPos() const { return mrStrm
.Tell(); }
169 void SetEncrypter( XclExpEncrypterRef xEncrypter
);
171 bool HasValidEncrypter() const;
173 void EnableEncryption( bool bEnable
= true );
175 void DisableEncryption();
178 /** Writes header data, internal setup. */
179 void InitRecord( sal_uInt16 nRecId
);
180 /** Rewrites correct record length, if different from calculated. */
181 void UpdateRecSize();
182 /** Recalculates mnCurrSize and mnSliceSize. */
183 void UpdateSizeVars( sal_Size nSize
);
184 /** Writes CONTINUE header, internal setup. */
185 void StartContinue();
186 /** Refreshes counter vars, creates CONTINUE records. */
187 void PrepareWrite( sal_uInt16 nSize
);
188 /** Creates CONTINUE record at end of record.
189 @return Maximum data block size remaining. */
190 sal_uInt16
PrepareWrite();
192 /** Writes a raw sequence of zero bytes. */
193 void WriteRawZeroBytes( sal_Size nBytes
);
196 SvStream
& mrStrm
; /// Reference to the system output stream.
197 const XclExpRoot
& mrRoot
; /// Filter root data.
200 XclExpEncrypterRef mxEncrypter
;
203 sal_uInt16 mnMaxRecSize
; /// Maximum size of record content.
204 sal_uInt16 mnMaxContSize
; /// Maximum size of CONTINUE content.
205 sal_uInt16 mnCurrMaxSize
; /// Current maximum, either mnMaxRecSize or mnMaxContSize.
206 sal_uInt16 mnMaxSliceSize
; /// Maximum size of data slices (parts that cannot be split).
207 sal_uInt16 mnHeaderSize
; /// Record size written in last record header.
208 sal_uInt16 mnCurrSize
; /// Count of bytes already written in current record.
209 sal_uInt16 mnSliceSize
; /// Count of bytes already written in current slice.
210 sal_Size mnPredictSize
; /// Predicted size received from calling function.
212 // stream position data
213 sal_Size mnLastSizePos
; /// Stream position of size field in current header.
214 bool mbInRec
; /// true = currently writing inside of a record.
217 // ============================================================================
219 class XclExpBiff8Encrypter
222 explicit XclExpBiff8Encrypter( const XclExpRoot
& rRoot
, const sal_uInt8 nDocId
[16],
223 const sal_uInt8 nSalt
[16] );
224 ~XclExpBiff8Encrypter();
226 bool IsValid() const;
228 void GetSaltDigest( sal_uInt8 nSaltDigest
[16] ) const;
230 void Encrypt( SvStream
& rStrm
, sal_uInt8 nData
);
231 void Encrypt( SvStream
& rStrm
, sal_uInt16 nData
);
232 void Encrypt( SvStream
& rStrm
, sal_uInt32 nData
);
234 void Encrypt( SvStream
& rStrm
, sal_Int8 nData
);
235 void Encrypt( SvStream
& rStrm
, sal_Int16 nData
);
236 void Encrypt( SvStream
& rStrm
, sal_Int32 nData
);
238 void Encrypt( SvStream
& rStrm
, float fValue
);
239 void Encrypt( SvStream
& rStrm
, double fValue
);
241 void EncryptBytes( SvStream
& rStrm
, ::std::vector
<sal_uInt8
>& aBytes
);
244 void Init( const String
& aPass
, const sal_uInt8 nDocId
[16],
245 const sal_uInt8 nSalt
[16] );
247 sal_uInt32
GetBlockPos( sal_Size nStrmPos
) const;
248 sal_uInt16
GetOffsetInBlock( sal_Size nStrmPos
) const;
251 ::svx::MSCodec_Std97 maCodec
; /// Crypto algorithm implementation.
252 sal_uInt16 mnPassw
[16]; /// Cached password data for copy construction.
253 sal_uInt8 mnDocId
[16]; /// Cached document ID for copy construction.
254 sal_uInt8 mnSaltDigest
[16];
256 const XclExpRoot
& mrRoot
;
257 sal_Size mnOldPos
; /// Last known stream position
261 // ----------------------------------------------------------------------------
264 // ============================================================================
266 // `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
267 #define XESTRING_TO_PSZ(s) \
268 (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
283 XclXmlUtils(const XclXmlUtils
&);
284 XclXmlUtils
& operator=(const XclXmlUtils
&);
286 static ::rtl::OUString
GetStreamName( const char* sStreamDir
, const char* sStream
, sal_Int32 nId
);
288 static ::rtl::OString
ToOString( const Color
& rColor
);
289 static ::rtl::OString
ToOString( const ::rtl::OUString
& s
);
290 static ::rtl::OString
ToOString( const ScfUInt16Vec
& rBuffer
);
291 static ::rtl::OString
ToOString( const String
& s
);
292 static ::rtl::OString
ToOString( const ScAddress
& rRange
);
293 static ::rtl::OString
ToOString( const ScRange
& rRange
);
294 static ::rtl::OString
ToOString( const ScRangeList
& rRangeList
);
295 static ::rtl::OString
ToOString( const XclAddress
& rAddress
);
296 static ::rtl::OString
ToOString( const XclExpString
& s
);
297 static ::rtl::OString
ToOString( const XclRangeList
& rRangeList
);
299 static ::rtl::OUString
ToOUString( const char* s
);
300 static ::rtl::OUString
ToOUString( const ScfUInt16Vec
& rBuffer
, sal_Int32 nStart
= 0, sal_Int32 nLength
= -1 );
301 static ::rtl::OUString
ToOUString( const String
& s
);
302 static ::rtl::OUString
ToOUString( ScDocument
& rDocument
, const ScAddress
& rAddress
, ScTokenArray
* pTokenArray
);
303 static ::rtl::OUString
ToOUString( const XclExpString
& s
);
304 static const char* ToPsz( bool b
);
307 class XclExpXmlStream
: public oox::core::XmlFilterBase
310 XclExpXmlStream( const com::sun::star::uno::Reference
< com::sun::star::lang::XMultiServiceFactory
>& rSMgr
, SvStream
& rStrm
, const XclExpRoot
& rRoot
);
311 virtual ~XclExpXmlStream();
313 /** Returns the filter root data. */
314 inline const XclExpRoot
& GetRoot() const { return mrRoot
; }
316 sax_fastparser::FSHelperPtr
& GetCurrentStream();
317 void PushStream( sax_fastparser::FSHelperPtr aStream
);
320 ::rtl::OUString
GetIdForPath( const ::rtl::OUString
& rPath
);
321 sax_fastparser::FSHelperPtr
GetStreamForPath( const ::rtl::OUString
& rPath
);
323 sax_fastparser::FSHelperPtr
& WriteAttributes( sal_Int32 nAttribute
, ... );
324 sax_fastparser::FSHelperPtr
& WriteFontData( const XclFontData
& rFontData
, sal_Int32 nNameId
);
326 sax_fastparser::FSHelperPtr
CreateOutputStream (
327 const ::rtl::OUString
& sFullStream
,
328 const ::rtl::OUString
& sRelativeStream
,
329 const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XOutputStream
>& xParentRelation
,
330 const char* sContentType
,
331 const char* sRelationshipType
,
332 ::rtl::OUString
* pRelationshipId
= NULL
);
335 virtual bool exportDocument() throw();
337 // only needed for import; ignore
338 virtual bool importDocument() throw();
339 virtual oox::vml::Drawing
* getVmlDrawing();
340 virtual const oox::drawingml::Theme
* getCurrentTheme() const;
341 virtual const oox::drawingml::table::TableStyleListPtr
getTableStyles();
342 virtual oox::drawingml::chart::ChartConverter
& getChartConverter();
344 void Trace( const char* format
, ...);
346 virtual ::rtl::OUString
implGetImplementationName() const;
348 typedef std::map
< ::rtl::OUString
,
349 std::pair
< ::rtl::OUString
,
350 sax_fastparser::FSHelperPtr
> > XclExpXmlPathToStateMap
;
352 const XclExpRoot
& mrRoot
; /// Filter root data.
353 std::stack
< sax_fastparser::FSHelperPtr
> maStreams
;
354 XclExpXmlPathToStateMap maOpenedStreamMap
;