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