xref: /aoo4110/main/svl/source/filerec/filerec.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_svl.hxx"
26*b1cdbd2cSJim Jagielski #include <svl/filerec.hxx>
27*b1cdbd2cSJim Jagielski #include <osl/endian.h>
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski //========================================================================
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski SV_IMPL_VARARR( SfxUINT32s, sal_uInt32 );
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski //========================================================================
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski /*	Die folgenden Makros extrahieren Teilbereiche aus einem sal_uInt32 Wert.
36*b1cdbd2cSJim Jagielski 	Diese sal_uInt32-Werte werden anstelle der einzelnen Werte gestreamt,
37*b1cdbd2cSJim Jagielski 	um Calls zu sparen.
38*b1cdbd2cSJim Jagielski */
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski #define SFX_REC_PRE(n) ( ((n) & 0x000000FF) )
41*b1cdbd2cSJim Jagielski #define SFX_REC_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 )
42*b1cdbd2cSJim Jagielski #define SFX_REC_TYP(n) ( ((n) & 0x000000FF) )
43*b1cdbd2cSJim Jagielski #define SFX_REC_VER(n) ( ((n) & 0x0000FF00) >> 8 )
44*b1cdbd2cSJim Jagielski #define SFX_REC_TAG(n) ( ((n) & 0xFFFF0000) >> 16 )
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski #define SFX_REC_CONTENT_VER(n) ( ((n) & 0x000000FF) )
47*b1cdbd2cSJim Jagielski #define SFX_REC_CONTENT_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 )
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
50*b1cdbd2cSJim Jagielski 
51*b1cdbd2cSJim Jagielski /*	Die folgenden Makros setzen Teilbereiche zu einem sal_uInt32 Wert zusammen.
52*b1cdbd2cSJim Jagielski 	Diese sal_uInt32-Werte werden anstelle der einzelnen Werte gestreamt,
53*b1cdbd2cSJim Jagielski 	um Calls zu sparen.
54*b1cdbd2cSJim Jagielski */
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski #define SFX_REC_MINI_HEADER(nPreTag,nStartPos,nEndPos) \
57*b1cdbd2cSJim Jagielski 					( sal_uInt32(nPreTag) | \
58*b1cdbd2cSJim Jagielski 					  sal_uInt32(nEndPos-nStartPos-SFX_REC_HEADERSIZE_MINI) << 8 )
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski #define SFX_REC_HEADER(nRecType,nContentTag,nContentVer) \
61*b1cdbd2cSJim Jagielski 					( sal_uInt32(nRecType) | \
62*b1cdbd2cSJim Jagielski 					  ( sal_uInt32(nContentVer) << 8 ) | \
63*b1cdbd2cSJim Jagielski 					  ( sal_uInt32(nContentTag) << 16 ) )
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski #define SFX_REC_CONTENT_HEADER(nContentVer,n1StStartPos,nCurStartPos) \
66*b1cdbd2cSJim Jagielski 					( sal_uInt32(nContentVer) | \
67*b1cdbd2cSJim Jagielski 					  sal_uInt32( nCurStartPos - n1StStartPos ) << 8 )
68*b1cdbd2cSJim Jagielski 
69*b1cdbd2cSJim Jagielski //=========================================================================
70*b1cdbd2cSJim Jagielski 
Close(FASTBOOL bSeekToEndOfRec)71*b1cdbd2cSJim Jagielski sal_uInt32 SfxMiniRecordWriter::Close
72*b1cdbd2cSJim Jagielski (
73*b1cdbd2cSJim Jagielski 	FASTBOOL	bSeekToEndOfRec 	/*	sal_True (default)
74*b1cdbd2cSJim Jagielski 										Der Stream wird an das Ende des Records
75*b1cdbd2cSJim Jagielski 										positioniert.
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski 										sal_False
78*b1cdbd2cSJim Jagielski 										Der Stream wird an den Anfang des
79*b1cdbd2cSJim Jagielski 										Contents (also hinter den Header)
80*b1cdbd2cSJim Jagielski 										positioniert.
81*b1cdbd2cSJim Jagielski 									*/
82*b1cdbd2cSJim Jagielski )
83*b1cdbd2cSJim Jagielski 
84*b1cdbd2cSJim Jagielski /*	[Beschreibung]
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 	Diese Methode schlie\st den Record. Dabei wird haupts"achlich der
87*b1cdbd2cSJim Jagielski 	Header geschrieben.
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski 	Wurde der Header bereits geschrieben, hat der Aufruf keine Wirkung.
90*b1cdbd2cSJim Jagielski 
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski 	[R"uckgabewert]
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski 	sal_uInt32		!= 0
95*b1cdbd2cSJim Jagielski 				Position im Stream, die direkt hinter dem Record liegt.
96*b1cdbd2cSJim Jagielski 				'bSeekToEndOfRecord==sal_True'
97*b1cdbd2cSJim Jagielski 				=> R"uckgabewert == aktuelle Stream-Position nach Aufruf
98*b1cdbd2cSJim Jagielski 
99*b1cdbd2cSJim Jagielski 				== 0
100*b1cdbd2cSJim Jagielski 				Der Header war bereits geschrieben worden.
101*b1cdbd2cSJim Jagielski */
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski {
104*b1cdbd2cSJim Jagielski 	// wurde der Header noch nicht geschrieben?
105*b1cdbd2cSJim Jagielski 	if ( !_bHeaderOk )
106*b1cdbd2cSJim Jagielski 	{
107*b1cdbd2cSJim Jagielski 		// Header an den Anfang des Records schreiben
108*b1cdbd2cSJim Jagielski 		sal_uInt32 nEndPos = _pStream->Tell();
109*b1cdbd2cSJim Jagielski 		_pStream->Seek( _nStartPos );
110*b1cdbd2cSJim Jagielski 		*_pStream << SFX_REC_MINI_HEADER( _nPreTag, _nStartPos, nEndPos );
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski 		// je nachdem ans Ende des Records seeken oder hinter Header bleiben
113*b1cdbd2cSJim Jagielski 		if ( bSeekToEndOfRec )
114*b1cdbd2cSJim Jagielski 			_pStream->Seek( nEndPos );
115*b1cdbd2cSJim Jagielski 
116*b1cdbd2cSJim Jagielski 		// Header wurde JETZT geschrieben
117*b1cdbd2cSJim Jagielski 		_bHeaderOk = sal_True;
118*b1cdbd2cSJim Jagielski 		return nEndPos;
119*b1cdbd2cSJim Jagielski 	}
120*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
121*b1cdbd2cSJim Jagielski 	// mu\s Fix-Size-Record gepr"uft werden?
122*b1cdbd2cSJim Jagielski 	else if ( SFX_BOOL_DONTCARE == _bHeaderOk )
123*b1cdbd2cSJim Jagielski 	{
124*b1cdbd2cSJim Jagielski 		// Header auslesen, um Soll-Gr"o\se zu bestimmen
125*b1cdbd2cSJim Jagielski 		sal_uInt32 nEndPos = _pStream->Tell();
126*b1cdbd2cSJim Jagielski 		_pStream->Seek( _nStartPos );
127*b1cdbd2cSJim Jagielski 		sal_uInt32 nHeader;
128*b1cdbd2cSJim Jagielski 		*_pStream >> nHeader;
129*b1cdbd2cSJim Jagielski 		_pStream->Seek( nEndPos );
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski 		// Soll-Gr"o\se mit Ist-Gr"o\se vergleichen
132*b1cdbd2cSJim Jagielski 		DBG_ASSERT( nEndPos - SFX_REC_OFS(nHeader) == _nStartPos + sizeof(sal_uInt32),
133*b1cdbd2cSJim Jagielski 					"fixed record size incorrect" );
134*b1cdbd2cSJim Jagielski 		DbgOutf( "SfxFileRec: written record until %ul", nEndPos );
135*b1cdbd2cSJim Jagielski 	}
136*b1cdbd2cSJim Jagielski #endif
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski 	// Record war bereits geschlossen
139*b1cdbd2cSJim Jagielski 	return 0;
140*b1cdbd2cSJim Jagielski }
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski //=========================================================================
143*b1cdbd2cSJim Jagielski 
ScanRecordType(SvStream * pStream)144*b1cdbd2cSJim Jagielski sal_uInt16 SfxMiniRecordReader::ScanRecordType
145*b1cdbd2cSJim Jagielski (
146*b1cdbd2cSJim Jagielski 	SvStream*	pStream 		/*	<SvStream> an dessen aktueller Position
147*b1cdbd2cSJim Jagielski 									ein Record liegt, dessen Typ erkannt werden
148*b1cdbd2cSJim Jagielski 									soll.
149*b1cdbd2cSJim Jagielski 								*/
150*b1cdbd2cSJim Jagielski )
151*b1cdbd2cSJim Jagielski 
152*b1cdbd2cSJim Jagielski /*	[Beschreibung]
153*b1cdbd2cSJim Jagielski 
154*b1cdbd2cSJim Jagielski 	Mit dieser statischen Methode kann ermittelt werden, ob sich an der
155*b1cdbd2cSJim Jagielski 	aktuellen Position in einem Stream ein Record befindet, und der Typ
156*b1cdbd2cSJim Jagielski 	des Records kann ermittelt werden.
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski 	Die Position im Stream ist nach dem Aufruf aufver"andert.
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski 	[Anmerkung]
162*b1cdbd2cSJim Jagielski 
163*b1cdbd2cSJim Jagielski 	Die Record-Typen k"onnen zwar (abgesehen vom Drawing-Enginge-Record)
164*b1cdbd2cSJim Jagielski 	untereinander eindeutig erkannt werden, es besteht jedoch die Gefahr
165*b1cdbd2cSJim Jagielski 	der Verwechslung von Records mit normalen Daten. File-Formate sollten
166*b1cdbd2cSJim Jagielski 	darauf R"ucksicht nehmen. Handelt es sich um keinen Record, wird
167*b1cdbd2cSJim Jagielski 	am wahrscheinlichsten SFX_REC_TYPE_MINI zur"uckgeliefert, da dieser
168*b1cdbd2cSJim Jagielski 	Typ sich aufgrund seines sparsam kurzen Headers durch die k"urzeste
169*b1cdbd2cSJim Jagielski 	Kennung auszeichnet.
170*b1cdbd2cSJim Jagielski 
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski 	[R"uckgabewert]
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski 	sal_uInt16							SFX_REC_TYPE_EOR
175*b1cdbd2cSJim Jagielski 									An der aktuellen Position des Streams
176*b1cdbd2cSJim Jagielski 									steht eine End-Of-Records-Kennung.
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_MINI
179*b1cdbd2cSJim Jagielski 									Es handelt sich um einen SW3 kompatiblen
180*b1cdbd2cSJim Jagielski 									Mini-Record, dessen einzige Kennung sein
181*b1cdbd2cSJim Jagielski 									'Mini-Tag' ist.
182*b1cdbd2cSJim Jagielski 
183*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_SINGLE
184*b1cdbd2cSJim Jagielski 									Es handelt sich um einen Extended-Record
185*b1cdbd2cSJim Jagielski 									mit einem einzigen Content, der durch eine
186*b1cdbd2cSJim Jagielski 									Version und ein Tag n"aher gekennzeichnet
187*b1cdbd2cSJim Jagielski 									ist.
188*b1cdbd2cSJim Jagielski 
189*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_FIXSIZE
190*b1cdbd2cSJim Jagielski 									Es handelt sich um einen Extended-Record
191*b1cdbd2cSJim Jagielski 									mit mehreren Contents gleicher Gr"o\se,
192*b1cdbd2cSJim Jagielski 									die gemeinsam durch eine einzige Version
193*b1cdbd2cSJim Jagielski 									und ein einziges gemeinsames Tag n"aher
194*b1cdbd2cSJim Jagielski 									gekennzeichnet sind.
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_VARSIZE
197*b1cdbd2cSJim Jagielski 									Es handelt sich um einen Extended-Record
198*b1cdbd2cSJim Jagielski 									mit mehreren Contents variabler Gr"o\se,
199*b1cdbd2cSJim Jagielski 									die gemeinsam durch eine einzige Version
200*b1cdbd2cSJim Jagielski 									und ein einziges gemeinsames Tag n"aher
201*b1cdbd2cSJim Jagielski 									gekennzeichnet sind.
202*b1cdbd2cSJim Jagielski 
203*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_MIXTAGS
204*b1cdbd2cSJim Jagielski 									Es handelt sich um einen Extended-Record
205*b1cdbd2cSJim Jagielski 									mit mehreren Contents variabler Gr"o\se,
206*b1cdbd2cSJim Jagielski 									die jeweils durch ein eignes Tag und
207*b1cdbd2cSJim Jagielski 									eine eigene Versions-Nummer n"aher
208*b1cdbd2cSJim Jagielski 									gekennzeichnet sind.
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski 									SFX_REC_TYPE_DRAWENG
211*b1cdbd2cSJim Jagielski 									Es handelt sich wahrscheinlich um einen
212*b1cdbd2cSJim Jagielski 									Drawing-Engine-Record. Dieser Record-Typ
213*b1cdbd2cSJim Jagielski 									kann von den Klassen dieser Gruppe nicht
214*b1cdbd2cSJim Jagielski 									interpretiert werden.
215*b1cdbd2cSJim Jagielski */
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski 	// die ersten 4 Bytes als Mini-Header lesen
219*b1cdbd2cSJim Jagielski 	sal_uInt32 nHeader;
220*b1cdbd2cSJim Jagielski 	*pStream >> nHeader;
221*b1cdbd2cSJim Jagielski 
222*b1cdbd2cSJim Jagielski 	// k"onnte es sich um einen extended-Record handeln?
223*b1cdbd2cSJim Jagielski 	sal_uInt16 nPreTag = sal::static_int_cast< sal_uInt16 >(SFX_REC_PRE(nHeader));
224*b1cdbd2cSJim Jagielski 	if ( SFX_REC_PRETAG_EXT == nPreTag )
225*b1cdbd2cSJim Jagielski 	{
226*b1cdbd2cSJim Jagielski 		// die n"achsten 4 Bytes als extended-Header lesen
227*b1cdbd2cSJim Jagielski 		*pStream >> nHeader;
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 		// Stream-Position restaurieren
230*b1cdbd2cSJim Jagielski 		pStream->SeekRel(-8);
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski 		// liegt eine g"ultige Record-Kennung vor?
233*b1cdbd2cSJim Jagielski 		sal_uInt16 nType = sal::static_int_cast< sal_uInt16 >(SFX_REC_TYP(nHeader));
234*b1cdbd2cSJim Jagielski 		if ( nType >= SFX_REC_TYPE_FIRST && nType <= SFX_REC_TYPE_LAST )
235*b1cdbd2cSJim Jagielski 			// entsprechenden extended-Record-Typ zur"uckliefern
236*b1cdbd2cSJim Jagielski 			return nType;
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski 		// sonst ist der Record-Typ unbekannt
239*b1cdbd2cSJim Jagielski 		return SFX_REC_TYPE_NONE;
240*b1cdbd2cSJim Jagielski 	}
241*b1cdbd2cSJim Jagielski 
242*b1cdbd2cSJim Jagielski 	// Stream-Position restaurieren
243*b1cdbd2cSJim Jagielski 	pStream->SeekRel(-4);
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski 	// liegt eine End-Of-Record-Kennung vor?
246*b1cdbd2cSJim Jagielski 	if ( SFX_REC_PRETAG_EOR == nPreTag )
247*b1cdbd2cSJim Jagielski 		return nPreTag;
248*b1cdbd2cSJim Jagielski 
249*b1cdbd2cSJim Jagielski 	// liegt ein Drawin-Engine-Record vor?
250*b1cdbd2cSJim Jagielski 	if ( nHeader == sal_uInt32(*"DRMD") || nHeader == sal_uInt32(*"DRVW") )
251*b1cdbd2cSJim Jagielski 		return SFX_REC_TYPE_DRAWENG;
252*b1cdbd2cSJim Jagielski 
253*b1cdbd2cSJim Jagielski 	// alle anderen sind grunds"atzlich g"ultige Mini-Records
254*b1cdbd2cSJim Jagielski 	return SFX_REC_TYPE_MINI;
255*b1cdbd2cSJim Jagielski }
256*b1cdbd2cSJim Jagielski 
257*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
258*b1cdbd2cSJim Jagielski 
SetHeader_Impl(sal_uInt32 nHeader)259*b1cdbd2cSJim Jagielski FASTBOOL SfxMiniRecordReader::SetHeader_Impl( sal_uInt32 nHeader )
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski /*	[Beschreibung]
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski 	Interne Methode zum nachtr"aglichen Verarbeiten eines extern gelesenen
264*b1cdbd2cSJim Jagielski 	Headers. Falls der Header eine End-Of-Records-Kennung darstellt,
265*b1cdbd2cSJim Jagielski 	wird am Stream ein Errorcode gesetzt und sal_False zur"uckgeliefert. Im
266*b1cdbd2cSJim Jagielski 	Fehlerfall wird der Stream jedoch nicht auf den Record-Anfang zur"uck-
267*b1cdbd2cSJim Jagielski 	gesetzt.
268*b1cdbd2cSJim Jagielski */
269*b1cdbd2cSJim Jagielski 
270*b1cdbd2cSJim Jagielski {
271*b1cdbd2cSJim Jagielski 	FASTBOOL bRet = sal_True;
272*b1cdbd2cSJim Jagielski 
273*b1cdbd2cSJim Jagielski 	// Record-Ende und Pre-Tag aus dem Header ermitteln
274*b1cdbd2cSJim Jagielski 	_nEofRec = _pStream->Tell() + SFX_REC_OFS(nHeader);
275*b1cdbd2cSJim Jagielski 	_nPreTag = sal::static_int_cast< sal_uInt8 >(SFX_REC_PRE(nHeader));
276*b1cdbd2cSJim Jagielski 
277*b1cdbd2cSJim Jagielski 	// wenn End-Of-Record-Kennung, dann Fehler
278*b1cdbd2cSJim Jagielski 	if ( _nPreTag == SFX_REC_PRETAG_EOR )
279*b1cdbd2cSJim Jagielski 	{
280*b1cdbd2cSJim Jagielski 		_pStream->SetError( ERRCODE_IO_WRONGFORMAT );
281*b1cdbd2cSJim Jagielski 		bRet = sal_False;
282*b1cdbd2cSJim Jagielski 	}
283*b1cdbd2cSJim Jagielski 	return bRet;
284*b1cdbd2cSJim Jagielski }
285*b1cdbd2cSJim Jagielski 
286*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
287*b1cdbd2cSJim Jagielski 
SfxMiniRecordReader(SvStream * pStream)288*b1cdbd2cSJim Jagielski SfxMiniRecordReader::SfxMiniRecordReader
289*b1cdbd2cSJim Jagielski (
290*b1cdbd2cSJim Jagielski 	SvStream*		pStream 		/*	<SvStream>, an dessen aktueller
291*b1cdbd2cSJim Jagielski 										Position sich ein <SfxMiniRecord>
292*b1cdbd2cSJim Jagielski 										befindet.
293*b1cdbd2cSJim Jagielski 									*/
294*b1cdbd2cSJim Jagielski )
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski /*	[Beschreibung]
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski 	Dieser Ctor liest den Header eines <SfxMiniRecord> ab der aktuellen
299*b1cdbd2cSJim Jagielski 	Position von 'pStream'. Da grunds"atzlich fast 4-Byte Kombination ein
300*b1cdbd2cSJim Jagielski 	g"ultiger SfxMiniRecord-Header ist, bleiben die einzig m"oglichen
301*b1cdbd2cSJim Jagielski 	Fehler der EOF-Status des Streams, und ein SFX_REC_PRETAG_EOR
302*b1cdbd2cSJim Jagielski 	als Pre-Tag. Ein entsprechender Error-Code (ERRCODE_IO_EOF bzw.
303*b1cdbd2cSJim Jagielski 	ERRCODE_IO_WRONGFORMAT) ist dann am Stream gesetzt, dessen Position
304*b1cdbd2cSJim Jagielski 	dann au\serdem unver"andert ist.
305*b1cdbd2cSJim Jagielski */
306*b1cdbd2cSJim Jagielski 
307*b1cdbd2cSJim Jagielski :	_pStream( pStream ),
308*b1cdbd2cSJim Jagielski 	_bSkipped( sal_False )
309*b1cdbd2cSJim Jagielski {
310*b1cdbd2cSJim Jagielski 	// Header einlesen
311*b1cdbd2cSJim Jagielski 	sal_uInt32 nStartPos = pStream->Tell(); // um im Fehlerfall zur"uck zu-seeken
312*b1cdbd2cSJim Jagielski 	DBG( DbgOutf( "SfxFileRec: reading record at %ul", nStartPos ) );
313*b1cdbd2cSJim Jagielski 	sal_uInt32 nHeader;
314*b1cdbd2cSJim Jagielski 	*pStream >> nHeader;
315*b1cdbd2cSJim Jagielski 
316*b1cdbd2cSJim Jagielski 	// Headerdaten extrahieren
317*b1cdbd2cSJim Jagielski 	SetHeader_Impl( nHeader );
318*b1cdbd2cSJim Jagielski 
319*b1cdbd2cSJim Jagielski 	// Fehlerbehandlung
320*b1cdbd2cSJim Jagielski 	if ( pStream->IsEof() )
321*b1cdbd2cSJim Jagielski 		_nPreTag = SFX_REC_PRETAG_EOR;
322*b1cdbd2cSJim Jagielski 	else if ( _nPreTag == SFX_REC_PRETAG_EOR )
323*b1cdbd2cSJim Jagielski 		pStream->SetError( ERRCODE_IO_WRONGFORMAT );
324*b1cdbd2cSJim Jagielski 	if ( !IsValid() )
325*b1cdbd2cSJim Jagielski 		pStream->Seek( nStartPos );
326*b1cdbd2cSJim Jagielski }
327*b1cdbd2cSJim Jagielski 
328*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
329*b1cdbd2cSJim Jagielski 
SfxMiniRecordReader(SvStream * pStream,sal_uInt8 nTag)330*b1cdbd2cSJim Jagielski SfxMiniRecordReader::SfxMiniRecordReader
331*b1cdbd2cSJim Jagielski (
332*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		/*	<SvStream>, an dessen aktueller
333*b1cdbd2cSJim Jagielski 										Position sich ein <SfxMiniRecord>
334*b1cdbd2cSJim Jagielski 										befindet.
335*b1cdbd2cSJim Jagielski 									*/
336*b1cdbd2cSJim Jagielski 	sal_uInt8			nTag			//	Pre-Tag des gew"unschten Records
337*b1cdbd2cSJim Jagielski )
338*b1cdbd2cSJim Jagielski 
339*b1cdbd2cSJim Jagielski /*	[Beschreibung]
340*b1cdbd2cSJim Jagielski 
341*b1cdbd2cSJim Jagielski 	Dieser Ctor interpretiert 'pStream' ab der aktuellen Position als
342*b1cdbd2cSJim Jagielski 	eine l"uckenlose Folge von, von dieser Klassen-Gruppe interpretierbaren,
343*b1cdbd2cSJim Jagielski 	Records. Der in dieser Folge erste als <SfxMiniRecord> interpretierbare
344*b1cdbd2cSJim Jagielski 	(also ggf. auch ein extended-Record) mit dem PreTag 'nTag' wird ge"offnet
345*b1cdbd2cSJim Jagielski 	und durch diese Instanz repr"asentiert.
346*b1cdbd2cSJim Jagielski 
347*b1cdbd2cSJim Jagielski 	Wird das Ende des Streams oder die Kennung SFX_REC_PRETAG_EOR
348*b1cdbd2cSJim Jagielski 	erreicht, bevor ein Record mit dem ge"unschten Pre-Tag gefunden wird,
349*b1cdbd2cSJim Jagielski 	ist die erzeugte Instanz ung"ultig ('IsValid() == sal_False'). Ein ent-
350*b1cdbd2cSJim Jagielski 	sprechender Error-Code (ERRCODE_IO_EOF bzw. ERRCODE_IO_WRONGFORMAT)
351*b1cdbd2cSJim Jagielski 	ist dann am Stream gesetzt, dessen Position ist dann au\serdem unver-
352*b1cdbd2cSJim Jagielski 	"andert.
353*b1cdbd2cSJim Jagielski 
354*b1cdbd2cSJim Jagielski 	Bei 'nTag==SFX_FILEREC_PRETAG_EOR' wird nicht versucht, einen Record
355*b1cdbd2cSJim Jagielski 	zu lesen, es wird sofort 'IsValid()' auf sal_False gesetzt und kein Error-Code
356*b1cdbd2cSJim Jagielski 	am Stream gesetzt. Dies ist dauzu gedacht, ohne 'new' und 'delete'
357*b1cdbd2cSJim Jagielski 	abw"rtskompatibel SfxMiniRecords einbauen zu k"onnen. Siehe dazu
358*b1cdbd2cSJim Jagielski 	<SfxItemSet::Load()>.
359*b1cdbd2cSJim Jagielski 
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski 	[Anwendungsvorschlag]
362*b1cdbd2cSJim Jagielski 
363*b1cdbd2cSJim Jagielski 	Wird dieser Ctor in einer bereits ausgelieferten Programmversion
364*b1cdbd2cSJim Jagielski 	verwendet, k"onnen in das File-Format jeweils davor kompatibel neue
365*b1cdbd2cSJim Jagielski 	Records mit einer anderen Kennung eingef"ugt werden. Diese werden
366*b1cdbd2cSJim Jagielski 	schlie\slich automatisch "uberlesen. Erkauft wird diese M"oglichkeit
367*b1cdbd2cSJim Jagielski 	allerdings mit etwas schlechterem Laufzeitverhalten im Vergleich mit
368*b1cdbd2cSJim Jagielski 	direktem 'drauf-los-lesen', der sich jedoch auf einen Vergleich zweier
369*b1cdbd2cSJim Jagielski 	Bytes reduziert, falls der gesuchte Record der erste in der Folge ist.
370*b1cdbd2cSJim Jagielski */
371*b1cdbd2cSJim Jagielski 
372*b1cdbd2cSJim Jagielski :   _pStream( pStream ),
373*b1cdbd2cSJim Jagielski 	_bSkipped( nTag == SFX_REC_PRETAG_EOR )
374*b1cdbd2cSJim Jagielski {
375*b1cdbd2cSJim Jagielski 	// ggf. ignorieren (s.o.)
376*b1cdbd2cSJim Jagielski 	if ( _bSkipped )
377*b1cdbd2cSJim Jagielski 	{
378*b1cdbd2cSJim Jagielski 		_nPreTag = nTag;
379*b1cdbd2cSJim Jagielski 		return;
380*b1cdbd2cSJim Jagielski 	}
381*b1cdbd2cSJim Jagielski 
382*b1cdbd2cSJim Jagielski 	// StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen
383*b1cdbd2cSJim Jagielski 	sal_uInt32 nStartPos = pStream->Tell();
384*b1cdbd2cSJim Jagielski 
385*b1cdbd2cSJim Jagielski 	// passenden Record suchen
386*b1cdbd2cSJim Jagielski 	while(sal_True)
387*b1cdbd2cSJim Jagielski 	{
388*b1cdbd2cSJim Jagielski 		// Header lesen
389*b1cdbd2cSJim Jagielski 		DBG( DbgOutf( "SfxFileRec: searching record at %ul", pStream->Tell() ) );
390*b1cdbd2cSJim Jagielski 		sal_uInt32 nHeader;
391*b1cdbd2cSJim Jagielski 		*pStream >> nHeader;
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski 		// Headerdaten von Basisklasse extrahieren lassen
394*b1cdbd2cSJim Jagielski 		SetHeader_Impl( nHeader );
395*b1cdbd2cSJim Jagielski 
396*b1cdbd2cSJim Jagielski 		// ggf. Fehler behandeln
397*b1cdbd2cSJim Jagielski 		if ( pStream->IsEof() )
398*b1cdbd2cSJim Jagielski 			_nPreTag = SFX_REC_PRETAG_EOR;
399*b1cdbd2cSJim Jagielski 		else if ( _nPreTag == SFX_REC_PRETAG_EOR )
400*b1cdbd2cSJim Jagielski 			pStream->SetError( ERRCODE_IO_WRONGFORMAT );
401*b1cdbd2cSJim Jagielski 		else
402*b1cdbd2cSJim Jagielski 		{
403*b1cdbd2cSJim Jagielski 			// wenn gefunden, dann Schleife abbrechen
404*b1cdbd2cSJim Jagielski 			if ( _nPreTag == nTag )
405*b1cdbd2cSJim Jagielski 				break;
406*b1cdbd2cSJim Jagielski 
407*b1cdbd2cSJim Jagielski 			// sonst skippen und weitersuchen
408*b1cdbd2cSJim Jagielski 			pStream->Seek( _nEofRec );
409*b1cdbd2cSJim Jagielski 			continue;
410*b1cdbd2cSJim Jagielski 		}
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski 		// Fehler => zur"uck-seeken
413*b1cdbd2cSJim Jagielski 		pStream->Seek( nStartPos );
414*b1cdbd2cSJim Jagielski 		break;
415*b1cdbd2cSJim Jagielski 	}
416*b1cdbd2cSJim Jagielski }
417*b1cdbd2cSJim Jagielski 
418*b1cdbd2cSJim Jagielski //=========================================================================
419*b1cdbd2cSJim Jagielski 
SfxSingleRecordWriter(sal_uInt8 nRecordType,SvStream * pStream,sal_uInt16 nContentTag,sal_uInt8 nContentVer)420*b1cdbd2cSJim Jagielski SfxSingleRecordWriter::SfxSingleRecordWriter
421*b1cdbd2cSJim Jagielski (
422*b1cdbd2cSJim Jagielski 	sal_uInt8			nRecordType,	// f"ur Subklassen
423*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		// Stream, in dem der Record angelegt wird
424*b1cdbd2cSJim Jagielski 	sal_uInt16			nContentTag,	// Inhalts-Art-Kennung
425*b1cdbd2cSJim Jagielski 	sal_uInt8			nContentVer 	// Inhalts-Versions-Kennung
426*b1cdbd2cSJim Jagielski )
427*b1cdbd2cSJim Jagielski 
428*b1cdbd2cSJim Jagielski /*	[Beschreibung]
429*b1cdbd2cSJim Jagielski 
430*b1cdbd2cSJim Jagielski 	Interner Ctor f"ur Subklassen.
431*b1cdbd2cSJim Jagielski */
432*b1cdbd2cSJim Jagielski 
433*b1cdbd2cSJim Jagielski :	SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT )
434*b1cdbd2cSJim Jagielski {
435*b1cdbd2cSJim Jagielski 	// Erweiterten Header hiner den des SfxMiniRec schreiben
436*b1cdbd2cSJim Jagielski 	*pStream << SFX_REC_HEADER(nRecordType, nContentTag, nContentVer);
437*b1cdbd2cSJim Jagielski }
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
440*b1cdbd2cSJim Jagielski 
SfxSingleRecordWriter(SvStream * pStream,sal_uInt16 nContentTag,sal_uInt8 nContentVer)441*b1cdbd2cSJim Jagielski SfxSingleRecordWriter::SfxSingleRecordWriter
442*b1cdbd2cSJim Jagielski (
443*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		// Stream, in dem der Record angelegt wird
444*b1cdbd2cSJim Jagielski 	sal_uInt16			nContentTag,	// Inhalts-Art-Kennung
445*b1cdbd2cSJim Jagielski 	sal_uInt8			nContentVer 	// Inhalts-Versions-Kennung
446*b1cdbd2cSJim Jagielski )
447*b1cdbd2cSJim Jagielski 
448*b1cdbd2cSJim Jagielski /*	[Beschreibung]
449*b1cdbd2cSJim Jagielski 
450*b1cdbd2cSJim Jagielski 	Legt in 'pStream' einen 'SfxSingleRecord' an, dessen Content-Gr"o\se
451*b1cdbd2cSJim Jagielski 	nicht bekannt ist, sondern nach dam Streamen des Contents errechnet
452*b1cdbd2cSJim Jagielski 	werden soll.
453*b1cdbd2cSJim Jagielski */
454*b1cdbd2cSJim Jagielski 
455*b1cdbd2cSJim Jagielski :	SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT )
456*b1cdbd2cSJim Jagielski {
457*b1cdbd2cSJim Jagielski 	// Erweiterten Header hiner den des SfxMiniRec schreiben
458*b1cdbd2cSJim Jagielski 	*pStream << SFX_REC_HEADER( SFX_REC_TYPE_SINGLE, nContentTag, nContentVer);
459*b1cdbd2cSJim Jagielski }
460*b1cdbd2cSJim Jagielski 
461*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
462*b1cdbd2cSJim Jagielski 
SfxSingleRecordWriter(SvStream * pStream,sal_uInt16 nContentTag,sal_uInt8 nContentVer,sal_uInt32 nContentSize)463*b1cdbd2cSJim Jagielski SfxSingleRecordWriter::SfxSingleRecordWriter
464*b1cdbd2cSJim Jagielski (
465*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		// Stream, in dem der Record angelegt wird
466*b1cdbd2cSJim Jagielski 	sal_uInt16			nContentTag,	// Inhalts-Art-Kennung
467*b1cdbd2cSJim Jagielski 	sal_uInt8			nContentVer,	// Inhalts-Versions-Kennung
468*b1cdbd2cSJim Jagielski 	sal_uInt32			nContentSize	// Gr"o\se des Inhalts in Bytes
469*b1cdbd2cSJim Jagielski )
470*b1cdbd2cSJim Jagielski 
471*b1cdbd2cSJim Jagielski /*  [Beschreibung]
472*b1cdbd2cSJim Jagielski 
473*b1cdbd2cSJim Jagielski 	Legt in 'pStream' einen 'SfxSingleRecord' an, dessen Content-Gr"o\se
474*b1cdbd2cSJim Jagielski 	von vornherein bekannt ist.
475*b1cdbd2cSJim Jagielski */
476*b1cdbd2cSJim Jagielski 
477*b1cdbd2cSJim Jagielski :	SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT,
478*b1cdbd2cSJim Jagielski 						 nContentSize + SFX_REC_HEADERSIZE_SINGLE )
479*b1cdbd2cSJim Jagielski {
480*b1cdbd2cSJim Jagielski 	// Erweiterten Header hinter den des SfxMiniRec schreiben
481*b1cdbd2cSJim Jagielski 	*pStream << SFX_REC_HEADER( SFX_REC_TYPE_SINGLE, nContentTag, nContentVer);
482*b1cdbd2cSJim Jagielski }
483*b1cdbd2cSJim Jagielski 
484*b1cdbd2cSJim Jagielski //=========================================================================
485*b1cdbd2cSJim Jagielski 
ReadHeader_Impl(sal_uInt16 nTypes)486*b1cdbd2cSJim Jagielski inline FASTBOOL SfxSingleRecordReader::ReadHeader_Impl( sal_uInt16 nTypes )
487*b1cdbd2cSJim Jagielski 
488*b1cdbd2cSJim Jagielski /*  [Beschreibung]
489*b1cdbd2cSJim Jagielski 
490*b1cdbd2cSJim Jagielski 	Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem
491*b1cdbd2cSJim Jagielski 	die Basisklasse bereits initialisiert und deren Header gelesen ist.
492*b1cdbd2cSJim Jagielski 	Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch
493*b1cdbd2cSJim Jagielski 	nicht zur"uckge-seekt.
494*b1cdbd2cSJim Jagielski */
495*b1cdbd2cSJim Jagielski 
496*b1cdbd2cSJim Jagielski {
497*b1cdbd2cSJim Jagielski 	FASTBOOL bRet;
498*b1cdbd2cSJim Jagielski 
499*b1cdbd2cSJim Jagielski 	// Basisklassen-Header einlesen
500*b1cdbd2cSJim Jagielski 	sal_uInt32 nHeader=0;
501*b1cdbd2cSJim Jagielski 	*_pStream >> nHeader;
502*b1cdbd2cSJim Jagielski 	if ( !SetHeader_Impl( nHeader ) )
503*b1cdbd2cSJim Jagielski 		bRet = sal_False;
504*b1cdbd2cSJim Jagielski 	else
505*b1cdbd2cSJim Jagielski 	{
506*b1cdbd2cSJim Jagielski 		// eigenen Header einlesen
507*b1cdbd2cSJim Jagielski 		*_pStream >> nHeader;
508*b1cdbd2cSJim Jagielski 		_nRecordVer = sal::static_int_cast< sal_uInt8 >(SFX_REC_VER(nHeader));
509*b1cdbd2cSJim Jagielski 		_nRecordTag = sal::static_int_cast< sal_uInt16 >(SFX_REC_TAG(nHeader));
510*b1cdbd2cSJim Jagielski 
511*b1cdbd2cSJim Jagielski 		// falscher Record-Typ?
512*b1cdbd2cSJim Jagielski 		_nRecordType = sal::static_int_cast< sal_uInt8 >(SFX_REC_TYP(nHeader));
513*b1cdbd2cSJim Jagielski 		bRet = 0 != ( nTypes & _nRecordType);
514*b1cdbd2cSJim Jagielski 	}
515*b1cdbd2cSJim Jagielski 	return bRet;
516*b1cdbd2cSJim Jagielski }
517*b1cdbd2cSJim Jagielski 
518*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
519*b1cdbd2cSJim Jagielski 
SfxSingleRecordReader(SvStream * pStream)520*b1cdbd2cSJim Jagielski SfxSingleRecordReader::SfxSingleRecordReader( SvStream *pStream )
521*b1cdbd2cSJim Jagielski :	SfxMiniRecordReader()
522*b1cdbd2cSJim Jagielski {
523*b1cdbd2cSJim Jagielski 	// Startposition merken, um im Fehlerfall zur"uck-seeken zu k"onnen
524*b1cdbd2cSJim Jagielski     #ifdef DBG_UTIL
525*b1cdbd2cSJim Jagielski 	sal_uInt32 nStartPos = pStream->Tell();
526*b1cdbd2cSJim Jagielski 	DBG( DbgOutf( "SfxFileRec: reading record at %ul", nStartPos ) );
527*b1cdbd2cSJim Jagielski     #endif
528*b1cdbd2cSJim Jagielski 
529*b1cdbd2cSJim Jagielski 	// Basisklasse initialisieren (nicht via Ctor, da der nur MiniRecs akzept.)
530*b1cdbd2cSJim Jagielski 	Construct_Impl( pStream );
531*b1cdbd2cSJim Jagielski 
532*b1cdbd2cSJim Jagielski 	// nur Header mit korrektem Record-Type akzeptieren
533*b1cdbd2cSJim Jagielski 	if ( !ReadHeader_Impl( SFX_REC_TYPE_SINGLE ) )
534*b1cdbd2cSJim Jagielski 	{
535*b1cdbd2cSJim Jagielski 		// Error-Code setzen und zur"uck-seeken
536*b1cdbd2cSJim Jagielski 		pStream->SeekRel( - SFX_REC_HEADERSIZE_SINGLE );
537*b1cdbd2cSJim Jagielski 		pStream->SetError( ERRCODE_IO_WRONGFORMAT );
538*b1cdbd2cSJim Jagielski 	}
539*b1cdbd2cSJim Jagielski }
540*b1cdbd2cSJim Jagielski 
541*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
542*b1cdbd2cSJim Jagielski 
SfxSingleRecordReader(SvStream * pStream,sal_uInt16 nTag)543*b1cdbd2cSJim Jagielski SfxSingleRecordReader::SfxSingleRecordReader( SvStream *pStream, sal_uInt16 nTag )
544*b1cdbd2cSJim Jagielski {
545*b1cdbd2cSJim Jagielski 	// StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen
546*b1cdbd2cSJim Jagielski 	sal_uInt32 nStartPos = pStream->Tell();
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski 	// richtigen Record suchen, ggf. Error-Code setzen und zur"uck-seeken
549*b1cdbd2cSJim Jagielski 	Construct_Impl( pStream );
550*b1cdbd2cSJim Jagielski 	if ( !FindHeader_Impl( SFX_REC_TYPE_SINGLE, nTag ) )
551*b1cdbd2cSJim Jagielski 	{
552*b1cdbd2cSJim Jagielski 		// Error-Code setzen und zur"uck-seeken
553*b1cdbd2cSJim Jagielski 		pStream->Seek( nStartPos );
554*b1cdbd2cSJim Jagielski 		pStream->SetError( ERRCODE_IO_WRONGFORMAT );
555*b1cdbd2cSJim Jagielski 	}
556*b1cdbd2cSJim Jagielski }
557*b1cdbd2cSJim Jagielski 
558*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
559*b1cdbd2cSJim Jagielski 
FindHeader_Impl(sal_uInt16 nTypes,sal_uInt16 nTag)560*b1cdbd2cSJim Jagielski FASTBOOL SfxSingleRecordReader::FindHeader_Impl
561*b1cdbd2cSJim Jagielski (
562*b1cdbd2cSJim Jagielski 	sal_uInt16		nTypes, 	// arithm. Veroderung erlaubter Record-Typen
563*b1cdbd2cSJim Jagielski 	sal_uInt16		nTag		// zu findende Record-Art-Kennung
564*b1cdbd2cSJim Jagielski )
565*b1cdbd2cSJim Jagielski 
566*b1cdbd2cSJim Jagielski /*	[Beschreibung]
567*b1cdbd2cSJim Jagielski 
568*b1cdbd2cSJim Jagielski 	Interne Methode zum lesen des Headers des ersten Record, der einem
569*b1cdbd2cSJim Jagielski 	der Typen in 'nTypes' entspricht und mit der Art-Kennung 'nTag'
570*b1cdbd2cSJim Jagielski 	gekennzeichnet ist.
571*b1cdbd2cSJim Jagielski 
572*b1cdbd2cSJim Jagielski 	Kann ein solcher Record nicht gefunden werden, wird am Stream ein
573*b1cdbd2cSJim Jagielski 	Errorcode gesetzt, zur"uck-geseekt und sal_False zur"uckgeliefert.
574*b1cdbd2cSJim Jagielski */
575*b1cdbd2cSJim Jagielski 
576*b1cdbd2cSJim Jagielski {
577*b1cdbd2cSJim Jagielski 	// StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen
578*b1cdbd2cSJim Jagielski 	sal_uInt32 nStartPos = _pStream->Tell();
579*b1cdbd2cSJim Jagielski 
580*b1cdbd2cSJim Jagielski 	// richtigen Record suchen
581*b1cdbd2cSJim Jagielski 	while ( !_pStream->IsEof() )
582*b1cdbd2cSJim Jagielski 	{
583*b1cdbd2cSJim Jagielski 		// Header lesen
584*b1cdbd2cSJim Jagielski 		sal_uInt32 nHeader;
585*b1cdbd2cSJim Jagielski 		DBG( DbgOutf( "SfxFileRec: searching record at %ul", _pStream->Tell() ) );
586*b1cdbd2cSJim Jagielski 		*_pStream >> nHeader;
587*b1cdbd2cSJim Jagielski 		if ( !SetHeader_Impl( nHeader ) )
588*b1cdbd2cSJim Jagielski 			// EOR => Such-Schleife abbreichen
589*b1cdbd2cSJim Jagielski 			break;
590*b1cdbd2cSJim Jagielski 
591*b1cdbd2cSJim Jagielski 		// Extended Record gefunden?
592*b1cdbd2cSJim Jagielski 		if ( _nPreTag == SFX_REC_PRETAG_EXT )
593*b1cdbd2cSJim Jagielski 		{
594*b1cdbd2cSJim Jagielski 			// Extended Header lesen
595*b1cdbd2cSJim Jagielski 			*_pStream >> nHeader;
596*b1cdbd2cSJim Jagielski 			_nRecordTag = sal::static_int_cast< sal_uInt16 >(SFX_REC_TAG(nHeader));
597*b1cdbd2cSJim Jagielski 
598*b1cdbd2cSJim Jagielski 			// richtigen Record gefunden?
599*b1cdbd2cSJim Jagielski 			if ( _nRecordTag == nTag )
600*b1cdbd2cSJim Jagielski 			{
601*b1cdbd2cSJim Jagielski 				// gefundener Record-Typ passend?
602*b1cdbd2cSJim Jagielski 				_nRecordType = sal::static_int_cast< sal_uInt8 >(
603*b1cdbd2cSJim Jagielski                     SFX_REC_TYP(nHeader));
604*b1cdbd2cSJim Jagielski 				if ( nTypes & _nRecordType )
605*b1cdbd2cSJim Jagielski 					// ==> gefunden
606*b1cdbd2cSJim Jagielski 					return sal_True;
607*b1cdbd2cSJim Jagielski 
608*b1cdbd2cSJim Jagielski 				// error => Such-Schleife abbrechen
609*b1cdbd2cSJim Jagielski 				break;
610*b1cdbd2cSJim Jagielski 			}
611*b1cdbd2cSJim Jagielski 		}
612*b1cdbd2cSJim Jagielski 
613*b1cdbd2cSJim Jagielski 		// sonst skippen
614*b1cdbd2cSJim Jagielski 		if ( !_pStream->IsEof() )
615*b1cdbd2cSJim Jagielski 			_pStream->Seek( _nEofRec );
616*b1cdbd2cSJim Jagielski 	}
617*b1cdbd2cSJim Jagielski 
618*b1cdbd2cSJim Jagielski 	// Fehler setzen und zur"uck-seeken
619*b1cdbd2cSJim Jagielski 	_pStream->SetError( ERRCODE_IO_WRONGFORMAT );
620*b1cdbd2cSJim Jagielski 	_pStream->Seek( nStartPos );
621*b1cdbd2cSJim Jagielski 	return sal_False;
622*b1cdbd2cSJim Jagielski }
623*b1cdbd2cSJim Jagielski 
624*b1cdbd2cSJim Jagielski //=========================================================================
625*b1cdbd2cSJim Jagielski 
SfxMultiFixRecordWriter(sal_uInt8 nRecordType,SvStream * pStream,sal_uInt16 nContentTag,sal_uInt8 nContentVer,sal_uInt32)626*b1cdbd2cSJim Jagielski SfxMultiFixRecordWriter::SfxMultiFixRecordWriter
627*b1cdbd2cSJim Jagielski (
628*b1cdbd2cSJim Jagielski 	sal_uInt8			nRecordType,	// Subklassen Record-Kennung
629*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		// Stream, in dem der Record angelegt wird
630*b1cdbd2cSJim Jagielski 	sal_uInt16			nContentTag,	// Content-Art-Kennung
631*b1cdbd2cSJim Jagielski 	sal_uInt8			nContentVer,	// Content-Versions-Kennung
632*b1cdbd2cSJim Jagielski 	sal_uInt32			              	// Gr"o\se jedes einzelnen Contents in Bytes
633*b1cdbd2cSJim Jagielski )
634*b1cdbd2cSJim Jagielski 
635*b1cdbd2cSJim Jagielski /*  [Beschreibung]
636*b1cdbd2cSJim Jagielski 
637*b1cdbd2cSJim Jagielski 	Interne Methode f"ur Subklassen.
638*b1cdbd2cSJim Jagielski */
639*b1cdbd2cSJim Jagielski 
640*b1cdbd2cSJim Jagielski :   SfxSingleRecordWriter( nRecordType, pStream, nContentTag, nContentVer ),
641*b1cdbd2cSJim Jagielski 	_nContentCount( 0 )
642*b1cdbd2cSJim Jagielski {
643*b1cdbd2cSJim Jagielski 	// Platz f"ur eigenen Header
644*b1cdbd2cSJim Jagielski 	pStream->SeekRel( + SFX_REC_HEADERSIZE_MULTI );
645*b1cdbd2cSJim Jagielski }
646*b1cdbd2cSJim Jagielski 
647*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
648*b1cdbd2cSJim Jagielski 
SfxMultiFixRecordWriter(SvStream * pStream,sal_uInt16 nContentTag,sal_uInt8 nContentVer,sal_uInt32)649*b1cdbd2cSJim Jagielski SfxMultiFixRecordWriter::SfxMultiFixRecordWriter
650*b1cdbd2cSJim Jagielski (
651*b1cdbd2cSJim Jagielski 	SvStream*		pStream,		// Stream, in dem der Record angelegt wird
652*b1cdbd2cSJim Jagielski 	sal_uInt16			nContentTag,	// Content-Art-Kennung
653*b1cdbd2cSJim Jagielski 	sal_uInt8			nContentVer,	// Content-Versions-Kennung
654*b1cdbd2cSJim Jagielski 	sal_uInt32			             	// Gr"o\se jedes einzelnen Contents in Bytes
655*b1cdbd2cSJim Jagielski )
656*b1cdbd2cSJim Jagielski 
657*b1cdbd2cSJim Jagielski /*  [Beschreibung]
658*b1cdbd2cSJim Jagielski 
659*b1cdbd2cSJim Jagielski 	Legt in 'pStream' einen 'SfxMultiFixRecord' an, dessen Content-Gr"o\se
660*b1cdbd2cSJim Jagielski 	konstant und von vornherein bekannt ist.
661*b1cdbd2cSJim Jagielski */
662*b1cdbd2cSJim Jagielski 
663*b1cdbd2cSJim Jagielski :   SfxSingleRecordWriter( SFX_REC_TYPE_FIXSIZE,
664*b1cdbd2cSJim Jagielski 						   pStream, nContentTag, nContentVer ),
665*b1cdbd2cSJim Jagielski 	_nContentCount( 0 )
666*b1cdbd2cSJim Jagielski {
667*b1cdbd2cSJim Jagielski 	// Platz f"ur eigenen Header
668*b1cdbd2cSJim Jagielski 	pStream->SeekRel( + SFX_REC_HEADERSIZE_MULTI );
669*b1cdbd2cSJim Jagielski }
670*b1cdbd2cSJim Jagielski 
671*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
672*b1cdbd2cSJim Jagielski 
Close(FASTBOOL bSeekToEndOfRec)673*b1cdbd2cSJim Jagielski sal_uInt32 SfxMultiFixRecordWriter::Close( FASTBOOL bSeekToEndOfRec )
674*b1cdbd2cSJim Jagielski 
675*b1cdbd2cSJim Jagielski //	siehe <SfxMiniRecordWriter>
676*b1cdbd2cSJim Jagielski 
677*b1cdbd2cSJim Jagielski {
678*b1cdbd2cSJim Jagielski 	// Header noch nicht geschrieben?
679*b1cdbd2cSJim Jagielski 	if ( !_bHeaderOk )
680*b1cdbd2cSJim Jagielski 	{
681*b1cdbd2cSJim Jagielski 		// Position hinter Record merken, um sie restaurieren zu k"onnen
682*b1cdbd2cSJim Jagielski 		sal_uInt32 nEndPos = SfxSingleRecordWriter::Close( sal_False );
683*b1cdbd2cSJim Jagielski 
684*b1cdbd2cSJim Jagielski 		// gegen"uber SfxSingleRecord erweiterten Header schreiben
685*b1cdbd2cSJim Jagielski 		*_pStream << _nContentCount;
686*b1cdbd2cSJim Jagielski 		*_pStream << _nContentSize;
687*b1cdbd2cSJim Jagielski 
688*b1cdbd2cSJim Jagielski 		// je nachdem ans Ende des Records seeken oder hinter Header bleiben
689*b1cdbd2cSJim Jagielski 		if ( bSeekToEndOfRec )
690*b1cdbd2cSJim Jagielski 			_pStream->Seek(nEndPos);
691*b1cdbd2cSJim Jagielski 		return nEndPos;
692*b1cdbd2cSJim Jagielski 	}
693*b1cdbd2cSJim Jagielski 
694*b1cdbd2cSJim Jagielski 	// Record war bereits geschlossen
695*b1cdbd2cSJim Jagielski 	return 0;
696*b1cdbd2cSJim Jagielski }
697*b1cdbd2cSJim Jagielski 
698*b1cdbd2cSJim Jagielski //=========================================================================
699*b1cdbd2cSJim Jagielski 
SfxMultiVarRecordWriter(sal_uInt8 nRecordType,SvStream * pStream,sal_uInt16 nRecordTag,sal_uInt8 nRecordVer)700*b1cdbd2cSJim Jagielski SfxMultiVarRecordWriter::SfxMultiVarRecordWriter
701*b1cdbd2cSJim Jagielski (
702*b1cdbd2cSJim Jagielski 	sal_uInt8			nRecordType,	// Record-Kennung der Subklasse
703*b1cdbd2cSJim Jagielski 	SvStream*       pStream,        // Stream, in dem der Record angelegt wird
704*b1cdbd2cSJim Jagielski 	sal_uInt16			nRecordTag, 	// Gesamt-Art-Kennung
705*b1cdbd2cSJim Jagielski 	sal_uInt8			nRecordVer		// Gesamt-Versions-Kennung
706*b1cdbd2cSJim Jagielski )
707*b1cdbd2cSJim Jagielski 
708*b1cdbd2cSJim Jagielski /*  [Beschreibung]
709*b1cdbd2cSJim Jagielski 
710*b1cdbd2cSJim Jagielski 	Interner Ctor f"ur Subklassen.
711*b1cdbd2cSJim Jagielski */
712*b1cdbd2cSJim Jagielski 
713*b1cdbd2cSJim Jagielski :   SfxMultiFixRecordWriter( nRecordType, pStream, nRecordTag, nRecordVer, 0 ),
714*b1cdbd2cSJim Jagielski 	_nContentVer( 0 )
715*b1cdbd2cSJim Jagielski {
716*b1cdbd2cSJim Jagielski }
717*b1cdbd2cSJim Jagielski 
718*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
719*b1cdbd2cSJim Jagielski 
SfxMultiVarRecordWriter(SvStream * pStream,sal_uInt16 nRecordTag,sal_uInt8 nRecordVer)720*b1cdbd2cSJim Jagielski SfxMultiVarRecordWriter::SfxMultiVarRecordWriter
721*b1cdbd2cSJim Jagielski (
722*b1cdbd2cSJim Jagielski 	SvStream*       pStream,        // Stream, in dem der Record angelegt wird
723*b1cdbd2cSJim Jagielski 	sal_uInt16			nRecordTag, 	// Gesamt-Art-Kennung
724*b1cdbd2cSJim Jagielski 	sal_uInt8			nRecordVer		// Gesamt-Versions-Kennung
725*b1cdbd2cSJim Jagielski )
726*b1cdbd2cSJim Jagielski 
727*b1cdbd2cSJim Jagielski /*  [Beschreibung]
728*b1cdbd2cSJim Jagielski 
729*b1cdbd2cSJim Jagielski 	Legt in 'pStream' einen 'SfxMultiVarRecord' an, dessen Content-Gr"o\sen
730*b1cdbd2cSJim Jagielski 	weder bekannt sind noch identisch sein m"ussen, sondern jeweils nach dem
731*b1cdbd2cSJim Jagielski 	Streamen jedes einzelnen Contents errechnet werden sollen.
732*b1cdbd2cSJim Jagielski 
733*b1cdbd2cSJim Jagielski 
734*b1cdbd2cSJim Jagielski 	[Anmerkung]
735*b1cdbd2cSJim Jagielski 
736*b1cdbd2cSJim Jagielski 	Diese Methode ist nicht inline, da f"ur die Initialisierung eines
737*b1cdbd2cSJim Jagielski 	<SvULongs>-Members zu viel Code generiert werden w"urde.
738*b1cdbd2cSJim Jagielski */
739*b1cdbd2cSJim Jagielski 
740*b1cdbd2cSJim Jagielski :   SfxMultiFixRecordWriter( SFX_REC_TYPE_VARSIZE,
741*b1cdbd2cSJim Jagielski 							 pStream, nRecordTag, nRecordVer, 0 ),
742*b1cdbd2cSJim Jagielski 	_nContentVer( 0 )
743*b1cdbd2cSJim Jagielski {
744*b1cdbd2cSJim Jagielski }
745*b1cdbd2cSJim Jagielski 
746*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
747*b1cdbd2cSJim Jagielski 
~SfxMultiVarRecordWriter()748*b1cdbd2cSJim Jagielski SfxMultiVarRecordWriter::~SfxMultiVarRecordWriter()
749*b1cdbd2cSJim Jagielski 
750*b1cdbd2cSJim Jagielski /*	[Beschreibung]
751*b1cdbd2cSJim Jagielski 
752*b1cdbd2cSJim Jagielski 	Der Dtor der Klasse <SfxMultiVarRecordWriter> schlie\st den Record
753*b1cdbd2cSJim Jagielski 	automatisch, falls <SfxMultiVarRecordWriter::Close()> nicht bereits
754*b1cdbd2cSJim Jagielski 	explizit gerufen wurde.
755*b1cdbd2cSJim Jagielski */
756*b1cdbd2cSJim Jagielski 
757*b1cdbd2cSJim Jagielski {
758*b1cdbd2cSJim Jagielski 	// wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden
759*b1cdbd2cSJim Jagielski 	if ( !_bHeaderOk )
760*b1cdbd2cSJim Jagielski 		Close();
761*b1cdbd2cSJim Jagielski }
762*b1cdbd2cSJim Jagielski 
763*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
764*b1cdbd2cSJim Jagielski 
FlushContent_Impl()765*b1cdbd2cSJim Jagielski void SfxMultiVarRecordWriter::FlushContent_Impl()
766*b1cdbd2cSJim Jagielski 
767*b1cdbd2cSJim Jagielski /*	[Beschreibung]
768*b1cdbd2cSJim Jagielski 
769*b1cdbd2cSJim Jagielski 	Interne Methode zum Abschlie\sen eines einzelnen Contents.
770*b1cdbd2cSJim Jagielski */
771*b1cdbd2cSJim Jagielski 
772*b1cdbd2cSJim Jagielski {
773*b1cdbd2cSJim Jagielski 	// Versions-Kennung und Positions-Offset des aktuellen Contents merken;
774*b1cdbd2cSJim Jagielski 	// das Positions-Offset ist relativ zur Startposition des ersten Contents
775*b1cdbd2cSJim Jagielski 	_aContentOfs.Insert(
776*b1cdbd2cSJim Jagielski 			SFX_REC_CONTENT_HEADER(_nContentVer,_nStartPos,_nContentStartPos),
777*b1cdbd2cSJim Jagielski 			_nContentCount-1 );
778*b1cdbd2cSJim Jagielski }
779*b1cdbd2cSJim Jagielski 
780*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
781*b1cdbd2cSJim Jagielski 
NewContent()782*b1cdbd2cSJim Jagielski void SfxMultiVarRecordWriter::NewContent()
783*b1cdbd2cSJim Jagielski 
784*b1cdbd2cSJim Jagielski // siehe <SfxMultiFixRecordWriter>
785*b1cdbd2cSJim Jagielski 
786*b1cdbd2cSJim Jagielski {
787*b1cdbd2cSJim Jagielski 	// schon ein Content geschrieben?
788*b1cdbd2cSJim Jagielski 	if ( _nContentCount )
789*b1cdbd2cSJim Jagielski 		FlushContent_Impl();
790*b1cdbd2cSJim Jagielski 
791*b1cdbd2cSJim Jagielski 	// neuen Content beginnen
792*b1cdbd2cSJim Jagielski 	_nContentStartPos = _pStream->Tell();
793*b1cdbd2cSJim Jagielski 	++_nContentCount;
794*b1cdbd2cSJim Jagielski }
795*b1cdbd2cSJim Jagielski 
796*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
797*b1cdbd2cSJim Jagielski 
Close(FASTBOOL bSeekToEndOfRec)798*b1cdbd2cSJim Jagielski sal_uInt32 SfxMultiVarRecordWriter::Close( FASTBOOL bSeekToEndOfRec )
799*b1cdbd2cSJim Jagielski 
800*b1cdbd2cSJim Jagielski // siehe <SfxMiniRecordWriter>
801*b1cdbd2cSJim Jagielski 
802*b1cdbd2cSJim Jagielski {
803*b1cdbd2cSJim Jagielski 	// Header noch nicht geschrieben?
804*b1cdbd2cSJim Jagielski 	if ( !_bHeaderOk )
805*b1cdbd2cSJim Jagielski 	{
806*b1cdbd2cSJim Jagielski 		// ggf. letzten Content abschlie\sen
807*b1cdbd2cSJim Jagielski 		if ( _nContentCount )
808*b1cdbd2cSJim Jagielski 			FlushContent_Impl();
809*b1cdbd2cSJim Jagielski 
810*b1cdbd2cSJim Jagielski 		// Content-Offset-Tabelle schreiben
811*b1cdbd2cSJim Jagielski 		sal_uInt32 nContentOfsPos = _pStream->Tell();
812*b1cdbd2cSJim Jagielski 		//! darf man das so einr"ucken?
813*b1cdbd2cSJim Jagielski 		#if defined(OSL_LITENDIAN)
814*b1cdbd2cSJim Jagielski 			_pStream->Write( _aContentOfs.GetData(),
815*b1cdbd2cSJim Jagielski 							 sizeof(sal_uInt32)*_nContentCount );
816*b1cdbd2cSJim Jagielski 		#else
817*b1cdbd2cSJim Jagielski 			for ( sal_uInt16 n = 0; n < _nContentCount; ++n )
818*b1cdbd2cSJim Jagielski 				*_pStream << sal_uInt32(_aContentOfs[n]);
819*b1cdbd2cSJim Jagielski 		#endif
820*b1cdbd2cSJim Jagielski 
821*b1cdbd2cSJim Jagielski 		// SfxMultiFixRecordWriter::Close() "uberspringen!
822*b1cdbd2cSJim Jagielski 		sal_uInt32 nEndPos = SfxSingleRecordWriter::Close( sal_False );
823*b1cdbd2cSJim Jagielski 
824*b1cdbd2cSJim Jagielski 		// eigenen Header schreiben
825*b1cdbd2cSJim Jagielski 		*_pStream << _nContentCount;
826*b1cdbd2cSJim Jagielski 		if ( SFX_REC_TYPE_VARSIZE_RELOC == _nPreTag ||
827*b1cdbd2cSJim Jagielski 			 SFX_REC_TYPE_MIXTAGS_RELOC == _nPreTag )
828*b1cdbd2cSJim Jagielski 			*_pStream << static_cast<sal_uInt32>(nContentOfsPos - ( _pStream->Tell() + sizeof(sal_uInt32) ));
829*b1cdbd2cSJim Jagielski 		else
830*b1cdbd2cSJim Jagielski 			*_pStream << nContentOfsPos;
831*b1cdbd2cSJim Jagielski 
832*b1cdbd2cSJim Jagielski 		// ans Ende des Records seeken bzw. am Ende des Headers bleiben
833*b1cdbd2cSJim Jagielski 		if ( bSeekToEndOfRec )
834*b1cdbd2cSJim Jagielski 			 _pStream->Seek(nEndPos);
835*b1cdbd2cSJim Jagielski 		return nEndPos;
836*b1cdbd2cSJim Jagielski 	}
837*b1cdbd2cSJim Jagielski 
838*b1cdbd2cSJim Jagielski 	// Record war bereits vorher geschlossen
839*b1cdbd2cSJim Jagielski 	return 0;
840*b1cdbd2cSJim Jagielski }
841*b1cdbd2cSJim Jagielski 
842*b1cdbd2cSJim Jagielski //=========================================================================
843*b1cdbd2cSJim Jagielski 
NewContent(sal_uInt16 nContentTag,sal_uInt8 nContentVer)844*b1cdbd2cSJim Jagielski void SfxMultiMixRecordWriter::NewContent
845*b1cdbd2cSJim Jagielski (
846*b1cdbd2cSJim Jagielski 	sal_uInt16		nContentTag,	// Kennung f"ur die Art des Contents
847*b1cdbd2cSJim Jagielski 	sal_uInt8		nContentVer 	// Kennung f"ur die Version des Contents
848*b1cdbd2cSJim Jagielski )
849*b1cdbd2cSJim Jagielski 
850*b1cdbd2cSJim Jagielski /*	[Beschreibung]
851*b1cdbd2cSJim Jagielski 
852*b1cdbd2cSJim Jagielski 	Mit dieser Methode wird in den Record ein neuer Content eingef"ugt
853*b1cdbd2cSJim Jagielski 	und dessen Content-Tag sowie dessen Content-Version angegeben. Jeder,
854*b1cdbd2cSJim Jagielski 	auch der 1. Record mu\s durch Aufruf dieser Methode eingeleitet werden.
855*b1cdbd2cSJim Jagielski */
856*b1cdbd2cSJim Jagielski 
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski 	// ggf. vorherigen Record abschlie\sen
859*b1cdbd2cSJim Jagielski 	if ( _nContentCount )
860*b1cdbd2cSJim Jagielski 		FlushContent_Impl();
861*b1cdbd2cSJim Jagielski 
862*b1cdbd2cSJim Jagielski 	// Tag vor den Content schreiben, Version und Startposition merken
863*b1cdbd2cSJim Jagielski 	_nContentStartPos = _pStream->Tell();
864*b1cdbd2cSJim Jagielski 	++_nContentCount;
865*b1cdbd2cSJim Jagielski 	*_pStream << nContentTag;
866*b1cdbd2cSJim Jagielski 	_nContentVer = nContentVer;
867*b1cdbd2cSJim Jagielski }
868*b1cdbd2cSJim Jagielski 
869*b1cdbd2cSJim Jagielski //=========================================================================
870*b1cdbd2cSJim Jagielski 
ReadHeader_Impl()871*b1cdbd2cSJim Jagielski FASTBOOL SfxMultiRecordReader::ReadHeader_Impl()
872*b1cdbd2cSJim Jagielski 
873*b1cdbd2cSJim Jagielski /*  [Beschreibung]
874*b1cdbd2cSJim Jagielski 
875*b1cdbd2cSJim Jagielski 	Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem
876*b1cdbd2cSJim Jagielski 	die Basisklasse bereits initialisiert und deren Header gelesen ist.
877*b1cdbd2cSJim Jagielski 	Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch
878*b1cdbd2cSJim Jagielski 	nicht zur"uckge-seekt.
879*b1cdbd2cSJim Jagielski */
880*b1cdbd2cSJim Jagielski 
881*b1cdbd2cSJim Jagielski {
882*b1cdbd2cSJim Jagielski 	// eigenen Header lesen
883*b1cdbd2cSJim Jagielski 	*_pStream >> _nContentCount;
884*b1cdbd2cSJim Jagielski 	*_pStream >> _nContentSize; // Fix: jedes einzelnen, Var|Mix: Tabellen-Pos.
885*b1cdbd2cSJim Jagielski 
886*b1cdbd2cSJim Jagielski 	// mu\s noch eine Tabelle mit Content-Offsets geladen werden?
887*b1cdbd2cSJim Jagielski 	if ( _nRecordType != SFX_REC_TYPE_FIXSIZE )
888*b1cdbd2cSJim Jagielski 	{
889*b1cdbd2cSJim Jagielski 		// Tabelle aus dem Stream einlesen
890*b1cdbd2cSJim Jagielski 		sal_uInt32 nContentPos = _pStream->Tell();
891*b1cdbd2cSJim Jagielski 		if ( _nRecordType == SFX_REC_TYPE_VARSIZE_RELOC ||
892*b1cdbd2cSJim Jagielski 			 _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC )
893*b1cdbd2cSJim Jagielski 			_pStream->SeekRel( + _nContentSize );
894*b1cdbd2cSJim Jagielski 		else
895*b1cdbd2cSJim Jagielski 			_pStream->Seek( _nContentSize );
896*b1cdbd2cSJim Jagielski 		_pContentOfs = new sal_uInt32[_nContentCount];
897*b1cdbd2cSJim Jagielski         memset(_pContentOfs, 0, _nContentCount*sizeof(sal_uInt32));
898*b1cdbd2cSJim Jagielski 	//! darf man jetzt so einr"ucken
899*b1cdbd2cSJim Jagielski 		#if defined(OSL_LITENDIAN)
900*b1cdbd2cSJim Jagielski 			_pStream->Read( _pContentOfs, sizeof(sal_uInt32)*_nContentCount );
901*b1cdbd2cSJim Jagielski 		#else
902*b1cdbd2cSJim Jagielski 			for ( sal_uInt16 n = 0; n < _nContentCount; ++n )
903*b1cdbd2cSJim Jagielski 				*_pStream >> _pContentOfs[n];
904*b1cdbd2cSJim Jagielski 		#endif
905*b1cdbd2cSJim Jagielski 		_pStream->Seek( nContentPos );
906*b1cdbd2cSJim Jagielski 	}
907*b1cdbd2cSJim Jagielski 
908*b1cdbd2cSJim Jagielski 	// Header konnte gelesen werden, wenn am Stream kein Error gesetzt ist
909*b1cdbd2cSJim Jagielski 	return !_pStream->GetError();
910*b1cdbd2cSJim Jagielski }
911*b1cdbd2cSJim Jagielski 
912*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
913*b1cdbd2cSJim Jagielski 
SfxMultiRecordReader(SvStream * pStream)914*b1cdbd2cSJim Jagielski SfxMultiRecordReader::SfxMultiRecordReader( SvStream *pStream )
915*b1cdbd2cSJim Jagielski     : _pContentOfs(0)
916*b1cdbd2cSJim Jagielski     , _nContentSize(0)
917*b1cdbd2cSJim Jagielski     , _nContentCount(0)
918*b1cdbd2cSJim Jagielski     , _nContentNo(0)
919*b1cdbd2cSJim Jagielski {
920*b1cdbd2cSJim Jagielski 	// Position im Stream merken, um im Fehlerfall zur"uck-seeken zu k"onnen
921*b1cdbd2cSJim Jagielski 	_nStartPos = pStream->Tell();
922*b1cdbd2cSJim Jagielski 
923*b1cdbd2cSJim Jagielski 	// Basisklasse konstruieren (normaler Ctor w"urde nur SingleRecs lesen)
924*b1cdbd2cSJim Jagielski 	SfxSingleRecordReader::Construct_Impl( pStream );
925*b1cdbd2cSJim Jagielski 
926*b1cdbd2cSJim Jagielski 	// Header der Basisklasse lesen
927*b1cdbd2cSJim Jagielski 	if ( !SfxSingleRecordReader::ReadHeader_Impl( SFX_REC_TYPE_FIXSIZE |
928*b1cdbd2cSJim Jagielski 				SFX_REC_TYPE_VARSIZE | SFX_REC_TYPE_VARSIZE_RELOC |
929*b1cdbd2cSJim Jagielski 				SFX_REC_TYPE_MIXTAGS | SFX_REC_TYPE_MIXTAGS_RELOC ) ||
930*b1cdbd2cSJim Jagielski 		 !ReadHeader_Impl() )
931*b1cdbd2cSJim Jagielski 		// als ung"ultig markieren und zur"uck-seeken
932*b1cdbd2cSJim Jagielski 		SetInvalid_Impl( _nStartPos );
933*b1cdbd2cSJim Jagielski }
934*b1cdbd2cSJim Jagielski 
935*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
936*b1cdbd2cSJim Jagielski 
SfxMultiRecordReader(SvStream * pStream,sal_uInt16 nTag)937*b1cdbd2cSJim Jagielski SfxMultiRecordReader::SfxMultiRecordReader( SvStream *pStream, sal_uInt16 nTag )
938*b1cdbd2cSJim Jagielski :	_nContentNo(0)
939*b1cdbd2cSJim Jagielski {
940*b1cdbd2cSJim Jagielski 	// Position im Stream merken, um im Fehlerfall zur"uck-seeken zu k"onnen
941*b1cdbd2cSJim Jagielski 	_nStartPos = pStream->Tell();
942*b1cdbd2cSJim Jagielski 
943*b1cdbd2cSJim Jagielski 	// passenden Record suchen und Basisklasse initialisieren
944*b1cdbd2cSJim Jagielski 	SfxSingleRecordReader::Construct_Impl( pStream );
945*b1cdbd2cSJim Jagielski 	if ( SfxSingleRecordReader::FindHeader_Impl( SFX_REC_TYPE_FIXSIZE |
946*b1cdbd2cSJim Jagielski 			SFX_REC_TYPE_VARSIZE | SFX_REC_TYPE_VARSIZE_RELOC |
947*b1cdbd2cSJim Jagielski 			SFX_REC_TYPE_MIXTAGS | SFX_REC_TYPE_MIXTAGS_RELOC,
948*b1cdbd2cSJim Jagielski 			nTag ) )
949*b1cdbd2cSJim Jagielski 	{
950*b1cdbd2cSJim Jagielski 		// eigenen Header dazu-lesen
951*b1cdbd2cSJim Jagielski 		if ( !ReadHeader_Impl() )
952*b1cdbd2cSJim Jagielski 			// nicht lesbar => als ung"ultig markieren und zur"uck-seeken
953*b1cdbd2cSJim Jagielski 			SetInvalid_Impl( _nStartPos);
954*b1cdbd2cSJim Jagielski 	}
955*b1cdbd2cSJim Jagielski }
956*b1cdbd2cSJim Jagielski 
957*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
958*b1cdbd2cSJim Jagielski 
~SfxMultiRecordReader()959*b1cdbd2cSJim Jagielski SfxMultiRecordReader::~SfxMultiRecordReader()
960*b1cdbd2cSJim Jagielski {
961*b1cdbd2cSJim Jagielski 	delete[] _pContentOfs;
962*b1cdbd2cSJim Jagielski }
963*b1cdbd2cSJim Jagielski 
964*b1cdbd2cSJim Jagielski //-------------------------------------------------------------------------
965*b1cdbd2cSJim Jagielski 
GetContent()966*b1cdbd2cSJim Jagielski FASTBOOL SfxMultiRecordReader::GetContent()
967*b1cdbd2cSJim Jagielski 
968*b1cdbd2cSJim Jagielski /*	[Beschreibung]
969*b1cdbd2cSJim Jagielski 
970*b1cdbd2cSJim Jagielski 	Positioniert den Stream an den Anfang des n"chsten bzw. beim 1. Aufruf
971*b1cdbd2cSJim Jagielski 	auf den Anfang des ersten Contents im Record und liest ggf. dessen
972*b1cdbd2cSJim Jagielski 	Header ein.
973*b1cdbd2cSJim Jagielski 
974*b1cdbd2cSJim Jagielski 	Liegt laut Record-Header kein Content mehr vor, wird sal_False zur"uck-
975*b1cdbd2cSJim Jagielski 	gegeben. Trotz einem sal_True-Returnwert kann am Stream ein Fehlercode
976*b1cdbd2cSJim Jagielski 	gesetzt sein, z.B. falls er unvorhergesehenerweise (kaputtes File)
977*b1cdbd2cSJim Jagielski 	zuende ist.
978*b1cdbd2cSJim Jagielski */
979*b1cdbd2cSJim Jagielski 
980*b1cdbd2cSJim Jagielski {
981*b1cdbd2cSJim Jagielski 	// noch ein Content vorhanden?
982*b1cdbd2cSJim Jagielski 	if ( _nContentNo < _nContentCount )
983*b1cdbd2cSJim Jagielski 	{
984*b1cdbd2cSJim Jagielski 		// den Stream an den Anfang des Contents positionieren
985*b1cdbd2cSJim Jagielski 		sal_uInt32 nOffset = _nRecordType == SFX_REC_TYPE_FIXSIZE
986*b1cdbd2cSJim Jagielski 					? _nContentNo * _nContentSize
987*b1cdbd2cSJim Jagielski 					: SFX_REC_CONTENT_OFS(_pContentOfs[_nContentNo]);
988*b1cdbd2cSJim Jagielski 		sal_uInt32 nNewPos = _nStartPos + nOffset;
989*b1cdbd2cSJim Jagielski 		DBG_ASSERT( nNewPos >= _pStream->Tell(), "SfxMultiRecordReader::GetContent() - New position before current, to much data red!" );
990*b1cdbd2cSJim Jagielski 
991*b1cdbd2cSJim Jagielski 		// #99366#: correct stream pos in every case;
992*b1cdbd2cSJim Jagielski         // the if clause was added by MT  a long time ago,
993*b1cdbd2cSJim Jagielski         // maybe to 'repair' other corrupt documents; but this
994*b1cdbd2cSJim Jagielski         // gives errors when writing with 5.1 and reading with current
995*b1cdbd2cSJim Jagielski         // versions, so we decided to remove the if clause (KA-05/17/2002)
996*b1cdbd2cSJim Jagielski         // if ( nNewPos > _pStream->Tell() )
997*b1cdbd2cSJim Jagielski 		_pStream->Seek( nNewPos );
998*b1cdbd2cSJim Jagielski 
999*b1cdbd2cSJim Jagielski 		// ggf. Content-Header lesen
1000*b1cdbd2cSJim Jagielski 		if ( _nRecordType == SFX_REC_TYPE_MIXTAGS ||
1001*b1cdbd2cSJim Jagielski 			 _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC )
1002*b1cdbd2cSJim Jagielski 		{
1003*b1cdbd2cSJim Jagielski 			_nContentVer = sal::static_int_cast< sal_uInt8 >(
1004*b1cdbd2cSJim Jagielski                 SFX_REC_CONTENT_VER(_pContentOfs[_nContentNo]));
1005*b1cdbd2cSJim Jagielski 			*_pStream >> _nContentTag;
1006*b1cdbd2cSJim Jagielski 		}
1007*b1cdbd2cSJim Jagielski 
1008*b1cdbd2cSJim Jagielski 		// ContentNo weiterz"ahlen
1009*b1cdbd2cSJim Jagielski 		++_nContentNo;
1010*b1cdbd2cSJim Jagielski 		return sal_True;
1011*b1cdbd2cSJim Jagielski 	}
1012*b1cdbd2cSJim Jagielski 
1013*b1cdbd2cSJim Jagielski 	return sal_False;
1014*b1cdbd2cSJim Jagielski }
1015*b1cdbd2cSJim Jagielski 
1016*b1cdbd2cSJim Jagielski 
1017