bump product version to 4.1.6.2
[LibreOffice.git] / svl / source / filerec / filerec.cxx
blob1787bf86fcb7fe1ed60668760aa201dc4a822dc4
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 #include <svl/filerec.hxx>
21 #include <osl/endian.h>
23 //========================================================================
25 /* Die folgenden Makros extrahieren Teilbereiche aus einem sal_uInt32 Wert.
26 Diese sal_uInt32-Werte werden anstelle der einzelnen Werte gestreamt,
27 um Calls zu sparen.
30 #define SFX_REC_PRE(n) ( ((n) & 0x000000FF) )
31 #define SFX_REC_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 )
32 #define SFX_REC_TYP(n) ( ((n) & 0x000000FF) )
33 #define SFX_REC_VER(n) ( ((n) & 0x0000FF00) >> 8 )
34 #define SFX_REC_TAG(n) ( ((n) & 0xFFFF0000) >> 16 )
36 #define SFX_REC_CONTENT_VER(n) ( ((n) & 0x000000FF) )
37 #define SFX_REC_CONTENT_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 )
39 //-------------------------------------------------------------------------
41 /* Die folgenden Makros setzen Teilbereiche zu einem sal_uInt32 Wert zusammen.
42 Diese sal_uInt32-Werte werden anstelle der einzelnen Werte gestreamt,
43 um Calls zu sparen.
46 #define SFX_REC_MINI_HEADER(nPreTag,nStartPos,nEndPos) \
47 ( sal_uInt32(nPreTag) | \
48 sal_uInt32(nEndPos-nStartPos-SFX_REC_HEADERSIZE_MINI) << 8 )
50 #define SFX_REC_HEADER(nRecType,nContentTag,nContentVer) \
51 ( sal_uInt32(nRecType) | \
52 ( sal_uInt32(nContentVer) << 8 ) | \
53 ( sal_uInt32(nContentTag) << 16 ) )
55 #define SFX_REC_CONTENT_HEADER(nContentVer,n1StStartPos,nCurStartPos) \
56 ( sal_uInt32(nContentVer) | \
57 sal_uInt32( nCurStartPos - n1StStartPos ) << 8 )
59 //=========================================================================
61 sal_uInt32 SfxMiniRecordWriter::Close
63 bool bSeekToEndOfRec /* true (default)
64 Der Stream wird an das Ende des Records
65 positioniert.
67 false
68 Der Stream wird an den Anfang des
69 Contents (also hinter den Header)
70 positioniert.
74 /* [Beschreibung]
76 Diese Methode schlie\st den Record. Dabei wird haupts"achlich der
77 Header geschrieben.
79 Wurde der Header bereits geschrieben, hat der Aufruf keine Wirkung.
82 [R"uckgabewert]
84 sal_uInt32 != 0
85 Position im Stream, die direkt hinter dem Record liegt.
86 'bSeekToEndOfRecord==sal_True'
87 => R"uckgabewert == aktuelle Stream-Position nach Aufruf
89 == 0
90 Der Header war bereits geschrieben worden.
94 // wurde der Header noch nicht geschrieben?
95 if ( !_bHeaderOk )
97 // Header an den Anfang des Records schreiben
98 sal_uInt32 nEndPos = _pStream->Tell();
99 _pStream->Seek( _nStartPos );
100 *_pStream << SFX_REC_MINI_HEADER( _nPreTag, _nStartPos, nEndPos );
102 // je nachdem ans Ende des Records seeken oder hinter Header bleiben
103 if ( bSeekToEndOfRec )
104 _pStream->Seek( nEndPos );
106 // Header wurde JETZT geschrieben
107 _bHeaderOk = true;
108 return nEndPos;
111 // Record war bereits geschlossen
112 return 0;
115 bool SfxMiniRecordReader::SetHeader_Impl( sal_uInt32 nHeader )
117 /* [Beschreibung]
119 Interne Methode zum nachtr"aglichen Verarbeiten eines extern gelesenen
120 Headers. Falls der Header eine End-Of-Records-Kennung darstellt,
121 wird am Stream ein Errorcode gesetzt und sal_False zur"uckgeliefert. Im
122 Fehlerfall wird der Stream jedoch nicht auf den Record-Anfang zur"uck-
123 gesetzt.
127 bool bRet = true;
129 // Record-Ende und Pre-Tag aus dem Header ermitteln
130 _nEofRec = _pStream->Tell() + SFX_REC_OFS(nHeader);
131 _nPreTag = sal::static_int_cast< sal_uInt8 >(SFX_REC_PRE(nHeader));
133 // wenn End-Of-Record-Kennung, dann Fehler
134 if ( _nPreTag == SFX_REC_PRETAG_EOR )
136 _pStream->SetError( ERRCODE_IO_WRONGFORMAT );
137 bRet = true;
139 return bRet;
142 SfxMiniRecordReader::SfxMiniRecordReader
144 SvStream* pStream, /* <SvStream>, an dessen aktueller
145 Position sich ein <SfxMiniRecord>
146 befindet.
148 sal_uInt8 nTag // Pre-Tag des gew"unschten Records
151 /* [Beschreibung]
153 Dieser Ctor interpretiert 'pStream' ab der aktuellen Position als
154 eine l"uckenlose Folge von, von dieser Klassen-Gruppe interpretierbaren,
155 Records. Der in dieser Folge erste als <SfxMiniRecord> interpretierbare
156 (also ggf. auch ein extended-Record) mit dem PreTag 'nTag' wird ge"offnet
157 und durch diese Instanz repr"asentiert.
159 Wird das Ende des Streams oder die Kennung SFX_REC_PRETAG_EOR
160 erreicht, bevor ein Record mit dem ge"unschten Pre-Tag gefunden wird,
161 ist die erzeugte Instanz ung"ultig ('IsValid() == sal_False'). Ein ent-
162 sprechender Error-Code (ERRCODE_IO_EOF bzw. ERRCODE_IO_WRONGFORMAT)
163 ist dann am Stream gesetzt, dessen Position ist dann au\serdem unver-
164 "andert.
166 Bei 'nTag==SFX_FILEREC_PRETAG_EOR' wird nicht versucht, einen Record
167 zu lesen, es wird sofort 'IsValid()' auf sal_False gesetzt und kein Error-Code
168 am Stream gesetzt. Dies ist dauzu gedacht, ohne 'new' und 'delete'
169 abw"rtskompatibel SfxMiniRecords einbauen zu k"onnen. Siehe dazu
170 <SfxItemSet::Load()>.
173 [Anwendungsvorschlag]
175 Wird dieser Ctor in einer bereits ausgelieferten Programmversion
176 verwendet, k"onnen in das File-Format jeweils davor kompatibel neue
177 Records mit einer anderen Kennung eingef"ugt werden. Diese werden
178 schlie\slich automatisch "uberlesen. Erkauft wird diese M"oglichkeit
179 allerdings mit etwas schlechterem Laufzeitverhalten im Vergleich mit
180 direktem 'drauf-los-lesen', der sich jedoch auf einen Vergleich zweier
181 Bytes reduziert, falls der gesuchte Record der erste in der Folge ist.
184 : _pStream( pStream ),
185 _bSkipped( nTag == SFX_REC_PRETAG_EOR )
187 // ggf. ignorieren (s.o.)
188 if ( _bSkipped )
190 _nPreTag = nTag;
191 return;
194 // StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen
195 sal_uInt32 nStartPos = pStream->Tell();
197 // passenden Record suchen
198 while(true)
200 // Header lesen
201 DBG( DbgOutf( "SfxFileRec: searching record at %ul", pStream->Tell() ) );
202 sal_uInt32 nHeader;
203 *pStream >> nHeader;
205 // Headerdaten von Basisklasse extrahieren lassen
206 SetHeader_Impl( nHeader );
208 // ggf. Fehler behandeln
209 if ( pStream->IsEof() )
210 _nPreTag = SFX_REC_PRETAG_EOR;
211 else if ( _nPreTag == SFX_REC_PRETAG_EOR )
212 pStream->SetError( ERRCODE_IO_WRONGFORMAT );
213 else
215 // wenn gefunden, dann Schleife abbrechen
216 if ( _nPreTag == nTag )
217 break;
219 // sonst skippen und weitersuchen
220 pStream->Seek( _nEofRec );
221 continue;
224 // Fehler => zur"uck-seeken
225 pStream->Seek( nStartPos );
226 break;
230 //=========================================================================
232 SfxSingleRecordWriter::SfxSingleRecordWriter
234 sal_uInt8 nRecordType, // f"ur Subklassen
235 SvStream* pStream, // Stream, in dem der Record angelegt wird
236 sal_uInt16 nContentTag, // Inhalts-Art-Kennung
237 sal_uInt8 nContentVer // Inhalts-Versions-Kennung
240 /* [Beschreibung]
242 Interner Ctor f"ur Subklassen.
245 : SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT )
247 // Erweiterten Header hiner den des SfxMiniRec schreiben
248 *pStream << SFX_REC_HEADER(nRecordType, nContentTag, nContentVer);
251 //=========================================================================
253 inline bool SfxSingleRecordReader::ReadHeader_Impl( sal_uInt16 nTypes )
255 /* [Beschreibung]
257 Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem
258 die Basisklasse bereits initialisiert und deren Header gelesen ist.
259 Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch
260 nicht zur"uckge-seekt.
264 bool bRet;
266 // Basisklassen-Header einlesen
267 sal_uInt32 nHeader=0;
268 *_pStream >> nHeader;
269 if ( !SetHeader_Impl( nHeader ) )
270 bRet = false;
271 else
273 // eigenen Header einlesen
274 *_pStream >> nHeader;
275 _nRecordVer = sal::static_int_cast< sal_uInt8 >(SFX_REC_VER(nHeader));
276 _nRecordTag = sal::static_int_cast< sal_uInt16 >(SFX_REC_TAG(nHeader));
278 // falscher Record-Typ?
279 _nRecordType = sal::static_int_cast< sal_uInt8 >(SFX_REC_TYP(nHeader));
280 bRet = 0 != ( nTypes & _nRecordType);
282 return bRet;
285 //-------------------------------------------------------------------------
287 bool SfxSingleRecordReader::FindHeader_Impl
289 sal_uInt16 nTypes, // arithm. Veroderung erlaubter Record-Typen
290 sal_uInt16 nTag // zu findende Record-Art-Kennung
293 /* [Beschreibung]
295 Interne Methode zum lesen des Headers des ersten Record, der einem
296 der Typen in 'nTypes' entspricht und mit der Art-Kennung 'nTag'
297 gekennzeichnet ist.
299 Kann ein solcher Record nicht gefunden werden, wird am Stream ein
300 Errorcode gesetzt, zur"uck-geseekt und sal_False zur"uckgeliefert.
304 // StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen
305 sal_uInt32 nStartPos = _pStream->Tell();
307 // richtigen Record suchen
308 while ( !_pStream->IsEof() )
310 // Header lesen
311 sal_uInt32 nHeader;
312 DBG( DbgOutf( "SfxFileRec: searching record at %ul", _pStream->Tell() ) );
313 *_pStream >> nHeader;
314 if ( !SetHeader_Impl( nHeader ) )
315 // EOR => Such-Schleife abbreichen
316 break;
318 // Extended Record gefunden?
319 if ( _nPreTag == SFX_REC_PRETAG_EXT )
321 // Extended Header lesen
322 *_pStream >> nHeader;
323 _nRecordTag = sal::static_int_cast< sal_uInt16 >(SFX_REC_TAG(nHeader));
325 // richtigen Record gefunden?
326 if ( _nRecordTag == nTag )
328 // gefundener Record-Typ passend?
329 _nRecordType = sal::static_int_cast< sal_uInt8 >(
330 SFX_REC_TYP(nHeader));
331 if ( nTypes & _nRecordType )
332 // ==> gefunden
333 return sal_True;
335 // error => Such-Schleife abbrechen
336 break;
340 // sonst skippen
341 if ( !_pStream->IsEof() )
342 _pStream->Seek( _nEofRec );
345 // Fehler setzen und zur"uck-seeken
346 _pStream->SetError( ERRCODE_IO_WRONGFORMAT );
347 _pStream->Seek( nStartPos );
348 return sal_False;
351 //=========================================================================
353 SfxMultiFixRecordWriter::SfxMultiFixRecordWriter
355 sal_uInt8 nRecordType, // Subklassen Record-Kennung
356 SvStream* pStream, // Stream, in dem der Record angelegt wird
357 sal_uInt16 nContentTag, // Content-Art-Kennung
358 sal_uInt8 nContentVer // Content-Versions-Kennung
361 /* [Beschreibung]
363 Interne Methode f"ur Subklassen.
366 : SfxSingleRecordWriter( nRecordType, pStream, nContentTag, nContentVer ),
367 _nContentCount( 0 )
369 // Platz f"ur eigenen Header
370 pStream->SeekRel( + SFX_REC_HEADERSIZE_MULTI );
373 //------------------------------------------------------------------------
375 sal_uInt32 SfxMultiFixRecordWriter::Close( bool bSeekToEndOfRec )
377 // siehe <SfxMiniRecordWriter>
380 // Header noch nicht geschrieben?
381 if ( !_bHeaderOk )
383 // Position hinter Record merken, um sie restaurieren zu k"onnen
384 sal_uInt32 nEndPos = SfxSingleRecordWriter::Close( sal_False );
386 // gegen"uber SfxSingleRecord erweiterten Header schreiben
387 *_pStream << _nContentCount;
388 *_pStream << _nContentSize;
390 // je nachdem ans Ende des Records seeken oder hinter Header bleiben
391 if ( bSeekToEndOfRec )
392 _pStream->Seek(nEndPos);
393 return nEndPos;
396 // Record war bereits geschlossen
397 return 0;
400 //=========================================================================
402 SfxMultiVarRecordWriter::SfxMultiVarRecordWriter
404 sal_uInt8 nRecordType, // Record-Kennung der Subklasse
405 SvStream* pStream, // Stream, in dem der Record angelegt wird
406 sal_uInt16 nRecordTag, // Gesamt-Art-Kennung
407 sal_uInt8 nRecordVer // Gesamt-Versions-Kennung
410 /* [Beschreibung]
412 Interner Ctor f"ur Subklassen.
415 : SfxMultiFixRecordWriter( nRecordType, pStream, nRecordTag, nRecordVer ),
416 _nContentVer( 0 )
420 //-------------------------------------------------------------------------
422 SfxMultiVarRecordWriter::SfxMultiVarRecordWriter
424 SvStream* pStream, // Stream, in dem der Record angelegt wird
425 sal_uInt16 nRecordTag, // Gesamt-Art-Kennung
426 sal_uInt8 nRecordVer // Gesamt-Versions-Kennung
429 /* [Beschreibung]
431 Legt in 'pStream' einen 'SfxMultiVarRecord' an, dessen Content-Gr"o\sen
432 weder bekannt sind noch identisch sein m"ussen, sondern jeweils nach dem
433 Streamen jedes einzelnen Contents errechnet werden sollen.
436 [Anmerkung]
438 Diese Methode ist nicht inline, da f"ur die Initialisierung eines
439 <SvULongs>-Members zu viel Code generiert werden w"urde.
442 : SfxMultiFixRecordWriter( SFX_REC_TYPE_VARSIZE,
443 pStream, nRecordTag, nRecordVer ),
444 _nContentVer( 0 )
448 //-------------------------------------------------------------------------
450 SfxMultiVarRecordWriter::~SfxMultiVarRecordWriter()
452 /* [Beschreibung]
454 Der Dtor der Klasse <SfxMultiVarRecordWriter> schlie\st den Record
455 automatisch, falls <SfxMultiVarRecordWriter::Close()> nicht bereits
456 explizit gerufen wurde.
460 // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden
461 if ( !_bHeaderOk )
462 Close();
465 //-------------------------------------------------------------------------
467 void SfxMultiVarRecordWriter::FlushContent_Impl()
469 /* [Beschreibung]
471 Interne Methode zum Abschlie\sen eines einzelnen Contents.
475 // Versions-Kennung und Positions-Offset des aktuellen Contents merken;
476 // das Positions-Offset ist relativ zur Startposition des ersten Contents
477 assert(_aContentOfs.size() == static_cast<size_t>(_nContentCount)-1);
478 _aContentOfs.resize(_nContentCount-1);
479 _aContentOfs.push_back(
480 SFX_REC_CONTENT_HEADER(_nContentVer,_nStartPos,_nContentStartPos));
483 //-------------------------------------------------------------------------
485 void SfxMultiVarRecordWriter::NewContent()
487 // siehe <SfxMultiFixRecordWriter>
490 // schon ein Content geschrieben?
491 if ( _nContentCount )
492 FlushContent_Impl();
494 // neuen Content beginnen
495 _nContentStartPos = _pStream->Tell();
496 ++_nContentCount;
499 //-------------------------------------------------------------------------
501 sal_uInt32 SfxMultiVarRecordWriter::Close( bool bSeekToEndOfRec )
503 // siehe <SfxMiniRecordWriter>
506 // Header noch nicht geschrieben?
507 if ( !_bHeaderOk )
509 // ggf. letzten Content abschlie\sen
510 if ( _nContentCount )
511 FlushContent_Impl();
513 // Content-Offset-Tabelle schreiben
514 sal_uInt32 nContentOfsPos = _pStream->Tell();
515 //! darf man das so einr"ucken?
516 for ( sal_uInt16 n = 0; n < _nContentCount; ++n )
517 *_pStream << _aContentOfs[n];
519 // SfxMultiFixRecordWriter::Close() "uberspringen!
520 sal_uInt32 nEndPos = SfxSingleRecordWriter::Close( sal_False );
522 // eigenen Header schreiben
523 *_pStream << _nContentCount;
524 if ( SFX_REC_TYPE_VARSIZE_RELOC == _nPreTag ||
525 SFX_REC_TYPE_MIXTAGS_RELOC == _nPreTag )
526 *_pStream << static_cast<sal_uInt32>(nContentOfsPos - ( _pStream->Tell() + sizeof(sal_uInt32) ));
527 else
528 *_pStream << nContentOfsPos;
530 // ans Ende des Records seeken bzw. am Ende des Headers bleiben
531 if ( bSeekToEndOfRec )
532 _pStream->Seek(nEndPos);
533 return nEndPos;
536 // Record war bereits vorher geschlossen
537 return 0;
540 //=========================================================================
542 void SfxMultiMixRecordWriter::NewContent
544 sal_uInt16 nContentTag, // Kennung f"ur die Art des Contents
545 sal_uInt8 nContentVer // Kennung f"ur die Version des Contents
548 /* [Beschreibung]
550 Mit dieser Methode wird in den Record ein neuer Content eingef"ugt
551 und dessen Content-Tag sowie dessen Content-Version angegeben. Jeder,
552 auch der 1. Record mu\s durch Aufruf dieser Methode eingeleitet werden.
556 // ggf. vorherigen Record abschlie\sen
557 if ( _nContentCount )
558 FlushContent_Impl();
560 // Tag vor den Content schreiben, Version und Startposition merken
561 _nContentStartPos = _pStream->Tell();
562 ++_nContentCount;
563 *_pStream << nContentTag;
564 _nContentVer = nContentVer;
567 //=========================================================================
569 bool SfxMultiRecordReader::ReadHeader_Impl()
571 /* [Beschreibung]
573 Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem
574 die Basisklasse bereits initialisiert und deren Header gelesen ist.
575 Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch
576 nicht zur"uckge-seekt.
580 // eigenen Header lesen
581 *_pStream >> _nContentCount;
582 *_pStream >> _nContentSize; // Fix: jedes einzelnen, Var|Mix: Tabellen-Pos.
584 // mu\s noch eine Tabelle mit Content-Offsets geladen werden?
585 if ( _nRecordType != SFX_REC_TYPE_FIXSIZE )
587 // Tabelle aus dem Stream einlesen
588 sal_uInt32 nContentPos = _pStream->Tell();
589 if ( _nRecordType == SFX_REC_TYPE_VARSIZE_RELOC ||
590 _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC )
591 _pStream->SeekRel( + _nContentSize );
592 else
593 _pStream->Seek( _nContentSize );
594 _pContentOfs = new sal_uInt32[_nContentCount];
595 memset(_pContentOfs, 0, _nContentCount*sizeof(sal_uInt32));
596 //! darf man jetzt so einr"ucken
597 #if defined(OSL_LITENDIAN)
598 _pStream->Read( _pContentOfs, sizeof(sal_uInt32)*_nContentCount );
599 #else
600 for ( sal_uInt16 n = 0; n < _nContentCount; ++n )
601 *_pStream >> _pContentOfs[n];
602 #endif
603 _pStream->Seek( nContentPos );
606 // Header konnte gelesen werden, wenn am Stream kein Error gesetzt ist
607 return !_pStream->GetError();
610 //-------------------------------------------------------------------------
612 SfxMultiRecordReader::SfxMultiRecordReader( SvStream *pStream, sal_uInt16 nTag )
613 : _pContentOfs(0)
614 , _nContentSize(0)
615 , _nContentCount(0)
616 , _nContentNo(0)
618 // Position im Stream merken, um im Fehlerfall zur"uck-seeken zu k"onnen
619 _nStartPos = pStream->Tell();
621 // passenden Record suchen und Basisklasse initialisieren
622 SfxSingleRecordReader::Construct_Impl( pStream );
623 if ( SfxSingleRecordReader::FindHeader_Impl( SFX_REC_TYPE_FIXSIZE |
624 SFX_REC_TYPE_VARSIZE | SFX_REC_TYPE_VARSIZE_RELOC |
625 SFX_REC_TYPE_MIXTAGS | SFX_REC_TYPE_MIXTAGS_RELOC,
626 nTag ) )
628 // eigenen Header dazu-lesen
629 if ( !ReadHeader_Impl() )
630 // nicht lesbar => als ung"ultig markieren und zur"uck-seeken
631 SetInvalid_Impl( _nStartPos);
635 //-------------------------------------------------------------------------
637 SfxMultiRecordReader::~SfxMultiRecordReader()
639 delete[] _pContentOfs;
642 //-------------------------------------------------------------------------
644 bool SfxMultiRecordReader::GetContent()
646 /* [Beschreibung]
648 Positioniert den Stream an den Anfang des n"chsten bzw. beim 1. Aufruf
649 auf den Anfang des ersten Contents im Record und liest ggf. dessen
650 Header ein.
652 Liegt laut Record-Header kein Content mehr vor, wird sal_False zur"uck-
653 gegeben. Trotz einem sal_True-Returnwert kann am Stream ein Fehlercode
654 gesetzt sein, z.B. falls er unvorhergesehenerweise (kaputtes File)
655 zuende ist.
659 // noch ein Content vorhanden?
660 if ( _nContentNo < _nContentCount )
662 // den Stream an den Anfang des Contents positionieren
663 sal_uInt32 nOffset = _nRecordType == SFX_REC_TYPE_FIXSIZE
664 ? _nContentNo * _nContentSize
665 : SFX_REC_CONTENT_OFS(_pContentOfs[_nContentNo]);
666 sal_uInt32 nNewPos = _nStartPos + nOffset;
667 DBG_ASSERT( nNewPos >= _pStream->Tell(), "SfxMultiRecordReader::GetContent() - New position before current, to much data red!" );
669 // #99366#: correct stream pos in every case;
670 // the if clause was added by MT a long time ago,
671 // maybe to 'repair' other corrupt documents; but this
672 // gives errors when writing with 5.1 and reading with current
673 // versions, so we decided to remove the if clause (KA-05/17/2002)
674 // if ( nNewPos > _pStream->Tell() )
675 _pStream->Seek( nNewPos );
677 // ggf. Content-Header lesen
678 if ( _nRecordType == SFX_REC_TYPE_MIXTAGS ||
679 _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC )
681 _nContentVer = sal::static_int_cast< sal_uInt8 >(
682 SFX_REC_CONTENT_VER(_pContentOfs[_nContentNo]));
683 *_pStream >> _nContentTag;
686 // ContentNo weiterz"ahlen
687 ++_nContentNo;
688 return sal_True;
691 return sal_False;
695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */