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
);
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 // ----------------------------------------------------------------------------
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;
252 ::svx::MSCodec_Std97 maCodec
; /// Crypto algorithm implementation.
253 sal_uInt16 mnPassw
[16]; /// Cached password data for copy construction.
254 sal_uInt8 mnDocId
[16]; /// Cached document ID for copy construction.
255 sal_uInt8 mnSaltDigest
[16];
257 const XclExpRoot
& mrRoot
;
258 sal_Size mnOldPos
; /// Last known stream position
262 // ----------------------------------------------------------------------------
265 // ============================================================================
267 // `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
268 #define XESTRING_TO_PSZ(s) \
269 (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL)
284 XclXmlUtils(const XclXmlUtils
&);
285 XclXmlUtils
& operator=(const XclXmlUtils
&);
287 static ::rtl::OUString
GetStreamName( const char* sStreamDir
, const char* sStream
, sal_Int32 nId
);
289 static ::rtl::OString
ToOString( const Color
& rColor
);
290 static ::rtl::OString
ToOString( const ::rtl::OUString
& s
);
291 static ::rtl::OString
ToOString( const ScfUInt16Vec
& rBuffer
);
292 static ::rtl::OString
ToOString( const String
& s
);
293 static ::rtl::OString
ToOString( const ScAddress
& rRange
);
294 static ::rtl::OString
ToOString( const ScRange
& rRange
);
295 static ::rtl::OString
ToOString( const ScRangeList
& rRangeList
);
296 static ::rtl::OString
ToOString( const XclAddress
& rAddress
);
297 static ::rtl::OString
ToOString( const XclExpString
& s
);
298 static ::rtl::OString
ToOString( const XclRangeList
& rRangeList
);
300 static ::rtl::OUString
ToOUString( const char* s
);
301 static ::rtl::OUString
ToOUString( const ScfUInt16Vec
& rBuffer
, sal_Int32 nStart
= 0, sal_Int32 nLength
= -1 );
302 static ::rtl::OUString
ToOUString( const String
& s
);
303 static ::rtl::OUString
ToOUString( ScDocument
& rDocument
, const ScAddress
& rAddress
, ScTokenArray
* pTokenArray
);
304 static ::rtl::OUString
ToOUString( const XclExpString
& s
);
305 static const char* ToPsz( bool b
);
308 class XclExpXmlStream
: public oox::core::XmlFilterBase
311 XclExpXmlStream( const com::sun::star::uno::Reference
< com::sun::star::lang::XMultiServiceFactory
>& rSMgr
, SvStream
& rStrm
, const XclExpRoot
& rRoot
);
312 virtual ~XclExpXmlStream();
314 /** Returns the filter root data. */
315 inline const XclExpRoot
& GetRoot() const { return mrRoot
; }
317 sax_fastparser::FSHelperPtr
& GetCurrentStream();
318 void PushStream( sax_fastparser::FSHelperPtr aStream
);
321 ::rtl::OUString
GetIdForPath( const ::rtl::OUString
& rPath
);
322 sax_fastparser::FSHelperPtr
GetStreamForPath( const ::rtl::OUString
& rPath
);
324 sax_fastparser::FSHelperPtr
& WriteAttributes( sal_Int32 nAttribute
, ... );
325 sax_fastparser::FSHelperPtr
& WriteFontData( const XclFontData
& rFontData
, sal_Int32 nNameId
);
327 sax_fastparser::FSHelperPtr
CreateOutputStream (
328 const ::rtl::OUString
& sFullStream
,
329 const ::rtl::OUString
& sRelativeStream
,
330 const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XOutputStream
>& xParentRelation
,
331 const char* sContentType
,
332 const char* sRelationshipType
,
333 ::rtl::OUString
* pRelationshipId
= NULL
);
336 virtual bool exportDocument() throw();
338 // only needed for import; ignore
339 virtual bool importDocument() throw();
340 virtual sal_Int32
getSchemeClr( sal_Int32 nColorSchemeToken
) const;
341 virtual const oox::vml::DrawingPtr
getDrawings();
342 virtual const oox::drawingml::Theme
* getCurrentTheme() const;
343 virtual const oox::drawingml::table::TableStyleListPtr
getTableStyles();
344 virtual oox::drawingml::chart::ChartConverter
* getChartConverter();
346 void Trace( const char* format
, ...);
348 virtual ::rtl::OUString
implGetImplementationName() const;
350 typedef std::map
< ::rtl::OUString
,
351 std::pair
< ::rtl::OUString
,
352 sax_fastparser::FSHelperPtr
> > XclExpXmlPathToStateMap
;
354 const XclExpRoot
& mrRoot
; /// Filter root data.
355 std::stack
< sax_fastparser::FSHelperPtr
> maStreams
;
356 XclExpXmlPathToStateMap maOpenedStreamMap
;