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