Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef SC_XERECORD_HXX
21 : #define SC_XERECORD_HXX
22 :
23 : #include "xlconst.hxx"
24 : #include "xestream.hxx"
25 : #include <boost/shared_ptr.hpp>
26 :
27 : // Base classes to export Excel records =======================================
28 :
29 : /** Base class for all Excel records.
30 :
31 : Derive from this class to implement any functionality performed during
32 : saving the records - except really writing a record (i.e. write a list of
33 : records contained in the class). Derive from XclExpRecord (instead from
34 : this class) to write common records.
35 : */
36 1652 : class XclExpRecordBase
37 : {
38 : public:
39 : virtual ~XclExpRecordBase();
40 :
41 : /** Overwrite this method to do any operation while saving the record. */
42 : virtual void Save( XclExpStream& rStrm );
43 : virtual void SaveXml( XclExpXmlStream& rStrm );
44 : };
45 :
46 : // ----------------------------------------------------------------------------
47 :
48 : class XclExpDelegatingRecord : public XclExpRecordBase
49 : {
50 : public:
51 : XclExpDelegatingRecord( XclExpRecordBase* pRecord );
52 : ~XclExpDelegatingRecord();
53 :
54 : virtual void SaveXml( XclExpXmlStream& rStrm );
55 : private:
56 : XclExpRecordBase* mpRecord;
57 : };
58 :
59 : // ----------------------------------------------------------------------------
60 :
61 : class XclExpXmlElementRecord : public XclExpRecordBase
62 : {
63 : public:
64 : XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
65 : virtual ~XclExpXmlElementRecord();
66 :
67 : protected:
68 : sal_Int32 mnElement;
69 : void (*mpAttributes)( XclExpXmlStream& rStrm );
70 : };
71 :
72 : // ----------------------------------------------------------------------------
73 :
74 : class XclExpXmlStartElementRecord : public XclExpXmlElementRecord
75 : {
76 : public:
77 : XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
78 : virtual ~XclExpXmlStartElementRecord();
79 :
80 : /** Starts the element nElement */
81 : virtual void SaveXml( XclExpXmlStream& rStrm );
82 : };
83 :
84 : // ----------------------------------------------------------------------------
85 :
86 : class XclExpXmlEndElementRecord : public XclExpXmlElementRecord
87 : {
88 : public:
89 : XclExpXmlEndElementRecord( sal_Int32 nElement );
90 : virtual ~XclExpXmlEndElementRecord();
91 :
92 : /** Ends the element nElement */
93 : virtual void SaveXml( XclExpXmlStream& rStrm );
94 : };
95 :
96 : // ----------------------------------------------------------------------------
97 :
98 : class XclExpXmlStartSingleElementRecord : public XclExpXmlElementRecord
99 : {
100 : public:
101 : XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
102 : virtual ~XclExpXmlStartSingleElementRecord();
103 :
104 : /** Starts the single element nElement */
105 : virtual void SaveXml( XclExpXmlStream& rStrm );
106 : };
107 :
108 : // ----------------------------------------------------------------------------
109 :
110 : class XclExpXmlEndSingleElementRecord : public XclExpRecordBase
111 : {
112 : public:
113 : XclExpXmlEndSingleElementRecord();
114 : virtual ~XclExpXmlEndSingleElementRecord();
115 :
116 : /** Ends the single element nElement */
117 : virtual void SaveXml( XclExpXmlStream& rStrm );
118 : };
119 :
120 : // ----------------------------------------------------------------------------
121 :
122 : /** Base class for single records with any content.
123 :
124 : This class handles writing the record header. Derived classes only have to
125 : write the record body. Calculating the record size before saving optimizes
126 : the write process (the stream does not have to seek back and update the
127 : written record size). But it is not required to calculate a valid size
128 : (maybe it would be too complex or just impossible until the record is
129 : really written).
130 : */
131 19 : class XclExpRecord : public XclExpRecordBase
132 : {
133 : public:
134 : /** @param nRecId The record ID of this record. May be set later with SetRecId().
135 : @param nRecSize The predicted record size. May be set later with SetRecSize(). */
136 : explicit XclExpRecord(
137 : sal_uInt16 nRecId = EXC_ID_UNKNOWN,
138 : sal_Size nRecSize = 0 );
139 :
140 : virtual ~XclExpRecord();
141 :
142 : /** Returns the current record ID. */
143 2 : inline sal_uInt16 GetRecId() const { return mnRecId; }
144 : /** Returns the current record size prediction. */
145 0 : inline sal_Size GetRecSize() const { return mnRecSize; }
146 :
147 : /** Sets a new record ID. */
148 22 : inline void SetRecId( sal_uInt16 nRecId ) { mnRecId = nRecId; }
149 : /** Sets a new record size prediction. */
150 27 : inline void SetRecSize( sal_Size nRecSize ) { mnRecSize = nRecSize; }
151 : /** Adds a size value to the record size prediction. */
152 0 : inline void AddRecSize( sal_Size nRecSize ) { mnRecSize += nRecSize; }
153 : /** Sets record ID and size with one call. */
154 : void SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize );
155 :
156 : /** Writes the record header and calls WriteBody(). */
157 : virtual void Save( XclExpStream& rStrm );
158 :
159 : protected:
160 : /** Writes the body of the record (without record header).
161 : @descr Usually this method will be overwritten by derived classes. */
162 : virtual void WriteBody( XclExpStream& rStrm );
163 :
164 : private:
165 : sal_Size mnRecSize; /// The predicted record size.
166 : sal_uInt16 mnRecId; /// The record ID.
167 : };
168 :
169 : // ----------------------------------------------------------------------------
170 :
171 : /** A record without body. Only the record ID and the size 0 will be written. */
172 2 : class XclExpEmptyRecord : public XclExpRecord
173 : {
174 : public:
175 : /** @param nRecId The record ID of this record. */
176 : inline explicit XclExpEmptyRecord( sal_uInt16 nRecId );
177 : };
178 :
179 1 : inline XclExpEmptyRecord::XclExpEmptyRecord( sal_uInt16 nRecId ) :
180 1 : XclExpRecord( nRecId, 0 )
181 : {
182 1 : }
183 :
184 : // ============================================================================
185 :
186 : /** A record with a single value of type Type.
187 : @descr Requires operator<<( XclExpStream&, const Type& ). */
188 : template< typename Type >
189 15 : class XclExpValueRecord : public XclExpRecord
190 : {
191 : public:
192 : /** @param nRecId The record ID of this record.
193 : @param rValue The value for the record body.
194 : @param nSize Record size. Uses sizeof( Type ), if this parameter is omitted. */
195 12 : inline explicit XclExpValueRecord( sal_uInt16 nRecId, const Type& rValue, sal_Size nSize = sizeof( Type ) ) :
196 12 : XclExpRecord( nRecId, nSize ), maValue( rValue ), mnAttribute( -1 ) {}
197 :
198 : /** Returns the value of the record. */
199 2 : inline const Type& GetValue() const { return maValue; }
200 : /** Sets a new record value. */
201 1 : inline void SetValue( const Type& rValue ) { maValue = rValue; }
202 :
203 : /** Sets the OOXML attribute this record corresponds to */
204 : XclExpValueRecord* SetAttribute( sal_Int32 nId );
205 :
206 : /** Write the OOXML attribute and its value */
207 : void SaveXml( XclExpXmlStream& rStrm );
208 :
209 : private:
210 : /** Writes the body of the record. */
211 0 : inline virtual void WriteBody( XclExpStream& rStrm ) { rStrm << maValue; }
212 : // inlining prevents warning in wntmsci10
213 :
214 : private:
215 : Type maValue; /// The record data.
216 : sal_Int32 mnAttribute; /// The OOXML attribute Id
217 : };
218 :
219 : template< typename Type >
220 4 : void XclExpValueRecord< Type >::SaveXml( XclExpXmlStream& rStrm )
221 : {
222 4 : if( mnAttribute == -1 )
223 8 : return;
224 0 : rStrm.WriteAttributes(
225 : mnAttribute, rtl::OString::valueOf( (sal_Int32) maValue ).getStr(),
226 : FSEND );
227 : }
228 :
229 : template<>
230 : void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm );
231 :
232 : template< typename Type >
233 6 : XclExpValueRecord< Type >* XclExpValueRecord< Type >::SetAttribute( sal_Int32 nId )
234 : {
235 6 : mnAttribute = nId;
236 6 : return this;
237 : }
238 :
239 : // ----------------------------------------------------------------------------
240 :
241 : /** A record containing an unsigned 16-bit value. */
242 : typedef XclExpValueRecord< sal_uInt16 > XclExpUInt16Record;
243 :
244 : /** A record containing an unsigned 32-bit value. */
245 : typedef XclExpValueRecord< sal_uInt32 > XclExpUInt32Record;
246 :
247 : /** A record containing a double value. */
248 : typedef XclExpValueRecord< double > XclExpDoubleRecord;
249 :
250 : // ----------------------------------------------------------------------------
251 :
252 : /** Record which contains a Boolean value.
253 : @descr The value is stored as 16-bit value: 0x0000 = sal_False, 0x0001 = TRUE. */
254 26 : class XclExpBoolRecord : public XclExpRecord
255 : {
256 : public:
257 : /** @param nRecId The record ID of this record.
258 : @param nValue The value for the record body. */
259 16 : inline explicit XclExpBoolRecord( sal_uInt16 nRecId, bool bValue, sal_Int32 nAttribute = -1 ) :
260 16 : XclExpRecord( nRecId, 2 ), mbValue( bValue ), mnAttribute( nAttribute ) {}
261 :
262 : /** Returns the Boolean value of the record. */
263 1 : inline bool GetBool() const { return mbValue; }
264 : /** Sets a new Boolean record value. */
265 : inline void SetBool( bool bValue ) { mbValue = bValue; }
266 :
267 : virtual void SaveXml( XclExpXmlStream& rStrm );
268 :
269 : private:
270 : /** Writes the body of the record. */
271 : virtual void WriteBody( XclExpStream& rStrm );
272 :
273 : private:
274 : bool mbValue; /// The record data.
275 : sal_Int32 mnAttribute; /// The attribute to generate within SaveXml()
276 : };
277 :
278 : // ----------------------------------------------------------------------------
279 :
280 : /** Record which exports a memory data array. */
281 2 : class XclExpDummyRecord : public XclExpRecord
282 : {
283 : public:
284 : /** @param nRecId The record ID of this record.
285 : @param pRecData Pointer to the data array representing the record body.
286 : @param nRecSize Size of the data array. */
287 : explicit XclExpDummyRecord(
288 : sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize );
289 :
290 : /** Sets a data array. */
291 : void SetData( const void* pRecData, sal_Size nRecSize );
292 :
293 : private:
294 : /** Writes the body of the record. */
295 : virtual void WriteBody( XclExpStream& rStrm );
296 :
297 : private:
298 : const void* mpData; /// The record data.
299 : };
300 :
301 : // Future records =============================================================
302 :
303 0 : class XclExpFutureRecord : public XclExpRecord
304 : {
305 : public:
306 : explicit XclExpFutureRecord( XclFutureRecType eRecType,
307 : sal_uInt16 nRecId, sal_Size nRecSize = 0 );
308 :
309 : /** Writes the extended record header and calls WriteBody(). */
310 : virtual void Save( XclExpStream& rStrm );
311 :
312 : private:
313 : XclFutureRecType meRecType;
314 : };
315 :
316 : // List of records ============================================================
317 :
318 : /** A list of Excel record objects.
319 :
320 : Provides saving the compete list. This class is derived from
321 : XclExpRecordBase, so it can be used as record in another record list.
322 : Requires RecType::Save( XclExpStream& ).
323 : */
324 : template< typename RecType = XclExpRecordBase >
325 116 : class XclExpRecordList : public XclExpRecordBase
326 : {
327 : public:
328 : typedef boost::shared_ptr< RecType > RecordRefType;
329 :
330 139 : inline bool IsEmpty() const { return maRecs.empty(); }
331 3128 : inline size_t GetSize() const { return maRecs.size(); }
332 :
333 : /** Returns true, if the passed index points to an exiting record. */
334 : inline bool HasRecord( size_t nPos ) const
335 : { return nPos < maRecs.size(); }
336 : /** Returns reference to an existing record or empty reference on error. */
337 9073 : inline RecordRefType GetRecord( size_t nPos ) const
338 9073 : { return (nPos < maRecs.size()) ? maRecs[ nPos ] : RecordRefType(); }
339 : /** Returns reference to the first existing record or empty reference, if list is empty. */
340 22 : inline RecordRefType GetFirstRecord() const
341 22 : { return maRecs.empty() ? RecordRefType() : maRecs.front(); }
342 : /** Returns reference to the last existing record or empty reference, if list is empty. */
343 22 : inline RecordRefType GetLastRecord() const
344 22 : { return maRecs.empty() ? RecordRefType() : maRecs.back(); }
345 :
346 : /** Inserts a record at the specified position into the list. */
347 376 : inline void InsertRecord( RecordRefType xRec, size_t nPos )
348 376 : { if( xRec.get() ) maRecs.insert( maRecs.begin() + ::std::min( nPos, maRecs.size() ), xRec ); }
349 : /** Appends a record to the list. */
350 1169 : inline void AppendRecord( RecordRefType xRec )
351 1169 : { if( xRec.get() ) maRecs.push_back( xRec ); }
352 : /** Replaces the record at the specified position from the list with the passed record. */
353 2 : inline void ReplaceRecord( RecordRefType xRec, size_t nPos )
354 2 : { RemoveRecord( nPos ); InsertRecord( xRec, nPos ); }
355 :
356 : /** Inserts a newly created record at the specified position into the list. */
357 : inline void InsertNewRecord( RecType* pRec, size_t nPos )
358 : { if( pRec ) InsertRecord( RecordRefType( pRec ), nPos ); }
359 : /** Appends a newly created record to the list. */
360 1096 : inline void AppendNewRecord( RecType* pRec )
361 1096 : { if( pRec ) AppendRecord( RecordRefType( pRec ) ); }
362 : /** Replaces the record at the specified position from the list with the passed newly created record. */
363 : inline void ReplaceNewRecord( RecType* pRec, size_t nPos )
364 : { RemoveRecord( nPos ); InsertNewRecord( pRec, nPos ); }
365 :
366 : /** Removes the record at the specified position from the list. */
367 1223 : inline void RemoveRecord( size_t nPos )
368 1223 : { if( nPos < maRecs.size() ) maRecs.erase( maRecs.begin() + nPos ); }
369 : /** Removes all records from the list. */
370 1 : inline void RemoveAllRecords() { maRecs.clear(); }
371 :
372 : /** Writes the complete record list. */
373 0 : inline virtual void Save( XclExpStream& rStrm )
374 : {
375 : // inlining prevents warning in wntmsci10
376 0 : for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
377 0 : (*aIt)->Save( rStrm );
378 0 : }
379 :
380 37 : inline virtual void SaveXml( XclExpXmlStream& rStrm )
381 : {
382 : // inlining prevents warning in wntmsci10
383 306 : for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
384 269 : (*aIt)->SaveXml( rStrm );
385 37 : }
386 :
387 : private:
388 : typedef ::std::vector< RecordRefType > RecordVec;
389 : RecordVec maRecs;
390 : };
391 :
392 : // ============================================================================
393 :
394 : /** Represents a complete substream of records enclosed into a pair of BOF/EOF records. */
395 0 : class XclExpSubStream : public XclExpRecordList<>
396 : {
397 : public:
398 : explicit XclExpSubStream( sal_uInt16 nSubStrmType );
399 :
400 : /** Writes the complete substream, including leading BOF and trailing EOF. */
401 : virtual void Save( XclExpStream& rStrm );
402 :
403 : private:
404 : sal_uInt16 mnSubStrmType; /// Substream type, stored in leading BOF record.
405 : };
406 :
407 : // ============================================================================
408 :
409 : #endif
410 :
411 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|