1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 _SFXFILEREC_HXX
21 #define _SFXFILEREC_HXX
23 //=========================================================================
25 #include "svl/svldllapi.h"
26 #include <tools/debug.hxx>
27 #include <tools/stream.hxx>
30 //------------------------------------------------------------------------
32 #define SFX_REC_PRETAG_EXT sal_uInt8(0x00) // Pre-Tag f"ur Extended-Records
33 #define SFX_REC_PRETAG_EOR sal_uInt8(0xFF) // Pre-Tag f"ur End-Of-Records
35 #define SFX_REC_TYPE_NONE sal_uInt8(0x00) // unbekannter Record-Typ
36 #define SFX_REC_TYPE_FIRST sal_uInt8(0x01)
37 #define SFX_REC_TYPE_SINGLE sal_uInt8(0x01) // Single-Content-Record
38 #define SFX_REC_TYPE_FIXSIZE sal_uInt8(0x02) // Fix-Size-Multi-Content-Record
39 #define SFX_REC_TYPE_VARSIZE_RELOC sal_uInt8(0x03) // variable Rec-Size
40 #define SFX_REC_TYPE_VARSIZE sal_uInt8(0x04) // alt (nicht verschiebbar)
41 #define SFX_REC_TYPE_MIXTAGS_RELOC sal_uInt8(0x07) // Mixed Tag Content-Record
42 #define SFX_REC_TYPE_MIXTAGS sal_uInt8(0x08) // alt (nicht verschiebbar)
43 #define SFX_REC_TYPE_LAST sal_uInt8(0x08)
44 #define SFX_REC_TYPE_MINI 0x100 // Mini-Record
45 #define SFX_REC_TYPE_DRAWENG 0x400 // Drawing-Engine-Record
46 #define SFX_REC_TYPE_EOR 0xF00 // End-Of-Records
48 //------------------------------------------------------------------------
50 #define SFX_REC_HEADERSIZE_MINI 4 // Gr"o\se des Mini-Record-Headers
51 #define SFX_REC_HEADERSIZE_SINGLE 4 // zzgl. HEADERSIZE_MINI => 8
52 #define SFX_REC_HEADERSIZE_MULTI 6 // zzgl. HEADERSIZE_SINGLE => 14
54 //------------------------------------------------------------------------
64 //------------------------------------------------------------------------
68 Jeder Record beginnt mit einem Byte, dem sogenannten 'Pre-Tag'.
70 Ist dieses 'Pre-Tag' == 0x00, dann handelt es sich um einen Extended-
71 Record, dessen Typ durch ein weiteres Byte an Position 5 n�her
75 0x02: SfxMultiFixRecord
76 0x03+0x04: SfxMultiVarRecord
77 0x07+0x08: SfxMultiMixRecord
78 (Alle weiteren Record-Typ-Kennungen sind reserviert.)
80 I.d.R. werden File-Formate schon aus Performance-Gr"unden so aufgebaut,
81 da\s beim Lesen jeweils vorher schon feststeht, welcher Record-Typ
82 vorliegt. Diese Kennung dient daher hautps"achlich der "Uberpr"ufung
83 und File-Viewern, die das genaue File-Format (unterhalb der Records)
86 Der 'SfxMiniRecordReader' verf"ugt dazu auch "uber eine statische
87 Methode 'ScanRecordType()', mit der festgestellt werden kann, welcher
88 Record-Typ in dem "ubergebenen Stream zu finden ist.
90 Ein 'Pre-Tag' mit dem Wert 0xFF ist als Terminator reserviert.
91 Terminatoren werden verwendet, um das Suchen nach einem speziellen
92 Record zu terminieren, d.h. ist er bis dorthin nicht gefunden, wird
93 auch nicht weitergesucht.
95 Bei allen anderen Werten des 'Pre-Tags' (also von 0x01 bis 0xFE)
96 handelt es sich um einen zum SW3 kompatbilen Record, der hier
97 'SfxMiniRecord' genannt wird, er kann daher mit einem <SfxMiniRecordReader>
100 Beginnt ein Record mit 0x44 k"onnte es sich um einen Drawing-Engine-
101 Record handeln. Dies ist dann der Fall, wenn die folgenden drei Bytes
102 die Zeichenkette 'RMD' bzw. 'RVW' ergeben (zusammen mit 'D'==0x44
103 ergibt dies die K"urzel f"ur 'DRaw-MoDel' bzw. 'DRaw-VieW'). Records
104 dieser Art k"onnen von den hier dargestellten Klassen weder gelesen,
105 noch in irgendeiner Weise interpretiert werden. Einzig die Methode
106 'ScanRecordType()' kann sie erkennen - weitere Behandlung obliegt
107 jedoch der Anwendungsprogrammierung.
109 Diese drei Bytes an den Positionen 2 bis 4 enthalten normalerweise
110 die Gr"o\se des Records ohne Pre-Tag und Gr"o\sen-Bytes selbst,
111 also die Restgr"o\se nach diesem 4-Byte-Header.
113 Struktur des Mini-Records:
116 3 sal_uInt8 OffsetToEndOfRec
117 OffsetToEndOfRec* 1 sal_uInt8 Content
119 Bei den Extended-Reords folgt auf diesen 4-Byte-Header ein erweiterter
120 Header, der zun"achst den o.g. Record-Typ, dann eine Versions-Kennung
121 sowie ein Tag enth"alt, welches den Inhalt kennzeichnet.
123 Struktur des Extended-Records:
125 1 sal_uInt8 Pre-Tag (==0x00)
126 3 sal_uInt8 OffsetToEndOfRec
127 OffsetToEndOfRec* 1 sal_uInt8 Content
128 1 sal_uInt8 Record-Type
131 ContentSize* 1 sal_uInt8 Content
133 (ContentSize = OffsetToEndOfRec - 8)
137 Der Aufbau der Records wird wie folgt begr"undet:
139 Der SW-Record-Typ war zuerst vorhanden, mu\ste also 1:1 "ubernommen
140 werden. Zum Gl"uck wurden einige Record-Tags nicht verwendet, (Z.B.
142 => 1. Byte 0x00 kann als Kennung f"ur erweiterten Record verwendet werden
143 => 1. Byte 0xFF kann f"ur besondere Zwecke verwendet werden
145 Egal welcher Record-Typ vorliegt, sollte eine Erkennung des Typs, ein
146 Auslesen des Headers und ein "uberpspringen des Records m"oglich sein,
147 ohne zu"uck-seeken zu m"ussen und ohne "uberfl"ussige Daten lesen zu
149 => die Bytes 2-4 werden bei allen Records als Offset zum Ende des
150 Records interpretiert, so da\s die Gesamt-Recors-Size sich wie
151 folgt berechnet: sizeof(sal_uInt32) + OffsetToEndOfRec
153 Die Records sollten einfach zu parsen un einheitlich aufgebaut sein.
154 => Sie bauen aufeinander auf, so ist z.B. der SfxMiniRecord in jedem
157 Die Records sollten auch von denen der Drawing Enginge unterscheidbar
158 sein. Diese beginnen mit 'DRMD' und 'DRVW'.
159 => Mini-Records mit dem Pre-Tag 'D' d"urfen maximal 4MB gro\s sein,
160 um nicht in diesen Kennungs-Bereich zu reichen.
164 Es ist geplant das File-Format so zu erweitern, da\s das High-Nibble
165 des Record-Typs der erweiterten Records besondere Aufgaben "ubernehmen
166 soll. Zum Beispiel ist geplant, Record-Contents als 'nur aus Records
167 bestehend' zu kennzeichnen. Ein File-Viewer k"onnte sich dann automatisch
168 durch solche Strukturen 'hangeln', ohne Gefahr zu laufen, auf Daten
169 zu sto\sen, die sich zwar als Records interpretieren lassen, aber
170 tats"achlis als 'flache' Daten geschrieben wurden. Die m"ogliche
171 Erweiterung wird schon jetzt insofern vorbereitet, als da\s das
172 High-Nibble des Typs bei Vergleichen nicht ber"ucksichtigt wird.
175 //------------------------------------------------------------------------
177 class SVL_DLLPUBLIC SfxMiniRecordWriter
181 Mit Instanzen dieser Klasse kann ein einfacher Record in einen Stream
182 geschrieben werden, der sich durch ein sal_uInt8-Tag identifiziert, sowie
183 seine eigene L"ange speichert und somit auch von "alteren Versionen
184 bzw. Readern, die diesen Record-Type (Tag) nicht kennen, "ubersprungen
185 werden kann. Es wird keine Version-Nummer gespeichert.
187 Alternativ kann die Gr"o\se fest angegeben werden oder sie wird
188 automatisch aus der Differenz der Tell()-Angaben vor und nach dem
189 Streamen des Inhalts ermittelt.
191 Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen
192 neue Versionen die Daten der "alteren immer komplett enthalten,
193 es d"urfen allenfalls neue Daten hintenan geh"angt werden!
197 1* sal_uInt8 Content-Tag (!= 0)
198 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
199 SizeOfContent* sal_uInt8 Content
204 SfxMiniRecordWriter aRecord( pStream, MY_TAG_X );
205 *aRecord << aMember1;
206 *aRecord << aMember2;
212 SvStream
* _pStream
; // <SvStream>, in dem der Record liegt
213 sal_uInt32 _nStartPos
; // Start-Position des Gesamt-Records im Stream
214 bool _bHeaderOk
; /* TRUE, wenn der Header schon geschrieben ist; */
215 sal_uInt8 _nPreTag
; // in den Header zu schreibendes 'Pre-Tag'
218 inline SfxMiniRecordWriter( SvStream
*pStream
,
220 inline SfxMiniRecordWriter( SvStream
*pStream
, sal_uInt8 nTag
,
223 inline ~SfxMiniRecordWriter();
225 inline SvStream
& operator*() const;
229 sal_uInt32
Close( bool bSeekToEndOfRec
= true );
232 // not implementend, not allowed
233 SfxMiniRecordWriter( const SfxMiniRecordWriter
& );
234 SfxMiniRecordWriter
& operator=(const SfxMiniRecordWriter
&);
237 //------------------------------------------------------------------------
239 class SVL_DLLPUBLIC SfxMiniRecordReader
243 Mit Instanzen dieser Klasse kann ein einfacher Record aus einem Stream
244 gelesen werden, der mit der Klasse <SfxRecordWriter> geschrieben wurde.
246 Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes
252 SfxMiniRecordReader aRecord( pStream );
253 switch ( aRecord.GetTag() )
256 *aRecord >> aMember1;
257 *aRecord >> aMember2;
267 SvStream
* _pStream
; // <SvStream>, aus dem gelesen wird
268 sal_uInt32 _nEofRec
; // Position direkt hinter dem Record
269 bool _bSkipped
; // TRUE: der Record wurde explizit geskippt
270 sal_uInt8 _nPreTag
; // aus dem Header gelesenes Pre-Tag
272 // Drei-Phasen-Ctor f"ur Subklassen
273 SfxMiniRecordReader() {}
274 void Construct_Impl( SvStream
*pStream
, sal_uInt8 nTag
)
277 _bSkipped
= sal_False
;
280 inline bool SetHeader_Impl( sal_uInt32 nHeader
);
282 // als ung"ultig markieren und zur"uck-seeken
283 void SetInvalid_Impl( sal_uInt32 nRecordStartPos
)
285 _nPreTag
= SFX_REC_PRETAG_EOR
;
286 _pStream
->Seek( nRecordStartPos
);
290 SfxMiniRecordReader( SvStream
*pStream
, sal_uInt8 nTag
);
291 inline ~SfxMiniRecordReader();
293 inline sal_uInt8
GetTag() const;
294 inline bool IsValid() const;
296 inline SvStream
& operator*() const;
301 // not implementend, not allowed
302 SfxMiniRecordReader( const SfxMiniRecordReader
& );
303 SfxMiniRecordReader
& operator=(const SfxMiniRecordReader
&);
306 //------------------------------------------------------------------------
308 class SVL_DLLPUBLIC SfxSingleRecordWriter
: public SfxMiniRecordWriter
312 Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben
313 werden, dessen einziger Inhalt sich durch ein sal_uInt16-Tag und eine
314 sal_uInt8-Versions-Nummer identifiziert, sowie seine eigene L"ange speichert
315 und somit auch von "alteren Versionen bzw. Readern, die diesen
316 Record-Type (Tag) nicht kennen, "ubersprungen werden kann.
318 Alternativ kann die Gr"o\se fest angegeben werden oder sie wird
319 automatisch aus der Differenz der Tell()-Angaben vor und nach dem
320 Streamen des Inhalts ermittelt.
322 Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen
323 neue Versionen die Daten der "alteren immer komplett enthalten,
324 es d"urfen allenfalls neue Daten hintenan geh"angt werden!
328 1* sal_uInt8 Pre-Tag (!= 0)
329 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
330 1* sal_uInt8 Record-Type (==SFX_REC_TYPE_SINGLE)
331 1* sal_uInt8 Content-Version
332 1* sal_uInt16 Content-Tag
333 SizeOfContent* sal_uInt8 Content
338 SfxSingleRecordWriter( sal_uInt8 nRecordType
,
340 sal_uInt16 nTag
, sal_uInt8 nCurVer
);
345 sal_uInt32
Close( bool bSeekToEndOfRec
= true );
348 //------------------------------------------------------------------------
350 class SVL_DLLPUBLIC SfxSingleRecordReader
: public SfxMiniRecordReader
354 Mit Instanzen dieser Klasse kann ein einfacher Record aus einem Stream
355 gelesen werden, der mit der Klasse <SfxSingleRecordWriter> geschrieben
358 Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes
364 sal_uInt16 _nRecordTag
; // Art des Gesamt-Inhalts
365 sal_uInt8 _nRecordVer
; // Version des Gesamt-Inhalts
366 sal_uInt8 _nRecordType
; // Record Type aus dem Header
368 // Drei-Phasen-Ctor f"ur Subklassen
369 SfxSingleRecordReader() {}
370 void Construct_Impl( SvStream
*pStream
)
372 SfxMiniRecordReader::Construct_Impl(
373 pStream
, SFX_REC_PRETAG_EXT
);
375 bool FindHeader_Impl( sal_uInt16 nTypes
, sal_uInt16 nTag
);
376 bool ReadHeader_Impl( sal_uInt16 nTypes
);
380 inline sal_uInt16
GetTag() const;
382 inline sal_uInt8
GetVersion() const;
383 inline bool HasVersion( sal_uInt16 nVersion
) const;
386 //------------------------------------------------------------------------
388 class SVL_DLLPUBLIC SfxMultiFixRecordWriter
: public SfxSingleRecordWriter
392 Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben
393 werden, der seine eigene L"ange speichert und somit auch von "alteren
394 Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen,
395 "ubersprungen werden kann.
397 Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben
398 Version, die einmalig (stellvertretend f"ur alle) im Header des Records
399 identifiziert werden. Alle Inhalte haben eine vorher bekannte und
402 Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen
403 neue Versionen die Daten der "alteren immer komplett enthalten,
404 es d"urfen allenfalls neue Daten hinten angeh"angt werden! Hier sind
405 damit selbstverst"andlich nur die Daten der einzelnen Inhalte gemeint,
406 die Anzahl der Inhalte ist selbstverst"andlich variabel und sollte
407 von lesenden Applikationen auch so behandelt werden.
411 1* sal_uInt8 Pre-Tag (==0)
412 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
413 1* sal_uInt8 Record-Type (==SFX_REC_TYPE_FIXSIZE)
414 1* sal_uInt8 Content-Version
415 1* sal_uInt16 Content-Tag
416 1* sal_uInt16 NumberOfContents
417 1* sal_uInt32 SizeOfEachContent
419 SizeOfEachContent sal_uInt8 Content
425 SfxMultiFixRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION );
426 for ( sal_uInt16 n = 0; n < Count(); ++n )
428 aRecord.NewContent();
429 *aRecord << aMember1[n];
430 *aRecord << aMember2[n];
437 sal_uInt32 _nContentStartPos
; /* Startposition des jeweiligen
438 Contents - nur bei DBG_UTIL
439 und f"ur Subklassen */
440 sal_uInt32 _nContentSize
; // Gr"o\se jedes Contents
441 sal_uInt16 _nContentCount
; // jeweilige Anzahl der Contents
443 SfxMultiFixRecordWriter( sal_uInt8 nRecordType
,
449 inline ~SfxMultiFixRecordWriter();
451 inline void NewContent();
455 sal_uInt32
Close( bool bSeekToEndOfRec
= true );
458 //------------------------------------------------------------------------
460 class SVL_DLLPUBLIC SfxMultiVarRecordWriter
: public SfxMultiFixRecordWriter
464 Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben
465 werden, der seine eigene L"ange speichert und somit auch von "alteren
466 Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen,
467 "ubersprungen werden kann.
469 Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben
470 Version, die einmalig (stellvertretend f"ur alle) im Header des Records
471 identifiziert werden. Die L"ange f"ur jeden einzelnen Inhalt wird
472 automatisch berechnet und gespeichert, so da\s auch einzelne Inhalte
473 "ubersprungen werden k"onnen, ohne sie interpretieren zu m"ussen.
475 Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen
476 neue Versionen die Daten der "alteren immer komplett enthalten,
477 es d"urfen allenfalls neue Daten hinten angeh"angt werden!
481 1* sal_uInt8 Pre-Tag (==0)
482 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
483 1* sal_uInt8 Record-Type (==SFX_FILETYPE_TYPE_VARSIZE)
484 1* sal_uInt8 Content-Version
485 1* sal_uInt16 Content-Tag
486 1* sal_uInt16 NumberOfContents
487 1* sal_uInt32 OffsetToOfsTable
489 ContentSize* sal_uInt8 Content
491 NumberOfContents* sal_uInt32 ContentOfs (je per <<8 verschoben)
496 SfxMultiVarRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION );
497 for ( sal_uInt16 n = 0; n < Count(); ++n )
499 aRecord.NewContent();
500 *aRecord << aMember1[n];
501 *aRecord << aMember2[n];
508 std::vector
<sal_uInt32
> _aContentOfs
;
509 sal_uInt16 _nContentVer
; // nur f"ur SfxMultiMixRecordWriter
511 SfxMultiVarRecordWriter( sal_uInt8 nRecordType
,
513 sal_uInt16 nRecordTag
,
514 sal_uInt8 nRecordVer
);
516 void FlushContent_Impl();
519 SfxMultiVarRecordWriter( SvStream
*pStream
,
520 sal_uInt16 nRecordTag
,
521 sal_uInt8 nRecordVer
);
522 virtual ~SfxMultiVarRecordWriter();
526 virtual sal_uInt32
Close( bool bSeekToEndOfRec
= true );
529 //------------------------------------------------------------------------
531 class SVL_DLLPUBLIC SfxMultiMixRecordWriter
: public SfxMultiVarRecordWriter
535 Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben
536 werden, der seine eigene L"ange speichert und somit auch von "alteren
537 Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen,
538 "ubersprungen werden kann.
540 Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben
541 Version, die einmalig (stellvertretend f"ur alle) im Header des Records
542 identifiziert werden. Alle Inhalte haben eine vorher bekannte und
545 Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen
546 neue Versionen die Daten der "alteren immer komplett enthalten,
547 es d"urfen allenfalls neue Daten hinten angeh"angt werden!
551 1* sal_uInt8 Pre-Tag (==0)
552 1* 3-sal_uInt8 OffsetToEndOfRec in Bytes
553 1* sal_uInt8 Record-Type (==SFX_REC_TYPE_MIXTAGS)
554 1* sal_uInt8 Content-Version
555 1* sal_uInt16 Record-Tag
556 1* sal_uInt16 NumberOfContents
557 1* sal_uInt32 OffsetToOfsTable
559 1* sal_uInt16 Content-Tag
560 ContentSize* sal_uInt8 Content
562 NumberOfContents* sal_uInt32 ( ContentOfs << 8 + Version )
567 inline SfxMultiMixRecordWriter( SvStream
*pStream
,
568 sal_uInt16 nRecordTag
,
569 sal_uInt8 nRecordVer
);
571 void NewContent( sal_uInt16 nTag
, sal_uInt8 nVersion
);
573 // private: geht nicht, da einige Compiler dann auch vorherige privat machen
575 { OSL_FAIL( "NewContent() only allowed with args" ); }
578 //------------------------------------------------------------------------
580 class SVL_DLLPUBLIC SfxMultiRecordReader
: public SfxSingleRecordReader
584 Mit Instanzen dieser Klasse kann ein aus mehreren Contents bestehender
585 Record aus einem Stream gelesen werden, der mit einer der Klassen
586 <SfxMultiFixRecordWriter>, <SfxMultiVarRecordWriter> oder
587 <SfxMultiMixRecordWriter> geschrieben wurde.
589 Es ist auch m"oglich, den Record oder einzelne Contents zu "uberspringen,
590 ohne das jeweilis interne Format zu kennen.
595 SfxMultiRecordReader aRecord( pStream );
596 for ( sal_uInt16 nRecNo = 0; aRecord.GetContent(); ++nRecNo )
598 switch ( aRecord.GetTag() )
602 *aRecord >> pObj.>aMember1;
603 if ( aRecord.HasVersion(2) )
604 *aRecord >> pObj->aMember2;
615 sal_uInt32 _nStartPos
; // Start-Position des Records
616 sal_uInt32
* _pContentOfs
; // Offsets der Startpositionen
617 sal_uInt32 _nContentSize
; // Size jedes einzelnen / Tabellen-Pos
618 sal_uInt16 _nContentCount
; // Anzahl der Contents im Record
619 sal_uInt16 _nContentNo
; /* der Index des aktuellen Contents
620 enth"alt jeweils den Index des
621 Contents, der beim n"achsten
622 GetContent() geholt wird */
623 sal_uInt16 _nContentTag
; // Art-Kennung des aktuellen Contents
624 sal_uInt8 _nContentVer
; // Versions-Kennung des akt. Contents
626 bool ReadHeader_Impl();
629 SfxMultiRecordReader( SvStream
*pStream
, sal_uInt16 nTag
);
630 ~SfxMultiRecordReader();
633 inline sal_uInt16
GetContentTag();
634 inline sal_uInt8
GetContentVersion() const;
635 inline bool HasContentVersion( sal_uInt16 nVersion
) const;
637 inline sal_uInt32
ContentCount() const;
640 //=========================================================================
642 inline SfxMiniRecordWriter::SfxMiniRecordWriter
644 SvStream
* pStream
, // Stream, in dem der Record angelegt wird
645 sal_uInt8 nTag
// Record-Tag zwischen 0x01 und 0xFE
650 Legt in 'pStream' einen 'SfxMiniRecord' an, dessen Content-Gr"o\se
651 nicht bekannt ist, sondern nach dam Streamen des Contents errechnet
655 : _pStream( pStream
),
656 _nStartPos( pStream
->Tell() ),
660 DBG_ASSERT( _nPreTag
!= 0xFF, "invalid Tag" );
661 DBG( DbgOutf( "SfxFileRec: writing record to %ul", pStream
->Tell() ) );
663 pStream
->SeekRel( + SFX_REC_HEADERSIZE_MINI
);
666 //-------------------------------------------------------------------------
668 inline SfxMiniRecordWriter::SfxMiniRecordWriter
670 SvStream
* pStream
, // Stream, in dem der Record angelegt wird
671 sal_uInt8 nTag
, // Record-Tag zwischen 0x01 und 0xFE
672 sal_uInt32 nSize
// Gr"o\se der Daten in Bytes
677 Legt in 'pStream' einen 'SfxMiniRecord' an, dessen Content-Gr"o\se
678 von vornherein bekannt ist.
681 : _pStream( pStream
),
682 // _nTag( uninitialized ),
683 // _nStarPos( uninitialized ),
686 DBG_ASSERT( nTag
!= 0 && nTag
!= 0xFF, "invalid Tag" );
687 DBG(_nStartPos
= pStream
->Tell());
688 DBG( DbgOutf( "SfxFileRec: writing record to %ul", _nStartPos
) );
690 *pStream
<< ( ( nTag
<< 24 ) | nSize
);
693 //-------------------------------------------------------------------------
695 inline SfxMiniRecordWriter::~SfxMiniRecordWriter()
699 Der Dtor der Klasse <SfxMiniRecordWriter> schlie\st den Record
700 automatisch, falls <SfxMiniRecordWriter::Close()> nicht bereits
701 explizit gerufen wurde.
705 // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden
710 //-------------------------------------------------------------------------
712 inline SvStream
& SfxMiniRecordWriter::operator*() const
716 Dieser Operator liefert den Stream, in dem der Record liegt.
717 Der Record darf noch nicht geschlossen worden sein.
721 DBG_ASSERT( !_bHeaderOk
, "getting Stream of closed record" );
725 //-------------------------------------------------------------------------
727 inline void SfxMiniRecordWriter::Reset()
729 _pStream
->Seek( _nStartPos
+ SFX_REC_HEADERSIZE_MINI
);
733 //=========================================================================
735 inline SfxMiniRecordReader::~SfxMiniRecordReader()
739 Der Dtor der Klasse <SfxMiniRecordReader> positioniert den Stream
740 automatisch auf die Position direkt hinter dem Record, falls nicht
741 <SfxMiniRecordReader::Skip()> bereits explizit gerufen wurde.
745 // noch nicht explizit ans Ende gesprungen?
750 //-------------------------------------------------------------------------
752 inline void SfxMiniRecordReader::Skip()
756 Mit dieser Methode wird der Stream direkt hinter das Ende des Records
761 _pStream
->Seek(_nEofRec
);
762 _bSkipped
= sal_True
;
765 //-------------------------------------------------------------------------
767 inline sal_uInt8
SfxMiniRecordReader::GetTag() const
771 Liefert des aus dem Header gelesene Pre-Tag des Records. Dieses kann
772 auch SFX_REC_PRETAG_EXT oder SFX_REC_PRETAG_EOR sein, im
773 letzteren Fall ist am Stream der Fehlercode ERRCODE_IO_WRONGFORMAT
774 gesetzt. SFX_REC_PRETAG_EXT ist g"ultig, da diese extended-Records
775 nur eine Erweiterung des SfxMiniRecord darstellen.
782 //-------------------------------------------------------------------------
784 inline bool SfxMiniRecordReader::IsValid() const
788 Hiermit kann abgefragt werden, ob der Record erfolgreich aus dem
789 Stream konstruiert werden konnte, der Header also f"ur diesen Record-Typ
794 return _nPreTag
!= SFX_REC_PRETAG_EOR
;
797 //-------------------------------------------------------------------------
799 inline SvStream
& SfxMiniRecordReader::operator*() const
803 Dieser Operator liefert den Stream in dem der Record liegt.
804 Die aktuelle Position des Streams mu\s innerhalb des Records liegen.
808 DBG_ASSERT( _pStream
->Tell() < _nEofRec
, "read behind record" );
812 //=========================================================================
814 inline sal_uInt32
SfxSingleRecordWriter::Close( bool bSeekToEndOfRec
)
816 // siehe <SfxMiniRecordWriter::Close(bool)>
821 // wurde der Header noch nicht geschrieben?
824 // Basisklassen-Header schreiben
825 sal_uInt32 nEndPos
= SfxMiniRecordWriter::Close( bSeekToEndOfRec
);
827 // ggf. ans Ende des eigenen Headers seeken oder hinter Rec bleiben
828 if ( !bSeekToEndOfRec
)
829 _pStream
->SeekRel( SFX_REC_HEADERSIZE_SINGLE
);
834 // Basisklassen-Header pr"ufen
835 SfxMiniRecordWriter::Close( bSeekToEndOfRec
);
838 // Record war bereits geschlossen
843 //-------------------------------------------------------------------------
845 inline void SfxSingleRecordWriter::Reset()
847 _pStream
->Seek( _nStartPos
+ SFX_REC_HEADERSIZE_MINI
+
848 SFX_REC_HEADERSIZE_SINGLE
);
852 //=========================================================================
854 inline sal_uInt16
SfxSingleRecordReader::GetTag() const
858 Liefert des aus dem Header gelesene Tag f"ur den Gesamt-Record.
865 //-------------------------------------------------------------------------
867 inline sal_uInt8
SfxSingleRecordReader::GetVersion() const
871 Liefert die Version des aus dem Stream gelesenen Records.
878 //-------------------------------------------------------------------------
880 inline bool SfxSingleRecordReader::HasVersion( sal_uInt16 nVersion
) const
884 Stellt fest, ob der aus dem Stream gelese Record in der Version
885 'nVersion' oder h"oher vorliegt.
889 return _nRecordVer
>= nVersion
;
892 //=========================================================================
894 inline SfxMultiFixRecordWriter::~SfxMultiFixRecordWriter()
898 Der Dtor der Klasse <SfxMultiFixRecordWriter> schlie\st den Record
899 automatisch, falls <SfxMutiFixRecordWriter::Close()> nicht bereits
900 explizit gerufen wurde.
904 // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden
909 //-------------------------------------------------------------------------
911 inline void SfxMultiFixRecordWriter::NewContent()
915 Mit dieser Methode wird in den Record ein neuer Content eingef"ugt.
916 Jeder, auch der 1. Record mu\s durch Aufruf dieser Methode eingeleitet
922 sal_uLong nOldStartPos
;
923 // Startposition des aktuellen Contents merken - Achtung Subklassen!
924 nOldStartPos
= _nContentStartPos
;
926 _nContentStartPos
= _pStream
->Tell();
929 // ist ein vorhergehender Content vorhanden?
930 if ( _nContentCount
)
932 // pr"ufen, ob der vorhergehende die Soll-Gr"o\se eingehalten hat
933 DBG_ASSERT( _nContentStartPos
- nOldStartPos
== _nContentSize
,
934 "wrong content size detected" );
942 //=========================================================================
944 inline SfxMultiMixRecordWriter::SfxMultiMixRecordWriter
946 SvStream
* pStream
, // Stream, in dem der Record angelegt wird
947 sal_uInt16 nRecordTag
, // Gesamt-Record-Art-Kennung
948 sal_uInt8 nRecordVer
// Gesamt-Record-Versions-Kennung
953 Legt in 'pStream' einen 'SfxMultiMixRecord' an, f"ur dessen Contents
954 je eine separate Kennung f"ur Art (Tag) und Version gespeichert wird.
955 Die Gr"o\sen der einzelnen Contents werden automatisch ermittelt.
958 : SfxMultiVarRecordWriter( SFX_REC_TYPE_MIXTAGS
,
959 pStream
, nRecordTag
, nRecordVer
)
963 //=========================================================================
965 inline void SfxMultiFixRecordWriter::Reset()
967 _pStream
->Seek( _nStartPos
+ SFX_REC_HEADERSIZE_MINI
+
968 SFX_REC_HEADERSIZE_SINGLE
+
969 SFX_REC_HEADERSIZE_MULTI
);
973 //=========================================================================
975 inline sal_uInt16
SfxMultiRecordReader::GetContentTag()
979 Diese Methode liefert die Art-Kennung des zuletzt mit der Methode
980 <SfxMultiRecordReder::GetContent()> ge"offneten Contents.
987 //-------------------------------------------------------------------------
989 inline sal_uInt8
SfxMultiRecordReader::GetContentVersion() const
993 Diese Methode liefert die Version-Kennung des zuletzt mit der Methode
994 <SfxMultiRecordReder::GetContent()> ge"offneten Contents.
1001 //-------------------------------------------------------------------------
1003 inline bool SfxMultiRecordReader::HasContentVersion( sal_uInt16 nVersion
) const
1007 Diese Methode stellt fest, ob die Version 'nVersion' in der Version des
1008 zuletzt mit der Methode <SfxMultiRecordReder::GetContent()> ge"offneten
1009 Contents enthalten ist.
1013 return _nContentVer
>= nVersion
;
1016 //-------------------------------------------------------------------------
1018 inline sal_uInt32
SfxMultiRecordReader::ContentCount() const
1022 Diese Methode liefert die Anzahl im Record befindlichen Contents.
1026 return _nContentCount
;
1031 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */