summaryrefslogtreecommitdiff
path: root/sc/source/filter/inc/xestream.hxx
blob: 14de4e71e5e8ff48b47cccbe7083f7dbbcd4bfb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/*************************************************************************
 *
 *  $RCSfile: xestream.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-26 18:05:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// ============================================================================

#ifndef SC_XESTREAM_HXX
#define SC_XESTREAM_HXX

#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif

#ifndef SC_FTOOLS_HXX
#include "ftools.hxx"
#endif


/* ============================================================================
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
{
private:
    SvStream&                   mrStrm;         /// Reference to the system output stream.
    const XclExpRoot&           mrRoot;         /// Filter root data.

                                // length data
    sal_uInt32                  mnMaxRecSize;   /// Maximum size of record content.
    sal_uInt32                  mnMaxContSize;  /// Maximum size of CONTINUE content.
    sal_uInt32                  mnCurrMaxSize;  /// Current maximum, either mnMaxRecSize or mnMaxContSize.
    sal_uInt32                  mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split).
    sal_uInt32                  mnCalcSize;     /// Calculated size received from calling function.
    sal_uInt32                  mnHeaderSize;   /// Record size written in last record header.
    sal_uInt32                  mnCurrSize;     /// Count of bytes already written in current record.
    sal_uInt32                  mnSliceSize;    /// Count of bytes already written in current slice.

                                // stream position data
    sal_uInt32                  mnLastSizePos;  /// Stream position of size field in current header.
    bool                        mbInRec;        /// true = currently writing inside of a record.

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_uInt32 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_uInt32 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_uInt32           GetRecPos() const                   { return mnCurrSize; }

    /** Returns the maximum size of a record. */
    inline sal_uInt32           GetMaxRecSize() const               { return mnMaxRecSize; }
    /** Sets maximum record size (valid only for current record). */
    inline void                 SetMaxRecSize( sal_uInt32 nMax )    { mnCurrMaxSize = nMax; }
    /** Sets maximum size of CONTINUE records (valid only for current record). */
    inline void                 SetMaxContSize( sal_uInt32 nMax )   { mnMaxContSize = nMax; }

    /** Sets data slice length. 0 = no slices. */
    void                        SetSliceSize( sal_uInt32 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_uInt32                  Write( const void* pData, sal_uInt32 nBytes );
    /** Writes a sequence of nBytes zero bytes (respects slice setting). */
    void                        WriteZeroBytes( sal_uInt32 nBytes );
    /** Copies nBytes bytes from current position of the stream rInStrm.
        @descr  Omitting the second parameter means: read to end of stream. */
    sal_uInt32                  CopyFromStream( SvStream& rInStrm, sal_uInt32 nBytes = STREAM_SEEK_TO_END );

    // *** unicode string export is realized with helper class XclExpString ***
    // (slice length setting has no effect here -> disabled automatically)

    /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */
    void                        WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_uInt32 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)

    /** Writes ByteString buffer (without string length field). */
    void                        WriteByteStringBuffer(
                                    const ByteString& rString,
                                    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_uInt32                  SetStreamPos( sal_uInt32 nPos );
    /** Returns the absolute position of the system stream. */
    inline sal_uInt32           GetStreamPos() 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_uInt32 nSize );
    /** Writes CONTINUE header, internal setup. */
    void                        StartContinue();
    /** Refreshes counter vars, creates CONTINUE records. */
    void                        PrepareWrite( sal_uInt32 nSize );
    /** Creates CONTINUE record at end of record.
        @return  Maximum data block size remaining. */
    sal_uInt32                  PrepareWrite();

    /** Writes a raw sequence of zero bytes. */
    void                        WriteRawZeroBytes( sal_uInt32 nBytes );
};


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;
}


// ============================================================================

/** Function object to stream out an object, useful i.e. for ::std::for_each(). */
template< typename Type > struct XclWriteFunc
{
    XclExpStream&               mrStrm;
    inline explicit             XclWriteFunc( XclExpStream& rStrm ) : mrStrm( rStrm ) {}
    inline void                 operator()( const Type& rObj ) { mrStrm << rObj; }
};


// ============================================================================

#endif