Branch libreoffice-5-0-4
[LibreOffice.git] / include / svl / filerec.hxx
blob9dfc58664fca4115452a3af1703beb82f6f4cfc5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SVL_FILEREC_HXX
21 #define INCLUDED_SVL_FILEREC_HXX
23 #include <sal/config.h>
25 #include <sal/log.hxx>
26 #include <svl/svldllapi.h>
27 #include <tools/debug.hxx>
28 #include <tools/stream.hxx>
29 #include <osl/diagnose.h>
31 #include <vector>
33 #define SFX_REC_PRETAG_EXT sal_uInt8(0x00) // Pre-Tag for Extended-Records
34 #define SFX_REC_PRETAG_EOR sal_uInt8(0xFF) // Pre-Tag for End-Of-Records
36 #define SFX_REC_TYPE_SINGLE sal_uInt8(0x01) // Single-Content-Record
37 #define SFX_REC_TYPE_FIXSIZE sal_uInt8(0x02) // Fix-Size-Multi-Content-Record
38 #define SFX_REC_TYPE_VARSIZE_RELOC sal_uInt8(0x03) // variable Rec-Size
39 #define SFX_REC_TYPE_VARSIZE sal_uInt8(0x04) // old (not movable)
40 #define SFX_REC_TYPE_MIXTAGS_RELOC sal_uInt8(0x07) // Mixed Tag Content-Record
41 #define SFX_REC_TYPE_MIXTAGS sal_uInt8(0x08) // old (not movable)
43 #define SFX_REC_HEADERSIZE_MINI 4 // size of the Mini-Record-Header
44 #define SFX_REC_HEADERSIZE_SINGLE 4 // additional HEADERSIZE_MINI => 8
45 #define SFX_REC_HEADERSIZE_MULTI 6 // additional HEADERSIZE_SINGLE => 14
48 // General file format: documented at class SfxMiniRecordReader below
50 /** Writes simple records in a stream
52 * An instance of this class can write a simple record into a stream. It identifies itself
53 * with a sal_uInt8 and stores its own size. This allows it to be skipped with old versions or
54 * readers if they do not know the record type (= tag). No version number will be stored.
56 * One can either provide the size or the latter will be automatically calculated based on the
57 * difference of Tell() before and after streaming the content.
59 * @par File format
61 * 1* sal_uInt8 Content-Tag (!= 0)
62 * 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
63 * SizeOfContent* sal_uInt8 Content
65 * @par Example
66 * @code
67 * {
68 * SfxMiniRecordWriter aRecord( pStream, MY_TAG_X );
69 * *aRecord << aMember1;
70 * *aRecord << aMember2;
71 * }
72 * @endcode
74 * @note To ensure up- and downwards compatibility, new versions need to include
75 * the data of the older ones and are only allowed to add data afterwards.
76 * @see SfxMiniRecordReader
78 class SVL_DLLPUBLIC SfxMiniRecordWriter
80 protected:
81 SvStream* _pStream; // <SvStream> with the record
82 sal_uInt32 _nStartPos; // starting position of the total record in the stream
83 bool _bHeaderOk; /* TRUE, if header already written */
84 sal_uInt8 _nPreTag; // 'pre-Tag' to write to header
86 public:
87 inline SfxMiniRecordWriter( SvStream *pStream, sal_uInt8 nTag );
88 inline ~SfxMiniRecordWriter();
90 inline SvStream& operator*() const;
92 inline void Reset();
93 sal_uInt32 Close( bool bSeekToEndOfRec = true );
95 private:
96 SfxMiniRecordWriter( const SfxMiniRecordWriter& ) SAL_DELETED_FUNCTION;
97 SfxMiniRecordWriter& operator=(const SfxMiniRecordWriter&) SAL_DELETED_FUNCTION;
100 /** Reads simple record from a stream
102 * An instance of this class allows to read a simple record from a stream that was written by
103 * SfxMiniRecordWriter. It is also possible to skip a record, even without knowing its internal
104 * format.
106 * @par Example
107 * @code
109 * SfxMiniRecordReader aRecord( pStream );
110 * switch ( aRecord.GetTag() )
112 * case MY_TAG_X:
113 * *aRecord >> aMember1;
114 * *aRecord >> aMember2;
115 * break;
117 * ...
120 * @endcode
122 * @par General file format
124 * Each record begins with one byte, the so called 'Pre-Tag'.
126 * If this 'Pre-Tag' == 0x00, then the record is a extended record,
127 * whose type is further determined by another byte at position 5:
129 * 0x01: SfxSingleRecord
130 * 0x02: SfxMultiFixRecord
131 * 0x03+0x04: SfxMultiVarRecord
132 * 0x07+0x08: SfxMultiMixRecord
133 * (All other possible record types are reserved.)
135 * Normally, if only for performance reasons, the file formats are
136 * constructed in such a way, that when loading the record type
137 * is predetermined. So the record type serves mainly for checks
138 * and for file viewers that do not know the exact file format.
140 * For that purpse 'SfxMiniRecordReader' provides a static method
141 * 'ScanRecordType()', with which it is possible to find out what
142 * Record type can be found in the stream that was passed.
144 * A 'Pre-Tag' with value 0xFF is reserved for a terminator.
145 * Terminators are used to stop looking for a particular record,
146 * i.e. if it was not found until then the search will not be continued.
148 * For all other values of the 'Pre-Tag' (so 0x01 to 0xFE) the record
149 * is one that is compatible with SW3, called 'SfxMiniRecord' here,
150 * and therefore it can be read with an <SfxMiniRecordReader>.
152 * If the record starts with 0x44 it could be a Drawing-Engine-Record.
153 * This is the case if the following 3 bytes spell 'RMD' or 'RVW'
154 * (which together with 'D'==0x44 form an abbreviation for 'DRaw-MoDel'
155 * or 'DRaw-VieW'). Records of this type cannot be readby the classes
156 * represented here, nor interpreted in any way. Only the
157 * 'ScanRecordType()' method can recognise it - but further processing
158 * is impossible.
160 * The 3 bytes in position 2 to 4 normally contain the size of the
161 * record without the pre-tag and the size field itself,
162 * so the remaining size after the 4 byte header.
164 * Structure of the Mini-Records:
166 * 1 sal_uInt8 Pre-Tag
167 * 3 sal_uInt8 OffsetToEndOfRec
168 * OffsetToEndOfRec* 1 sal_uInt8 Content
170 * For Extended-Reords the 4 byte header is followed by an extended header,
171 * which contains first the record type, than a version number
172 * and a tag, which indicates the kind of content.
174 * Structure of the extended record:
176 * 1 sal_uInt8 Pre-Tag (==0x00)
177 * 3 sal_uInt8 OffsetToEndOfRec
178 * OffsetToEndOfRec* 1 sal_uInt8 Content
179 * 1 sal_uInt8 Record-Type
180 * 1 sal_uInt8 Version
181 * 2 sal_uInt8 Tag
182 * ContentSize* 1 sal_uInt8 Content
184 * (ContentSize = OffsetToEndOfRec - 8)
186 * @note
187 * The reason for the structure of the record is as follows:
189 * The SW record type came first, and so had to be kept 1:1.
190 * Fortunately some record tags had not been used (like 0x00 and 0xFF).
191 * <BR>
192 * => 1st byte 0x00 can be used to identify extended records
193 * <BR>
194 * => 1st byte 0xFF can be used for special purposes.
196 * Whatever record type is present, it should be possible to recognise
197 * the type, read the header and skip the record without having to
198 * seek back or read superfluous data.
199 * <BR>
200 * => Bytes 2-4 are interpreted as the offset to the end of the record
201 * whatever the record, so that the total record size is equal
202 * to sizeof(sal_uInt32) + OffsetToEndOfRec
204 * The records should be easy to parse and constructed uniformly
205 * <BR>
206 * => They build on each, for instance the SfxMiniRecord is contained
207 * in all others
209 * It should be possible to distinguish the record from Drawing Enginge
210 * ones. These start with 'DRMD' und 'DRVW'.
211 * <BR>
212 * => Mini-Records with Pre-Tag 'D' can only be up to 4MB in size,
213 * to avoid confusion.
215 * @par Extensions
216 * Plans are to extend the file format in such a way that the high nibble
217 * of the record type has special duties. For instance it is planned
218 * to mark Record-Contents als 'consisting only of Records'. That way
219 * a file viewer could automatically parse these structures without
220 * risking encountering data that looks like records, but actually is
221 * flat data. Those further extensions are prepared to the extent
222 * that in type comparisons the high nibble is not taken into account.
224 * @see SfxMiniRecordWriter
226 class SVL_DLLPUBLIC SfxMiniRecordReader
228 protected:
229 SvStream* _pStream; // <SvStream> to read from
230 sal_uInt32 _nEofRec; // Position direcly after the record
231 bool _bSkipped; // TRUE: the record was skipped explicitly
232 sal_uInt8 _nPreTag; // Pre-Tag read from the heather
234 // three phase constructor for sub-classes
235 SfxMiniRecordReader()
236 : _pStream(NULL)
237 , _nEofRec(0)
238 , _bSkipped(false)
239 , _nPreTag(0)
242 void Construct_Impl( SvStream *pStream, sal_uInt8 nTag )
244 _pStream = pStream;
245 _bSkipped = false;
246 _nPreTag = nTag;
248 inline bool SetHeader_Impl( sal_uInt32 nHeader );
250 // mark as invalid and seek back
251 void SetInvalid_Impl( sal_uInt32 nRecordStartPos )
253 _nPreTag = SFX_REC_PRETAG_EOR;
254 _pStream->Seek( nRecordStartPos );
257 public:
258 SfxMiniRecordReader( SvStream *pStream, sal_uInt8 nTag );
259 inline ~SfxMiniRecordReader();
261 inline sal_uInt8 GetTag() const;
262 inline bool IsValid() const;
264 inline SvStream& operator*() const;
266 inline void Skip();
268 private:
269 SfxMiniRecordReader( const SfxMiniRecordReader& ) SAL_DELETED_FUNCTION;
270 SfxMiniRecordReader& operator=(const SfxMiniRecordReader&) SAL_DELETED_FUNCTION;
275 * With instances of this class a record ban be written to a stream,
276 * whose only contents is identified by a sal_uInt16 tag and a
277 * sal_uInt8 version number. Also the length of the record is stored
278 * so that older versions or readers that do not known the
279 * record type (tag) can skip it.
281 * The size can be given directly or calculated automatically from
282 * the difference between the tell() return values before and
283 * after streaming the conntents.
285 * To allow for forward and backward compatibility, newer versions
286 * of the data must always inclode the older versions completely,
287 * it is only allowed to append new data!
289 * @par File Format
291 * 1* sal_uInt8 Pre-Tag (!= 0)
292 * 1* 3-sal_uInt8 OffsetToEndOfRec in bytes
293 * 1* sal_uInt8 Record-Type (==SFX_REC_TYPE_SINGLE)
294 * 1* sal_uInt8 Content-Version
295 * 1* sal_uInt16 Content-Tag
296 * SizeOfContent* sal_uInt8 Content
298 class SVL_DLLPUBLIC SfxSingleRecordWriter: public SfxMiniRecordWriter
300 protected:
301 SfxSingleRecordWriter( sal_uInt8 nRecordType,
302 SvStream *pStream,
303 sal_uInt16 nTag, sal_uInt8 nCurVer );
305 public:
306 inline void Reset();
308 sal_uInt32 Close( bool bSeekToEndOfRec = true );
313 * With instances of this class simple records can be read from a stream,
314 * that were written with class <SfxSingleRecordWriter>.
316 * It is also possible to skip the record without knowing the internal format.
318 class SVL_DLLPUBLIC SfxSingleRecordReader: public SfxMiniRecordReader
320 protected:
321 sal_uInt16 _nRecordTag; // type of the complete contents
322 sal_uInt8 _nRecordVer; // version of the complete contents
323 sal_uInt8 _nRecordType; // Record Type from the header
325 // Three phase constructor for derived classes
326 SfxSingleRecordReader()
327 : _nRecordTag(0)
328 , _nRecordVer(0)
329 , _nRecordType(0)
332 void Construct_Impl( SvStream *pStream )
334 SfxMiniRecordReader::Construct_Impl(
335 pStream, SFX_REC_PRETAG_EXT );
337 bool FindHeader_Impl( sal_uInt16 nTypes, sal_uInt16 nTag );
338 bool ReadHeader_Impl( sal_uInt16 nTypes );
340 public:
342 inline sal_uInt16 GetTag() const;
344 inline sal_uInt8 GetVersion() const;
345 inline bool HasVersion( sal_uInt16 nVersion ) const;
350 * Instances of this class can be used to write a record to a stream,
351 * which stores its own length so that it can be skipped by
352 * older versions and readers that do not known the record type (tag).
354 * It contains multiple contents of the same type (tag) and the same
355 * version, which have been identified once and for all in the
356 * header of the record. All contents have a length which is
357 * known in advance and identical.
359 * To be able to guarantee forward and backwards compatibility,
360 * newer versions of the that must always completely contain
361 * the old version, so it is only allowed to append data!
362 * Obviously, only the data of the individual contents are meant,
363 * the number of contents is naturally variable, and should be
364 * treated as such by the reading application.
366 * @par File format
368 * 1* sal_uInt8 Pre-Tag (==0)
369 * 1* 3-sal_uInt8 OffsetToEndOfRec in bytes
370 * 1* sal_uInt8 Record-Type (==SFX_REC_TYPE_FIXSIZE)
371 * 1* sal_uInt8 Content-Version
372 * 1* sal_uInt16 Content-Tag
373 * 1* sal_uInt16 NumberOfContents
374 * 1* sal_uInt32 SizeOfEachContent
375 * NumberOfContents* (
376 * SizeOfEachContent sal_uInt8 Content
379 * @par Example
380 * @code
382 * SfxMultiFixRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION );
383 * for ( sal_uInt16 n = 0; n < Count(); ++n )
385 * aRecord.NewContent();
386 * *aRecord << aMember1[n];
387 * *aRecord << aMember2[n];
390 * @endcode
392 class SVL_DLLPUBLIC SfxMultiFixRecordWriter: public SfxSingleRecordWriter
394 protected:
395 sal_uInt32 _nContentStartPos; /* start position of respective
396 content - only with DBG_UTIL
397 and for subclasses */
398 sal_uInt32 _nContentSize; // size of each content
399 sal_uInt16 _nContentCount; // number of contents
401 SfxMultiFixRecordWriter( sal_uInt8 nRecordType,
402 SvStream *pStream,
403 sal_uInt16 nTag,
404 sal_uInt8 nCurVer );
406 public:
407 inline ~SfxMultiFixRecordWriter();
409 inline void NewContent();
411 inline void Reset();
413 sal_uInt32 Close( bool bSeekToEndOfRec = true );
416 /** write record with multiple content items
418 * Write a record into a stream that stores its own size. This allows it to be
419 * skipped with old versions or readers if they do not know the record type (= tag).
421 * It contains multiple content items of the same tag and version, that are both
422 * stored in the header of the record. The size of each content will be calculated
423 * automatically and stored so that single content items can be skipped without
424 * having to read them.
426 * @par File Format
428 * 1* sal_uInt8 Pre-Tag (==0)
429 * 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
430 * 1* sal_uInt8 Record-Type (==SFX_FILETYPE_TYPE_VARSIZE)
431 * 1* sal_uInt8 Content-Version
432 * 1* sal_uInt16 Content-Tag
433 * 1* sal_uInt16 NumberOfContents
434 * 1* sal_uInt32 OffsetToOfsTable
435 * NumberOfContents* (
436 * ContentSize* sal_uInt8 Content
438 * NumberOfContents* sal_uInt32 ContentOfs (shifted each <<8)
440 * @par Example
441 * @code
443 * SfxMultiVarRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION );
444 * for ( sal_uInt16 n = 0; n < Count(); ++n )
446 * aRecord.NewContent();
447 * *aRecord << aMember1[n];
448 * *aRecord << aMember2[n];
451 * @endcode
453 * @note To ensure up- and downwards compatibility, new versions need to include
454 * the data of the older ones and are only allowed to add data afterwards.
456 class SVL_DLLPUBLIC SfxMultiVarRecordWriter: public SfxMultiFixRecordWriter
458 protected:
459 std::vector<sal_uInt32> _aContentOfs;
460 sal_uInt16 _nContentVer; // only for SfxMultiMixRecordWriter
462 SfxMultiVarRecordWriter( sal_uInt8 nRecordType,
463 SvStream *pStream,
464 sal_uInt16 nRecordTag,
465 sal_uInt8 nRecordVer );
467 void FlushContent_Impl();
469 public:
470 SfxMultiVarRecordWriter( SvStream *pStream,
471 sal_uInt16 nRecordTag,
472 sal_uInt8 nRecordVer );
473 virtual ~SfxMultiVarRecordWriter();
475 void NewContent();
477 sal_uInt32 Close( bool bSeekToEndOfRec = true );
480 /** write record with multiple content items with identical size
482 * Write a record into a stream that stores its own size. This allows it to be
483 * skipped with old versions or readers if they do not know the record type (= tag).
485 * It contains multiple content items of the same tag and version, that are both
486 * stored in the header of the record. All content items have a known identical
487 * size.
489 * @par File Format
491 * 1* sal_uInt8 Pre-Tag (==0)
492 * 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
493 * 1* sal_uInt8 record type (==SFX_REC_TYPE_MIXTAGS)
494 * 1* sal_uInt8 content version
495 * 1* sal_uInt16 record tag
496 * 1* sal_uInt16 NumberOfContents
497 * 1* sal_uInt32 OffsetToOfsTable
498 * NumberOfContents* (
499 * 1* sal_uInt16 content tag
500 * ContentSize* sal_uInt8 content
502 * NumberOfContents* sal_uInt32 ( ContentOfs << 8 + Version )
504 * @note To ensure up- and downwards compatibility, new versions need to include
505 * the data of the older ones and are only allowed to add data afterwards.
507 class SVL_DLLPUBLIC SfxMultiMixRecordWriter: public SfxMultiVarRecordWriter
509 public:
510 inline SfxMultiMixRecordWriter( SvStream *pStream,
511 sal_uInt16 nRecordTag,
512 sal_uInt8 nRecordVer );
514 void NewContent( sal_uInt16 nTag, sal_uInt8 nVersion );
515 // private: not possible, since some compilers then make the previous also private
516 void NewContent()
517 { OSL_FAIL( "NewContent() only allowed with args" ); }
520 /** Read multiple content items of an existing record
522 * Instances of this class allow to read multiple content items of a record
523 * that was written with
524 * - SfxMultiFixRecordWriter
525 * - SfxMultiVarRecordWriter
526 * - SfxMultiMixRecordWriter
528 * It is possible to skip single content or the whole record without knowing
529 * its internal format.
531 * @par Example
532 * @code
534 * SfxMultiRecordReader aRecord( pStream );
535 * for ( sal_uInt16 nRecNo = 0; aRecord.GetContent(); ++nRecNo )
537 * switch ( aRecord.GetTag() )
539 * case MY_TAG_X:
540 * X *pObj = new X;
541 * *aRecord >> pObj.>aMember1;
542 * if ( aRecord.HasVersion(2) )
543 * *aRecord >> pObj->aMember2;
544 * Append( pObj );
545 * break;
547 * ...
551 * @endcode
553 class SVL_DLLPUBLIC SfxMultiRecordReader: public SfxSingleRecordReader
555 sal_uInt32 _nStartPos; // start position of this record
556 sal_uInt32* _pContentOfs; // offsets of the start positions
557 sal_uInt32 _nContentSize; // size of each record or table position
558 sal_uInt16 _nContentCount; // number of content items
559 sal_uInt16 _nContentNo; /* the index of the current content
560 contains the next content's index
561 for GetContent() */
562 sal_uInt16 _nContentTag; // tag of the current content
563 sal_uInt8 _nContentVer; // version of the current content
565 bool ReadHeader_Impl();
567 public:
568 SfxMultiRecordReader( SvStream *pStream, sal_uInt16 nTag );
569 ~SfxMultiRecordReader();
571 bool GetContent();
572 inline sal_uInt16 GetContentTag();
573 inline sal_uInt8 GetContentVersion() const;
574 inline bool HasContentVersion( sal_uInt16 nVersion ) const;
576 inline sal_uInt32 ContentCount() const;
579 /** create a mini record
581 * The content size is calculated automatically after streaming.
583 * @param pStream the stream that will contain the record
584 * @param nTag a record tag between 0x01 and 0xFE
586 inline SfxMiniRecordWriter::SfxMiniRecordWriter( SvStream* pStream, sal_uInt8 nTag )
587 : _pStream( pStream ),
588 _nStartPos( pStream->Tell() ),
589 _bHeaderOk(false),
590 _nPreTag( nTag )
592 DBG_ASSERT( _nPreTag != 0xFF, "invalid Tag" );
593 SAL_INFO("svl", "SfxFileRec: writing record to " << pStream->Tell());
595 pStream->SeekRel( + SFX_REC_HEADERSIZE_MINI );
598 /** The destructor closes the record automatically if not done earlier */
599 inline SfxMiniRecordWriter::~SfxMiniRecordWriter()
601 // the header was not written, yet, or needs to be checked
602 if ( !_bHeaderOk )
603 Close();
606 /** Get the record's stream
607 * @return The stream containing the record
608 * @note The record must not be already closed!
610 inline SvStream& SfxMiniRecordWriter::operator*() const
612 DBG_ASSERT( !_bHeaderOk, "getting Stream of closed record" );
613 return *_pStream;
616 inline void SfxMiniRecordWriter::Reset()
618 _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI );
619 _bHeaderOk = false;
622 /** The dtor moves the stream automatically to the position directly behind the record */
623 inline SfxMiniRecordReader::~SfxMiniRecordReader()
625 if ( !_bSkipped )
626 Skip();
629 /** position the stream directly behind the record's end */
630 inline void SfxMiniRecordReader::Skip()
632 _pStream->Seek(_nEofRec);
633 _bSkipped = true;
636 /** Get the pre-tag of this record
638 * The pre-tag might also be SFX_REC_PRETAG_EXT or SFX_REC_PRETAG_EOR.
639 * The latter means that in the stream the error code ERRCODE_IO_WRONGFORMAT
640 * is set. The former is valid, since extended records are just building on
641 * top of SfxMiniRecord.
643 * @return The pre-tag
645 inline sal_uInt8 SfxMiniRecordReader::GetTag() const
647 return _nPreTag;
650 /** This method allows to check if the record could be recreated successfully
651 * from the stream and, hence, was correct for this record type.
653 inline bool SfxMiniRecordReader::IsValid() const
655 return _nPreTag != SFX_REC_PRETAG_EOR;
658 /** get the owning stream
660 * This method returns the stream in which the record is contained.
661 * The current position of the stream must be inside the record.
663 inline SvStream& SfxMiniRecordReader::operator*() const
665 DBG_ASSERT( _pStream->Tell() < _nEofRec, "read behind record" );
666 return *_pStream;
669 /// @see SfxMiniRecordWriter::Close()
670 inline sal_uInt32 SfxSingleRecordWriter::Close( bool bSeekToEndOfRec )
672 sal_uInt32 nRet = 0;
674 // was the header already written?
675 if ( !_bHeaderOk )
677 // write base class header
678 sal_uInt32 nEndPos = SfxMiniRecordWriter::Close( bSeekToEndOfRec );
680 // seek the end of the own header if needed or stay behind the record
681 if ( !bSeekToEndOfRec )
682 _pStream->SeekRel( SFX_REC_HEADERSIZE_SINGLE );
683 nRet = nEndPos;
685 #ifdef DBG_UTIL
686 else
687 // check base class header
688 SfxMiniRecordWriter::Close( bSeekToEndOfRec );
689 #endif
691 return nRet;
694 inline void SfxSingleRecordWriter::Reset()
696 _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI +
697 SFX_REC_HEADERSIZE_SINGLE );
698 _bHeaderOk = false;
701 /** @returns the tag for the overall record (stored in the record's head) */
702 inline sal_uInt16 SfxSingleRecordReader::GetTag() const
704 return _nRecordTag;
707 /** @returns version of the record */
708 inline sal_uInt8 SfxSingleRecordReader::GetVersion() const
710 return _nRecordVer;
713 /** determine if the read record has at least the given version */
714 inline bool SfxSingleRecordReader::HasVersion( sal_uInt16 nVersion ) const
716 return _nRecordVer >= nVersion;
719 /** The destructor closes the record automatically if not done earlier */
720 inline SfxMultiFixRecordWriter::~SfxMultiFixRecordWriter()
722 // the header was not written, yet, or needs to be checked
723 if ( !_bHeaderOk )
724 Close();
727 /** add a new content into a record
729 * @note each, also the first record, must be initialized by this method
731 inline void SfxMultiFixRecordWriter::NewContent()
733 #ifdef DBG_UTIL
734 sal_uLong nOldStartPos;
735 // store starting position of the current content - CAUTION: sub classes!
736 nOldStartPos = _nContentStartPos;
737 #endif
738 _nContentStartPos = _pStream->Tell();
740 #ifdef DBG_UTIL
741 // is there a previous content?
742 if ( _nContentCount )
744 // check if the previous content stays in specified max. size
745 DBG_ASSERT( _nContentStartPos - nOldStartPos == _nContentSize,
746 "wrong content size detected" );
748 #endif
750 // count how many
751 ++_nContentCount;
755 * Creates a SfxMultiMixRecord in the given stream with a separate tags and
756 * versions of its content parts. The sizes of each part are calculated
757 * automatically.
759 * @param pStream target stream in which the record will be created
760 * @param nRecordTag tag for the total record
761 * @param nRecordVer version for the total record
763 inline SfxMultiMixRecordWriter::SfxMultiMixRecordWriter( SvStream* pStream,
764 sal_uInt16 nRecordTag,
765 sal_uInt8 nRecordVer )
766 : SfxMultiVarRecordWriter( SFX_REC_TYPE_MIXTAGS, pStream, nRecordTag, nRecordVer )
770 inline void SfxMultiFixRecordWriter::Reset()
772 _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI +
773 SFX_REC_HEADERSIZE_SINGLE +
774 SFX_REC_HEADERSIZE_MULTI );
775 _bHeaderOk = false;
778 /** @returns the tag of the last opened content
779 * @see SfxMultiRecordReder::GetContent()
781 inline sal_uInt16 SfxMultiRecordReader::GetContentTag()
783 return _nContentTag;
786 /** @returns the version of the last opened content
787 * @see SfxMultiRecordReder::GetContent()
789 inline sal_uInt8 SfxMultiRecordReader::GetContentVersion() const
791 return _nContentVer;
794 /** Determines if the given version is in the last opened content
796 * This method checks if the version is contained in the last version of the
797 * content that was opened with SfxMultiRecordReder::GetContent().
799 * @param nVersion The version to find
800 * @return true, if found
801 * @see SfxMultiRecordReder::GetContent()
803 inline bool SfxMultiRecordReader::HasContentVersion( sal_uInt16 nVersion ) const
805 return _nContentVer >= nVersion;
808 /** @returns number of this record's contents */
809 inline sal_uInt32 SfxMultiRecordReader::ContentCount() const
811 return _nContentCount;
814 #endif
816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */