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