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