xref: /aoo41x/main/svl/source/items/poolio.cxx (revision 6fb30688)
1cdf0e10cSrcweir /*************************************************************************
2cdf0e10cSrcweir  *
3cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4cdf0e10cSrcweir  *
5cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6cdf0e10cSrcweir  *
7cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8cdf0e10cSrcweir  *
9cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10cdf0e10cSrcweir  *
11cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14cdf0e10cSrcweir  *
15cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20cdf0e10cSrcweir  *
21cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25cdf0e10cSrcweir  *
26cdf0e10cSrcweir  ************************************************************************/
27cdf0e10cSrcweir 
28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29cdf0e10cSrcweir #include "precompiled_svl.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <string.h>
32cdf0e10cSrcweir #include <stdio.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #ifndef GCC
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <tools/solar.h>
38cdf0e10cSrcweir #include <svl/itempool.hxx>
39cdf0e10cSrcweir #include "whassert.hxx"
40cdf0e10cSrcweir #include <svl/brdcst.hxx>
41cdf0e10cSrcweir #include <svl/filerec.hxx>
42cdf0e10cSrcweir #include <svl/svldata.hxx>
43cdf0e10cSrcweir #include "poolio.hxx"
44cdf0e10cSrcweir 
45cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
46cdf0e10cSrcweir 
47cdf0e10cSrcweir DBG_NAME(SfxItemPool);
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //========================================================================
50cdf0e10cSrcweir 
51cdf0e10cSrcweir void SfxItemPool::SetStoringPool( const SfxItemPool *pStoringPool )
52cdf0e10cSrcweir 
53cdf0e10cSrcweir /*	[Beschreibung]
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 	Diese Methode setzt den <SfxItemPool>, der gerade gespeichert wird.
56cdf0e10cSrcweir 	Sie sollte nur in Notf"allen verwendet werden, um z.B. File-Format-
57cdf0e10cSrcweir 	Kompatibilit"at zu gew"ahrleisten o."o. - z.B. in der "uberladung eines
58cdf0e10cSrcweir 	<SfxPoolItem::Store()> zus"atzliche Daten aus dem dazuge"horigen
59cdf0e10cSrcweir 	Pool mit <SfxItemPool::GetStoringPool()> zu besorgen.
60cdf0e10cSrcweir 
61cdf0e10cSrcweir 	Sie wird von <SfxItemPool::Store()> bedient, kann jedoch f"ur nicht
62cdf0e10cSrcweir 	poolable Items auch direkt gerufen werden. Bitte m"oglichst nicht
63cdf0e10cSrcweir 	f"ur jedes Item einzeln, da 2 Calls!
64cdf0e10cSrcweir */
65cdf0e10cSrcweir 
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	ImpSvlData::GetSvlData().pStoringPool = pStoringPool;
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //-------------------------------------------------------------------------
71cdf0e10cSrcweir 
72cdf0e10cSrcweir const SfxItemPool* SfxItemPool::GetStoringPool()
73cdf0e10cSrcweir 
74cdf0e10cSrcweir /*	[Beschreibung]
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	Diese Methode liefert den <SfxItemPool>, der gerade gespeichert wird.
77cdf0e10cSrcweir 	Sie sollte nur in Notf"allen verwendet werden, um z.B. File-Format-
78cdf0e10cSrcweir 	Kompatibilit"at zu gew"ahrleisten o."o. - z.B. in der "uberladung eines
79cdf0e10cSrcweir 	<SfxPoolItem::Store()> zus"atzliche Daten aus dem dazuge"horigen
80cdf0e10cSrcweir 	Pool zu besorgen.
81cdf0e10cSrcweir */
82cdf0e10cSrcweir 
83cdf0e10cSrcweir {
84cdf0e10cSrcweir 	return ImpSvlData::GetSvlData().pStoringPool;
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir //-------------------------------------------------------------------------
88cdf0e10cSrcweir 
89cdf0e10cSrcweir SvStream &SfxItemPool::Store(SvStream &rStream) const
90cdf0e10cSrcweir 
91cdf0e10cSrcweir /*	[Beschreibung]
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	Der SfxItemPool wird inklusive aller seiner Sekund"arpools mit
94cdf0e10cSrcweir 	Pool-Defaults und gepoolten Items in dem angegebenen Stream gespeichert.
95cdf0e10cSrcweir 	Die statischen Defaults werden nicht gespeichert.
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 	[Fileformat]
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 	;zun"achst ein Kompatiblit"ats-Header-Block
101cdf0e10cSrcweir 	Start:		0x1111	SFX_ITEMPOOL_TAG_STARTPOOLS(_4/_5)
102cdf0e10cSrcweir 				sal_uInt8	MAJOR_VER					;SfxItemPool-Version
103cdf0e10cSrcweir 				sal_uInt8	MINOR_VER					;"
104cdf0e10cSrcweir 				0xFFFF	SFX_ITEMPOOL_TAG_TRICK4OLD  ;ex. GetVersion()
105cdf0e10cSrcweir 				sal_uInt16	0x0000						;Pseudo-StyleSheetPool
106cdf0e10cSrcweir 				sal_uInt16	0x0000						;Pseudo-StyleSheetPool
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 	;den ganzen Pool in einen Record
109cdf0e10cSrcweir 				record	SfxMiniRecod(SFX_ITEMPOOL_REC)
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 	;je ein Header vorweg
112cdf0e10cSrcweir 	Header:		record  	SfxMiniRecord(SFX_ITEMPOOL_REC_HEADER)
113cdf0e10cSrcweir 				sal_uInt16			GetVersion()			;Which-Ranges etc.
114cdf0e10cSrcweir 				String			GetName()				;Pool-Name
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	;die Versions-Map, um WhichIds neuer File-Versionen mappen zu k"onnen
117cdf0e10cSrcweir 	Versions:	record	    SfxMultiRecord(SFX_ITEMPOOL_REC_VERSIONS, 0)
118cdf0e10cSrcweir 				sal_uInt16			OldVersion
119cdf0e10cSrcweir 				sal_uInt16			OldStartWhich
120cdf0e10cSrcweir 				sal_uInt16			OldEndWhich
121cdf0e10cSrcweir 				sal_uInt16[]        NewWhich (OldEndWhich-OldStartWhich+1)
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 	;jetzt die gepoolten Items (zuerst nicht-SfxSetItems)
124cdf0e10cSrcweir 	Items:  	record      SfxMultiRecord(SFX_ITEMPOOL_REC_WHICHIDS, 0)
125cdf0e10cSrcweir 				content 		SlotId, 0
126cdf0e10cSrcweir 				sal_uInt16			WhichId
127cdf0e10cSrcweir 				sal_uInt16			pItem->GetVersion()
128cdf0e10cSrcweir 				sal_uInt16			Array-Size
129cdf0e10cSrcweir 				record			SfxMultiRecord(SFX_, 0)
130cdf0e10cSrcweir 				content				Surrogate
131cdf0e10cSrcweir 				sal_uInt16				RefCount
132cdf0e10cSrcweir 				unknown 			pItem->Store()
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	;jetzt die gesetzten Pool-Defaults
135cdf0e10cSrcweir 	Defaults:	record	    SfxMultiRecord(SFX_ITEMPOOL_REC_DEFAULTS, 0)
136cdf0e10cSrcweir 				content			SlotId, 0
137cdf0e10cSrcweir 				sal_uInt16			WhichId
138cdf0e10cSrcweir 				sal_uInt16			pPoolDef->GetVersion()
139cdf0e10cSrcweir 				unknown			pPoolDef->Store();
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 	;dahinter folgt ggf. der Secondary ohne Kompatiblit"ats-Header-Block
142cdf0e10cSrcweir */
143cdf0e10cSrcweir 
144cdf0e10cSrcweir {
145cdf0e10cSrcweir 	DBG_CHKTHIS(SfxItemPool, 0);
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 	// Store-Master finden
148cdf0e10cSrcweir 	SfxItemPool *pStoreMaster = pMaster != this ? pMaster : 0;
149cdf0e10cSrcweir 	while ( pStoreMaster && !pStoreMaster->pImp->bStreaming )
150cdf0e10cSrcweir 		pStoreMaster = pStoreMaster->pSecondary;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	// Alter-Header (Version des Pools an sich und Inhalts-Version 0xffff)
153cdf0e10cSrcweir 	pImp->bStreaming = sal_True;
154cdf0e10cSrcweir 	if ( !pStoreMaster )
155cdf0e10cSrcweir 	{
156cdf0e10cSrcweir 		rStream << ( rStream.GetVersion() >= SOFFICE_FILEFORMAT_50
157cdf0e10cSrcweir 				? SFX_ITEMPOOL_TAG_STARTPOOL_5
158cdf0e10cSrcweir 				: SFX_ITEMPOOL_TAG_STARTPOOL_4 );
159cdf0e10cSrcweir 		rStream << SFX_ITEMPOOL_VER_MAJOR << SFX_ITEMPOOL_VER_MINOR;
160cdf0e10cSrcweir 		rStream << SFX_ITEMPOOL_TAG_TRICK4OLD;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 		// SfxStyleSheet-Bug umgehen
163cdf0e10cSrcweir 		rStream << sal_uInt16(0); // Version
164cdf0e10cSrcweir 		rStream << sal_uInt16(0); // Count (2. Schleife f"allt sonst auf die Fresse)
165cdf0e10cSrcweir 	}
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 	// jeder Pool ist als ganzes ein Record
168cdf0e10cSrcweir 	SfxMiniRecordWriter aPoolRec( &rStream, SFX_ITEMPOOL_REC );
169cdf0e10cSrcweir 	ImpSvlData::GetSvlData().pStoringPool = this;
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 	// Einzel-Header (Version des Inhalts und Name)
172cdf0e10cSrcweir 	{
173cdf0e10cSrcweir 		SfxMiniRecordWriter aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER);
174cdf0e10cSrcweir 		rStream << pImp->nVersion;
175cdf0e10cSrcweir 		SfxPoolItem::writeByteString(rStream, aName);
176cdf0e10cSrcweir 	}
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 	// Version-Maps
179cdf0e10cSrcweir 	{
180cdf0e10cSrcweir 		SfxMultiVarRecordWriter aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP, 0 );
181cdf0e10cSrcweir 		for ( size_t nVerNo = 0; nVerNo < pImp->aVersions.size(); ++nVerNo )
182cdf0e10cSrcweir 		{
183cdf0e10cSrcweir 			aVerRec.NewContent();
184cdf0e10cSrcweir 			SfxPoolVersion_ImplPtr pVer = pImp->aVersions[nVerNo];
185cdf0e10cSrcweir 			rStream << pVer->_nVer << pVer->_nStart << pVer->_nEnd;
186cdf0e10cSrcweir 			sal_uInt16 nCount = pVer->_nEnd - pVer->_nStart + 1;
187cdf0e10cSrcweir 			sal_uInt16 nNewWhich = 0;
188cdf0e10cSrcweir 			for ( sal_uInt16 n = 0; n < nCount; ++n )
189cdf0e10cSrcweir 			{
190cdf0e10cSrcweir 				nNewWhich = pVer->_pMap[n];
191cdf0e10cSrcweir 				rStream << nNewWhich;
192cdf0e10cSrcweir 			}
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 			// Workaround gegen Bug in SetVersionMap der 312
195cdf0e10cSrcweir 			if ( SOFFICE_FILEFORMAT_31 == _nFileFormatVersion )
196cdf0e10cSrcweir 				rStream << sal_uInt16(nNewWhich+1);
197cdf0e10cSrcweir 		}
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 	// gepoolte Items
201cdf0e10cSrcweir 	{
202cdf0e10cSrcweir 		SfxMultiMixRecordWriter aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS, 0 );
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 		// erst Atomaren-Items und dann die Sets schreiben (wichtig beim Laden)
205cdf0e10cSrcweir 		for ( pImp->bInSetItem = sal_False; pImp->bInSetItem <= sal_True && !rStream.GetError(); ++pImp->bInSetItem )
206cdf0e10cSrcweir 		{
207cdf0e10cSrcweir 			SfxPoolItemArray_Impl **pArr = pImp->ppPoolItems;
208cdf0e10cSrcweir 			SfxPoolItem **ppDefItem = ppStaticDefaults;
209cdf0e10cSrcweir 			const sal_uInt16 nSize = GetSize_Impl();
210cdf0e10cSrcweir 			for ( size_t i = 0; i < nSize && !rStream.GetError(); ++i, ++pArr, ++ppDefItem )
211cdf0e10cSrcweir 			{
212cdf0e10cSrcweir 				// Version des Items feststellen
213cdf0e10cSrcweir 				sal_uInt16 nItemVersion = (*ppDefItem)->GetVersion( _nFileFormatVersion );
214cdf0e10cSrcweir 				if ( USHRT_MAX == nItemVersion )
215cdf0e10cSrcweir 					// => kam in zu exportierender Version gar nicht vor
216cdf0e10cSrcweir 					continue;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 				// !poolable wird gar nicht im Pool gespeichert
219cdf0e10cSrcweir 				// und itemsets/plain-items je nach Runde
220cdf0e10cSrcweir #ifdef TF_POOLABLE
221cdf0e10cSrcweir 				if ( *pArr && IsItemFlag(**ppDefItem, SFX_ITEM_POOLABLE) &&
222cdf0e10cSrcweir #else
223cdf0e10cSrcweir 				if ( *pArr && (*ppDefItem)->IsPoolable() &&
224cdf0e10cSrcweir #endif
225cdf0e10cSrcweir 					 pImp->bInSetItem == (*ppDefItem)->ISA(SfxSetItem) )
226cdf0e10cSrcweir 				{
227cdf0e10cSrcweir 					// eigene Kennung, globale Which-Id und Item-Version
228cdf0e10cSrcweir 					sal_uInt16 nSlotId = GetSlotId( (*ppDefItem)->Which(), sal_False );
229cdf0e10cSrcweir 					aWhichIdsRec.NewContent(nSlotId, 0);
230cdf0e10cSrcweir 					rStream << (*ppDefItem)->Which();
231cdf0e10cSrcweir 					rStream << nItemVersion;
232cdf0e10cSrcweir 					const sal_uInt32 nCount = ::std::min<size_t>( (*pArr)->size(), SAL_MAX_UINT32 );
233cdf0e10cSrcweir 					DBG_ASSERT(nCount, "ItemArr is empty");
234cdf0e10cSrcweir 					rStream << nCount;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 					// Items an sich schreiben
237cdf0e10cSrcweir 					SfxMultiMixRecordWriter aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS, 0 );
238cdf0e10cSrcweir 					for ( size_t j = 0; j < nCount; ++j )
239cdf0e10cSrcweir 					{
240cdf0e10cSrcweir 						// Item selbst besorgen
241cdf0e10cSrcweir 						const SfxPoolItem *pItem = (*pArr)->operator[](j);
242cdf0e10cSrcweir 						if ( pItem && pItem->GetRefCount() ) //! siehe anderes MI-REF
243cdf0e10cSrcweir 						{
244cdf0e10cSrcweir 							aItemsRec.NewContent((sal_uInt16)j, 'X' );
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 							if ( pItem->GetRefCount() == SFX_ITEMS_SPECIAL )
247cdf0e10cSrcweir 								rStream << (sal_uInt16) pItem->GetKind();
248cdf0e10cSrcweir 							else
249cdf0e10cSrcweir 							{
250cdf0e10cSrcweir 								rStream << (sal_uInt16) pItem->GetRefCount();
251cdf0e10cSrcweir 								if( pItem->GetRefCount() > SFX_ITEMS_OLD_MAXREF )
252cdf0e10cSrcweir 									rStream.SetError( ERRCODE_IO_NOTSTORABLEINBINARYFORMAT );
253cdf0e10cSrcweir 							}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 							if ( !rStream.GetError() )
256cdf0e10cSrcweir 								pItem->Store(rStream, nItemVersion);
257cdf0e10cSrcweir 							else
258cdf0e10cSrcweir 								break;
259cdf0e10cSrcweir #ifdef DBG_UTIL_MI
260cdf0e10cSrcweir 							if ( !pItem->ISA(SfxSetItem) )
261cdf0e10cSrcweir 							{
262cdf0e10cSrcweir 								sal_uLong nMark = rStream.Tell();
263cdf0e10cSrcweir 								rStream.Seek( nItemStartPos + sizeof(sal_uInt16) );
264cdf0e10cSrcweir 								SfxPoolItem *pClone = pItem->Create(rStream, nItemVersion );
265cdf0e10cSrcweir 								sal_uInt16 nWh = pItem->Which();
266cdf0e10cSrcweir 								SFX_ASSERT( rStream.Tell() == nMark, nWh,"asymmetric store/create" );
267cdf0e10cSrcweir 								SFX_ASSERT( *pClone == *pItem, nWh, "unequal after store/create" );
268cdf0e10cSrcweir 								delete pClone;
269cdf0e10cSrcweir 							}
270cdf0e10cSrcweir #endif
271cdf0e10cSrcweir 						}
272cdf0e10cSrcweir 					}
273cdf0e10cSrcweir 				}
274cdf0e10cSrcweir 			}
275cdf0e10cSrcweir 		}
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 		pImp->bInSetItem = sal_False;
278cdf0e10cSrcweir 	}
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 	// die gesetzten Defaults speichern (Pool-Defaults)
281cdf0e10cSrcweir 	if ( !rStream.GetError() )
282cdf0e10cSrcweir 	{
283cdf0e10cSrcweir 		SfxMultiMixRecordWriter aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS, 0 );
284cdf0e10cSrcweir 		sal_uInt16 nCount = GetSize_Impl();
285cdf0e10cSrcweir 		for ( sal_uInt16 n = 0; n < nCount; ++n )
286cdf0e10cSrcweir 		{
287cdf0e10cSrcweir 			const SfxPoolItem* pDefaultItem = ppPoolDefaults[n];
288cdf0e10cSrcweir 			if ( pDefaultItem )
289cdf0e10cSrcweir 			{
290cdf0e10cSrcweir 				// Version ermitteln
291cdf0e10cSrcweir 				sal_uInt16 nItemVersion = pDefaultItem->GetVersion( _nFileFormatVersion );
292cdf0e10cSrcweir 				if ( USHRT_MAX == nItemVersion )
293cdf0e10cSrcweir 					// => gab es in der Version noch nicht
294cdf0e10cSrcweir 					continue;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 				// eigene Kennung, globale Kennung, Version
297cdf0e10cSrcweir 				sal_uInt16 nSlotId = GetSlotId( pDefaultItem->Which(), sal_False );
298cdf0e10cSrcweir 				aDefsRec.NewContent( nSlotId, 0 );
299cdf0e10cSrcweir 				rStream << pDefaultItem->Which();
300cdf0e10cSrcweir 				rStream << nItemVersion;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 				// Item an sich
303cdf0e10cSrcweir 				pDefaultItem->Store( rStream, nItemVersion );
304cdf0e10cSrcweir 			}
305cdf0e10cSrcweir 		}
306cdf0e10cSrcweir 	}
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 	// weitere Pools rausschreiben
309cdf0e10cSrcweir 	ImpSvlData::GetSvlData().pStoringPool = 0;
310cdf0e10cSrcweir 	aPoolRec.Close();
311cdf0e10cSrcweir 	if ( !rStream.GetError() && pSecondary )
312cdf0e10cSrcweir 		pSecondary->Store( rStream );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	pImp->bStreaming = sal_False;
315cdf0e10cSrcweir 	return rStream;
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir // -----------------------------------------------------------------------
319cdf0e10cSrcweir 
320cdf0e10cSrcweir void SfxItemPool::LoadCompleted()
321cdf0e10cSrcweir 
322cdf0e10cSrcweir /*	[Beschreibung]
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	Wurde der SfxItemPool mit 'bRefCounts' == sal_False geladen, mu\s das
325cdf0e10cSrcweir 	Laden der Dokumentinhalte mit einem Aufruf dieser Methode beendet
326cdf0e10cSrcweir 	werden. Ansonsten hat der Aufruf dieser Methode keine Funktion.
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 	[Anmerkung]
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	Beim Laden ohne Ref-Counts werden diese tats"achlich auf 1 gesetzt,
332cdf0e10cSrcweir 	damit nicht w"ahrend des Ladevorgangs SfxPoolItems gel"oscht werden,
333cdf0e10cSrcweir 	die danach, aber auch noch beim Ladevorgang, ben"otigt werden. Diese
334cdf0e10cSrcweir 	Methode setzt den Ref-Count wieder zur"uck und entfernt dabei
335cdf0e10cSrcweir 	gleichzeitig alle nicht mehr ben"otigten Items.
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 	[Querverweise]
339cdf0e10cSrcweir 
340cdf0e10cSrcweir 	<SfxItemPool::Load()>
341cdf0e10cSrcweir */
342cdf0e10cSrcweir 
343cdf0e10cSrcweir {
344cdf0e10cSrcweir 	// wurden keine Ref-Counts mitgeladen?
345cdf0e10cSrcweir 	if ( pImp->nInitRefCount > 1 )
346cdf0e10cSrcweir 	{
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 		// "uber alle Which-Werte iterieren
349cdf0e10cSrcweir 		SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems;
350cdf0e10cSrcweir 		for( sal_uInt16 nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++ppItemArr )
351cdf0e10cSrcweir 		{
352cdf0e10cSrcweir 			// ist "uberhaupt ein Item mit dem Which-Wert da?
353cdf0e10cSrcweir 			if ( *ppItemArr )
354cdf0e10cSrcweir 			{
355cdf0e10cSrcweir 				// "uber alle Items mit dieser Which-Id iterieren
356cdf0e10cSrcweir 				SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
357cdf0e10cSrcweir 				for( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
358cdf0e10cSrcweir 					if (*ppHtArr)
359cdf0e10cSrcweir 					{
360cdf0e10cSrcweir                         #ifdef DBG_UTIL
361cdf0e10cSrcweir 						const SfxPoolItem &rItem = **ppHtArr;
362cdf0e10cSrcweir 						DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
363cdf0e10cSrcweir 									0 != &((const SfxSetItem&)rItem).GetItemSet(),
364cdf0e10cSrcweir 									"SetItem without ItemSet" );
365cdf0e10cSrcweir                         #endif
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 						if ( !ReleaseRef( **ppHtArr, 1 ) )
368cdf0e10cSrcweir 							DELETEZ( *ppHtArr );
369cdf0e10cSrcweir 					}
370cdf0e10cSrcweir 			}
371cdf0e10cSrcweir 		}
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 		// from now on normal initial ref count
374cdf0e10cSrcweir 		pImp->nInitRefCount = 1;
375cdf0e10cSrcweir 	}
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	// notify secondary pool
378cdf0e10cSrcweir 	if ( pSecondary )
379cdf0e10cSrcweir 		pSecondary->LoadCompleted();
380cdf0e10cSrcweir }
381cdf0e10cSrcweir 
382cdf0e10cSrcweir //============================================================================
383cdf0e10cSrcweir // This had to be moved to a method of its own to keep Solaris GCC happy:
384cdf0e10cSrcweir void SfxItemPool::readTheItems (
385cdf0e10cSrcweir 	SvStream & rStream, sal_uInt32 nItemCount, sal_uInt16 nVersion,
386cdf0e10cSrcweir 	SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** ppArr)
387cdf0e10cSrcweir {
388cdf0e10cSrcweir 	SfxMultiRecordReader aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS );
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 	SfxPoolItemArray_Impl *pNewArr = new SfxPoolItemArray_Impl();
391cdf0e10cSrcweir 	SfxPoolItem *pItem = 0;
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 	sal_uLong n, nLastSurrogate = sal_uLong(-1);
394cdf0e10cSrcweir 	while (aItemsRec.GetContent())
395cdf0e10cSrcweir 	{
396cdf0e10cSrcweir 		// n"achstes Surrogat holen
397cdf0e10cSrcweir 		sal_uInt16 nSurrogate = aItemsRec.GetContentTag();
398cdf0e10cSrcweir 		DBG_ASSERT( aItemsRec.GetContentVersion() == 'X',
399cdf0e10cSrcweir 					"not an item content" );
400cdf0e10cSrcweir 
401cdf0e10cSrcweir 		// fehlende auff"ullen
402cdf0e10cSrcweir 		for ( pItem = 0, n = nLastSurrogate+1; n < nSurrogate; ++n )
403cdf0e10cSrcweir 			pNewArr->push_back( (SfxPoolItem*) pItem );
404cdf0e10cSrcweir 		nLastSurrogate = nSurrogate;
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 		// Ref-Count und Item laden
407*6fb30688SEike Rathke 		sal_uInt16 nRef(0);
408cdf0e10cSrcweir 		rStream >> nRef;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 		pItem = pDefItem->Create(rStream, nVersion);
411cdf0e10cSrcweir 		pNewArr->push_back( (SfxPoolItem*) pItem );
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 		if ( !bPersistentRefCounts )
414cdf0e10cSrcweir 			// bis <SfxItemPool::LoadCompleted()> festhalten
415cdf0e10cSrcweir 			AddRef(*pItem, 1);
416cdf0e10cSrcweir 		else
417cdf0e10cSrcweir 		{
418cdf0e10cSrcweir 			if ( nRef > SFX_ITEMS_OLD_MAXREF )
419cdf0e10cSrcweir 				pItem->SetKind( nRef );
420cdf0e10cSrcweir 			else
421cdf0e10cSrcweir 				AddRef(*pItem, nRef);
422cdf0e10cSrcweir 		}
423cdf0e10cSrcweir 	}
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 	// fehlende auff"ullen
426cdf0e10cSrcweir 	for ( pItem = 0, n = nLastSurrogate+1; n < nItemCount; ++n )
427cdf0e10cSrcweir 		pNewArr->push_back( (SfxPoolItem*) pItem );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 	SfxPoolItemArray_Impl *pOldArr = *ppArr;
430cdf0e10cSrcweir 	*ppArr = pNewArr;
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	// die Items merken, die schon im Pool sind
433cdf0e10cSrcweir 	bool bEmpty = true;
434cdf0e10cSrcweir 	if ( 0 != pOldArr )
435cdf0e10cSrcweir 		for ( n = 0; bEmpty && n < pOldArr->size(); ++n )
436cdf0e10cSrcweir 			bEmpty = pOldArr->operator[](n) == 0;
437cdf0e10cSrcweir 	DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" );
438cdf0e10cSrcweir 	if ( !bEmpty )
439cdf0e10cSrcweir 	{
440cdf0e10cSrcweir 		// f"ur alle alten suchen, ob ein gleiches neues existiert
441cdf0e10cSrcweir 		for ( size_t nOld = 0; nOld < pOldArr->size(); ++nOld )
442cdf0e10cSrcweir 		{
443cdf0e10cSrcweir 			SfxPoolItem *pOldItem = (*pOldArr)[nOld];
444cdf0e10cSrcweir 			if ( pOldItem )
445cdf0e10cSrcweir 			{
446cdf0e10cSrcweir 				sal_uInt32 nFree = SAL_MAX_UINT32;
447cdf0e10cSrcweir 				bool bFound = false;
448cdf0e10cSrcweir 				for ( size_t nNew = (*ppArr)->size(); nNew--; )
449cdf0e10cSrcweir 				{
450cdf0e10cSrcweir 					// geladenes Item
451cdf0e10cSrcweir 					SfxPoolItem *&rpNewItem =
452cdf0e10cSrcweir 						(SfxPoolItem*&)(*ppArr)->operator[](nNew);
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 					// surrogat unbenutzt?
455cdf0e10cSrcweir 					if ( !rpNewItem )
456cdf0e10cSrcweir 						nFree = nNew;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 					// gefunden?
459cdf0e10cSrcweir 					else if ( *rpNewItem == *pOldItem )
460cdf0e10cSrcweir 					{
461cdf0e10cSrcweir 						// wiederverwenden
462cdf0e10cSrcweir 						AddRef( *pOldItem, rpNewItem->GetRefCount() );
463cdf0e10cSrcweir 						SetRefCount( *rpNewItem, 0 );
464cdf0e10cSrcweir 						delete rpNewItem;
465cdf0e10cSrcweir 						rpNewItem = pOldItem;
466cdf0e10cSrcweir 						bFound = true;
467cdf0e10cSrcweir 						break;
468cdf0e10cSrcweir 					}
469cdf0e10cSrcweir 				}
470cdf0e10cSrcweir 
471cdf0e10cSrcweir 				// vorhervorhandene, nicht geladene uebernehmen
472cdf0e10cSrcweir 				if ( !bFound )
473cdf0e10cSrcweir 				{
474cdf0e10cSrcweir 					if ( nFree != SAL_MAX_UINT32 )
475cdf0e10cSrcweir 						(SfxPoolItem*&)(*ppArr)->operator[](nFree) = pOldItem;
476cdf0e10cSrcweir 					else
477cdf0e10cSrcweir 						(*ppArr)->push_back( (SfxPoolItem*) pOldItem );
478cdf0e10cSrcweir 				}
479cdf0e10cSrcweir 			}
480cdf0e10cSrcweir 		}
481cdf0e10cSrcweir 	}
482cdf0e10cSrcweir 	delete pOldArr;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir // -----------------------------------------------------------------------
486cdf0e10cSrcweir 
487cdf0e10cSrcweir SvStream &SfxItemPool::Load(SvStream &rStream)
488cdf0e10cSrcweir {
489cdf0e10cSrcweir 	DBG_CHKTHIS(SfxItemPool, 0);
490cdf0e10cSrcweir 	DBG_ASSERT(ppStaticDefaults, "kein DefaultArray");
491cdf0e10cSrcweir 
492cdf0e10cSrcweir 	// protect items by increasing ref count
493cdf0e10cSrcweir 	if ( !bPersistentRefCounts )
494cdf0e10cSrcweir 	{
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 		// "uber alle Which-Werte iterieren
497cdf0e10cSrcweir 		SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems;
498cdf0e10cSrcweir 		for( size_t nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++ppItemArr )
499cdf0e10cSrcweir 		{
500cdf0e10cSrcweir 			// ist "uberhaupt ein Item mit dem Which-Wert da?
501cdf0e10cSrcweir 			if ( *ppItemArr )
502cdf0e10cSrcweir 			{
503cdf0e10cSrcweir 				// "uber alle Items mit dieser Which-Id iterieren
504cdf0e10cSrcweir 				SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
505cdf0e10cSrcweir 				for( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
506cdf0e10cSrcweir 					if (*ppHtArr)
507cdf0e10cSrcweir 					{
508cdf0e10cSrcweir                         #ifdef DBG_UTIL
509cdf0e10cSrcweir 						const SfxPoolItem &rItem = **ppHtArr;
510cdf0e10cSrcweir 						DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
511cdf0e10cSrcweir 									0 != &((const SfxSetItem&)rItem).GetItemSet(),
512cdf0e10cSrcweir 									"SetItem without ItemSet" );
513cdf0e10cSrcweir 						DBG_WARNING( "loading non-empty ItemPool" );
514cdf0e10cSrcweir                         #endif
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 						AddRef( **ppHtArr, 1 );
517cdf0e10cSrcweir 					}
518cdf0e10cSrcweir 			}
519cdf0e10cSrcweir 		}
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 		// during loading (until LoadCompleted()) protect all items
522cdf0e10cSrcweir 		pImp->nInitRefCount = 2;
523cdf0e10cSrcweir 	}
524cdf0e10cSrcweir 
525cdf0e10cSrcweir 	// Load-Master finden
526cdf0e10cSrcweir 	SfxItemPool *pLoadMaster = pMaster != this ? pMaster : 0;
527cdf0e10cSrcweir 	while ( pLoadMaster && !pLoadMaster->pImp->bStreaming )
528cdf0e10cSrcweir 		pLoadMaster = pLoadMaster->pSecondary;
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	// Gesamt Header einlesen
531cdf0e10cSrcweir 	pImp->bStreaming = sal_True;
532cdf0e10cSrcweir 	if ( !pLoadMaster )
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir 		// Format-Version laden
535cdf0e10cSrcweir 		CHECK_FILEFORMAT2( rStream,
536cdf0e10cSrcweir 				SFX_ITEMPOOL_TAG_STARTPOOL_5, SFX_ITEMPOOL_TAG_STARTPOOL_4 );
537cdf0e10cSrcweir 		rStream >> pImp->nMajorVer >> pImp->nMinorVer;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 		// Format-Version in Master-Pool "ubertragen
540cdf0e10cSrcweir 		pMaster->pImp->nMajorVer = pImp->nMajorVer;
541cdf0e10cSrcweir 		pMaster->pImp->nMinorVer = pImp->nMinorVer;
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 		// altes Format?
544cdf0e10cSrcweir 		if ( pImp->nMajorVer < 2 )
545cdf0e10cSrcweir 			// pImp->bStreaming wird von Load1_Impl() zur"uckgesetzt
546cdf0e10cSrcweir 			return Load1_Impl( rStream );
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 		// zu neues Format?
549cdf0e10cSrcweir 		if ( pImp->nMajorVer > SFX_ITEMPOOL_VER_MAJOR )
550cdf0e10cSrcweir 		{
551cdf0e10cSrcweir 			rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
552cdf0e10cSrcweir 			pImp->bStreaming = sal_False;
553cdf0e10cSrcweir 			return rStream;
554cdf0e10cSrcweir 		}
555cdf0e10cSrcweir 
556cdf0e10cSrcweir 		// Version 1.2-Trick-Daten "uberspringen
557cdf0e10cSrcweir 		CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_TRICK4OLD );
558cdf0e10cSrcweir 		rStream.SeekRel( 4 ); // Hack-Daten wegen SfxStyleSheetPool-Bug  skippen
559cdf0e10cSrcweir 	}
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 	// neues Record-orientiertes Format
562cdf0e10cSrcweir 	SfxMiniRecordReader aPoolRec( &rStream, SFX_ITEMPOOL_REC );
563cdf0e10cSrcweir 	if ( rStream.GetError() )
564cdf0e10cSrcweir 	{
565cdf0e10cSrcweir 		pImp->bStreaming = sal_False;
566cdf0e10cSrcweir 		return rStream;
567cdf0e10cSrcweir 	}
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 	// Einzel-Header
570cdf0e10cSrcweir 	int bOwnPool = sal_True;
571cdf0e10cSrcweir 	UniString aExternName;
572cdf0e10cSrcweir 	{
573cdf0e10cSrcweir 		// Header-Record suchen
574cdf0e10cSrcweir 		SfxMiniRecordReader aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER );
575cdf0e10cSrcweir 		if ( rStream.GetError() )
576cdf0e10cSrcweir 		{
577cdf0e10cSrcweir 			pImp->bStreaming = sal_False;
578cdf0e10cSrcweir 			return rStream;
579cdf0e10cSrcweir 		}
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 		// Header-lesen
582cdf0e10cSrcweir 		rStream >> pImp->nLoadingVersion;
583cdf0e10cSrcweir 		SfxPoolItem::readByteString(rStream, aExternName);
584cdf0e10cSrcweir 		bOwnPool = aExternName == aName;
585cdf0e10cSrcweir 
586cdf0e10cSrcweir 		//! solange wir keine fremden Pools laden k"onnen
587cdf0e10cSrcweir 		if ( !bOwnPool )
588cdf0e10cSrcweir 		{
589cdf0e10cSrcweir 			rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
590cdf0e10cSrcweir 			aPoolRec.Skip();
591cdf0e10cSrcweir 			pImp->bStreaming = sal_False;
592cdf0e10cSrcweir 			return rStream;
593cdf0e10cSrcweir 		}
594cdf0e10cSrcweir 	}
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 	// Version-Maps
597cdf0e10cSrcweir 	{
598cdf0e10cSrcweir 		SfxMultiRecordReader aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP );
599cdf0e10cSrcweir 		if ( rStream.GetError() )
600cdf0e10cSrcweir 		{
601cdf0e10cSrcweir 			pImp->bStreaming = sal_False;
602cdf0e10cSrcweir 			return rStream;
603cdf0e10cSrcweir 		}
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 		// Versions-Maps einlesen
606cdf0e10cSrcweir 		sal_uInt16 nOwnVersion = pImp->nVersion;
607cdf0e10cSrcweir 		for ( sal_uInt16 nVerNo = 0; aVerRec.GetContent(); ++nVerNo )
608cdf0e10cSrcweir 		{
609cdf0e10cSrcweir 			// Header f"ur einzelne Version einlesen
610*6fb30688SEike Rathke 			sal_uInt16 nVersion(0), nHStart(0), nHEnd(0);
611cdf0e10cSrcweir 			rStream >> nVersion >> nHStart >> nHEnd;
612cdf0e10cSrcweir 			sal_uInt16 nCount = nHEnd - nHStart + 1;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 			// Is new version is known?
615cdf0e10cSrcweir 			if ( nVerNo >= pImp->aVersions.size() )
616cdf0e10cSrcweir 			{
617cdf0e10cSrcweir 				// Add new Version
618cdf0e10cSrcweir 				sal_uInt16 *pMap = new sal_uInt16[nCount];
619*6fb30688SEike Rathke                 memset(pMap, 0, nCount * sizeof(sal_uInt16));
620cdf0e10cSrcweir 				for ( sal_uInt16 n = 0; n < nCount; ++n )
621cdf0e10cSrcweir 					rStream >> pMap[n];
622cdf0e10cSrcweir 				SetVersionMap( nVersion, nHStart, nHEnd, pMap );
623cdf0e10cSrcweir 			}
624cdf0e10cSrcweir 		}
625cdf0e10cSrcweir 		pImp->nVersion = nOwnVersion;
626cdf0e10cSrcweir 	}
627cdf0e10cSrcweir 
628cdf0e10cSrcweir 	// Items laden
629cdf0e10cSrcweir 	FASTBOOL bSecondaryLoaded = sal_False;
630cdf0e10cSrcweir 	long nSecondaryEnd = 0;
631cdf0e10cSrcweir 	{
632cdf0e10cSrcweir 		SfxMultiRecordReader aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS);
633cdf0e10cSrcweir 		while ( aWhichIdsRec.GetContent() )
634cdf0e10cSrcweir 		{
635cdf0e10cSrcweir 			// SlotId, Which-Id und Item-Version besorgen
636*6fb30688SEike Rathke 			sal_uInt32 nCount(0);
637*6fb30688SEike Rathke 			sal_uInt16 nVersion(0), nWhich(0);
638cdf0e10cSrcweir 			//!sal_uInt16 nSlotId = aWhichIdsRec.GetContentTag();
639cdf0e10cSrcweir 			rStream >> nWhich;
640cdf0e10cSrcweir 			if ( pImp->nLoadingVersion != pImp->nVersion )
641cdf0e10cSrcweir 				// Which-Id aus File-Version in Pool-Version verschieben
642cdf0e10cSrcweir 				nWhich = GetNewWhich( nWhich );
643cdf0e10cSrcweir 
644cdf0e10cSrcweir 			// unbekanntes Item aus neuerer Version
645cdf0e10cSrcweir 			if ( !IsInRange(nWhich) )
646cdf0e10cSrcweir 				continue;
647cdf0e10cSrcweir 
648cdf0e10cSrcweir 			rStream >> nVersion;
649cdf0e10cSrcweir 			rStream >> nCount;
650cdf0e10cSrcweir 			//!SFX_ASSERTWARNING( !nSlotId || !HasMap() ||
651cdf0e10cSrcweir 			//!			( nSlotId == GetSlotId( nWhich, sal_False ) ) ||
652cdf0e10cSrcweir 			//!			!GetSlotId( nWhich, sal_False ),
653cdf0e10cSrcweir 			//!			nWhich, "Slot/Which mismatch" );
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 			sal_uInt16 nIndex = GetIndex_Impl(nWhich);
656cdf0e10cSrcweir 			SfxPoolItemArray_Impl **ppArr = pImp->ppPoolItems + nIndex;
657cdf0e10cSrcweir 
658cdf0e10cSrcweir 			// SfxSetItems k"onnten Items aus Sekund"arpools beinhalten
659cdf0e10cSrcweir 			SfxPoolItem *pDefItem = *(ppStaticDefaults + nIndex);
660cdf0e10cSrcweir 			pImp->bInSetItem = pDefItem->ISA(SfxSetItem);
661cdf0e10cSrcweir 			if ( !bSecondaryLoaded && pSecondary && pImp->bInSetItem )
662cdf0e10cSrcweir 			{
663cdf0e10cSrcweir 				// an das Ende des eigenen Pools seeken
664cdf0e10cSrcweir 				sal_uLong nLastPos = rStream.Tell();
665cdf0e10cSrcweir 				aPoolRec.Skip();
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 				// Sekund"arpool einlesen
668cdf0e10cSrcweir 				pSecondary->Load( rStream );
669cdf0e10cSrcweir 				bSecondaryLoaded = sal_True;
670cdf0e10cSrcweir 				nSecondaryEnd = rStream.Tell();
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 				// zur"uck zu unseren eigenen Items
673cdf0e10cSrcweir 				rStream.Seek(nLastPos);
674cdf0e10cSrcweir 			}
675cdf0e10cSrcweir 
676cdf0e10cSrcweir 			// Items an sich lesen
677cdf0e10cSrcweir 			readTheItems(rStream, nCount, nVersion, pDefItem, ppArr);
678cdf0e10cSrcweir 
679cdf0e10cSrcweir 			pImp->bInSetItem = sal_False;
680cdf0e10cSrcweir 		}
681cdf0e10cSrcweir 	}
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 	// Pool-Defaults lesen
684cdf0e10cSrcweir 	{
685cdf0e10cSrcweir 		SfxMultiRecordReader aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS );
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 		while ( aDefsRec.GetContent() )
688cdf0e10cSrcweir 		{
689cdf0e10cSrcweir 			// SlotId, Which-Id und Item-Version besorgen
690*6fb30688SEike Rathke 			sal_uInt16 nVersion(0), nWhich(0);
691cdf0e10cSrcweir 			//!sal_uInt16 nSlotId = aDefsRec.GetContentTag();
692cdf0e10cSrcweir 			rStream >> nWhich;
693cdf0e10cSrcweir 			if ( pImp->nLoadingVersion != pImp->nVersion )
694cdf0e10cSrcweir 				// Which-Id aus File-Version in Pool-Version verschieben
695cdf0e10cSrcweir 				nWhich = GetNewWhich( nWhich );
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 			// unbekanntes Item aus neuerer Version
698cdf0e10cSrcweir 			if ( !IsInRange(nWhich) )
699cdf0e10cSrcweir 				continue;
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 			rStream >> nVersion;
702cdf0e10cSrcweir 			//!SFX_ASSERTWARNING( !HasMap() || ( nSlotId == GetSlotId( nWhich, sal_False ) ),
703cdf0e10cSrcweir 			//!			nWhich, "Slot/Which mismatch" );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 			// Pool-Default-Item selbst laden
706cdf0e10cSrcweir 			SfxPoolItem *pItem =
707cdf0e10cSrcweir 					( *( ppStaticDefaults + GetIndex_Impl(nWhich) ) )
708cdf0e10cSrcweir 					->Create( rStream, nVersion );
709cdf0e10cSrcweir 			pItem->SetKind( SFX_ITEMS_POOLDEFAULT );
710cdf0e10cSrcweir 			*( ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem;
711cdf0e10cSrcweir 		}
712cdf0e10cSrcweir 	}
713cdf0e10cSrcweir 
714cdf0e10cSrcweir 	// ggf. Secondary-Pool laden
715cdf0e10cSrcweir 	aPoolRec.Skip();
716cdf0e10cSrcweir 	if ( pSecondary )
717cdf0e10cSrcweir 	{
718cdf0e10cSrcweir 		if ( !bSecondaryLoaded )
719cdf0e10cSrcweir 			pSecondary->Load( rStream );
720cdf0e10cSrcweir 		else
721cdf0e10cSrcweir 			rStream.Seek( nSecondaryEnd );
722cdf0e10cSrcweir 	}
723cdf0e10cSrcweir 
724cdf0e10cSrcweir 	// wenn nicht own-Pool, dann kein Name
725cdf0e10cSrcweir 	if ( aExternName != aName )
726cdf0e10cSrcweir 		aName.Erase();
727cdf0e10cSrcweir 
728cdf0e10cSrcweir 	pImp->bStreaming = sal_False;
729cdf0e10cSrcweir 	return rStream;
730cdf0e10cSrcweir };
731cdf0e10cSrcweir 
732cdf0e10cSrcweir // -----------------------------------------------------------------------
733cdf0e10cSrcweir 
734cdf0e10cSrcweir SvStream &SfxItemPool::Load1_Impl(SvStream &rStream)
735cdf0e10cSrcweir {
736cdf0e10cSrcweir 	// beim Master ist der Header schon von <Load()> geladen worden
737cdf0e10cSrcweir 	if ( !pImp->bStreaming )
738cdf0e10cSrcweir 	{
739cdf0e10cSrcweir 		// Header des Secondary lesen
740cdf0e10cSrcweir 		CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_STARTPOOL_4 );
741cdf0e10cSrcweir 		rStream >> pImp->nMajorVer >> pImp->nMinorVer;
742cdf0e10cSrcweir 	}
743*6fb30688SEike Rathke 	sal_uInt32 nAttribSize(0);
744cdf0e10cSrcweir 	int bOwnPool = sal_True;
745cdf0e10cSrcweir 	UniString aExternName;
746cdf0e10cSrcweir 	if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 2 )
747cdf0e10cSrcweir 		rStream >> pImp->nLoadingVersion;
748cdf0e10cSrcweir 	SfxPoolItem::readByteString(rStream, aExternName);
749cdf0e10cSrcweir 	bOwnPool = aExternName == aName;
750cdf0e10cSrcweir 	pImp->bStreaming = sal_True;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	//! solange wir keine fremden laden k"onnen
753cdf0e10cSrcweir 	if ( !bOwnPool )
754cdf0e10cSrcweir 	{
755cdf0e10cSrcweir 		rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
756cdf0e10cSrcweir 		pImp->bStreaming = sal_False;
757cdf0e10cSrcweir 		return rStream;
758cdf0e10cSrcweir 	}
759cdf0e10cSrcweir 
760cdf0e10cSrcweir 	// Versionen bis 1.3 k"onnen noch keine Which-Verschiebungen lesen
761cdf0e10cSrcweir 	if ( pImp->nMajorVer == 1 && pImp->nMinorVer <= 2 &&
762cdf0e10cSrcweir 		 pImp->nVersion < pImp->nLoadingVersion )
763cdf0e10cSrcweir 	{
764cdf0e10cSrcweir 		rStream.SetError(ERRCODE_IO_WRONGVERSION);
765cdf0e10cSrcweir 		pImp->bStreaming = sal_False;
766cdf0e10cSrcweir 		return rStream;
767cdf0e10cSrcweir 	}
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 	// Size-Table liegt hinter den eigentlichen Attributen
770cdf0e10cSrcweir 	rStream >> nAttribSize;
771cdf0e10cSrcweir 
772cdf0e10cSrcweir 	// Size-Table einlesen
773cdf0e10cSrcweir 	sal_uLong nStartPos = rStream.Tell();
774cdf0e10cSrcweir 	rStream.SeekRel( nAttribSize );
775cdf0e10cSrcweir 	CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_SIZES );
776*6fb30688SEike Rathke 	sal_uInt32 nSizeTableLen(0);
777cdf0e10cSrcweir 	rStream >> nSizeTableLen;
778cdf0e10cSrcweir 	sal_Char *pBuf = new sal_Char[nSizeTableLen];
779cdf0e10cSrcweir 	rStream.Read( pBuf, nSizeTableLen );
780cdf0e10cSrcweir 	sal_uLong nEndOfSizes = rStream.Tell();
781cdf0e10cSrcweir 	SvMemoryStream aSizeTable( pBuf, nSizeTableLen, STREAM_READ );
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 	// ab Version 1.3 steht in der Size-Table eine Versions-Map
784cdf0e10cSrcweir 	if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 3 )
785cdf0e10cSrcweir 	{
786cdf0e10cSrcweir 		// Version-Map finden (letztes sal_uLong der Size-Table gibt Pos an)
787cdf0e10cSrcweir 		rStream.Seek( nEndOfSizes - sizeof(sal_uInt32) );
788*6fb30688SEike Rathke 		sal_uInt32 nVersionMapPos(0);
789cdf0e10cSrcweir 		rStream >> nVersionMapPos;
790cdf0e10cSrcweir 		rStream.Seek( nVersionMapPos );
791cdf0e10cSrcweir 
792cdf0e10cSrcweir 		// Versions-Maps einlesen
793cdf0e10cSrcweir 		CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_VERSIONMAP );
794*6fb30688SEike Rathke 		sal_uInt16 nVerCount(0);
795cdf0e10cSrcweir 		rStream >> nVerCount;
796cdf0e10cSrcweir 		for ( sal_uInt16 nVerNo = 0; nVerNo < nVerCount; ++nVerNo )
797cdf0e10cSrcweir 		{
798cdf0e10cSrcweir 			// Header f"ur einzelne Version einlesen
799*6fb30688SEike Rathke 			sal_uInt16 nVersion(0), nHStart(0), nHEnd(0);
800cdf0e10cSrcweir 			rStream >> nVersion >> nHStart >> nHEnd;
801cdf0e10cSrcweir 			sal_uInt16 nCount = nHEnd - nHStart + 1;
802cdf0e10cSrcweir 			sal_uInt16 nBytes = (nCount)*sizeof(sal_uInt16);
803cdf0e10cSrcweir 
804cdf0e10cSrcweir 			// Is new version is known?
805cdf0e10cSrcweir 			if ( nVerNo >= pImp->aVersions.size() )
806cdf0e10cSrcweir 			{
807cdf0e10cSrcweir 				// Add new Version
808cdf0e10cSrcweir 				sal_uInt16 *pMap = new sal_uInt16[nCount];
809*6fb30688SEike Rathke                 memset(pMap, 0, nCount * sizeof(sal_uInt16));
810cdf0e10cSrcweir 				for ( sal_uInt16 n = 0; n < nCount; ++n )
811cdf0e10cSrcweir 					rStream >> pMap[n];
812cdf0e10cSrcweir 				SetVersionMap( nVersion, nHStart, nHEnd, pMap );
813cdf0e10cSrcweir 			}
814cdf0e10cSrcweir 			else
815cdf0e10cSrcweir 				// Version schon bekannt => "uberspringen
816cdf0e10cSrcweir 				rStream.SeekRel( nBytes );
817cdf0e10cSrcweir 		}
818cdf0e10cSrcweir 	}
819cdf0e10cSrcweir 
820cdf0e10cSrcweir 	// Items laden
821cdf0e10cSrcweir 	rStream.Seek( nStartPos );
822cdf0e10cSrcweir 	CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ITEMS );
823cdf0e10cSrcweir 	FASTBOOL bSecondaryLoaded = sal_False;
824cdf0e10cSrcweir 	long nSecondaryEnd = 0;
825*6fb30688SEike Rathke 	sal_uInt16 nWhich(0), nSlot(0);
826cdf0e10cSrcweir 	while ( rStream >> nWhich, nWhich )
827cdf0e10cSrcweir 	{
828cdf0e10cSrcweir 		// ggf. Which-Id aus alter Version verschieben?
829cdf0e10cSrcweir 		if ( pImp->nLoadingVersion != pImp->nVersion )
830cdf0e10cSrcweir 			nWhich = GetNewWhich( nWhich );
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 		rStream >> nSlot;
833cdf0e10cSrcweir 		sal_uInt16 nMappedWhich = GetWhich(nSlot, sal_False);
834cdf0e10cSrcweir 		int bKnownItem = bOwnPool || IsWhich(nMappedWhich);
835cdf0e10cSrcweir 
836*6fb30688SEike Rathke 		sal_uInt16 nRef(0), nCount(0), nVersion(0);
837*6fb30688SEike Rathke 		sal_uInt32 nAttrSize(0);
838cdf0e10cSrcweir 		rStream >> nVersion >> nCount;
839cdf0e10cSrcweir 
840cdf0e10cSrcweir 		SfxPoolItemArray_Impl **ppArr = 0;
841cdf0e10cSrcweir 		SfxPoolItemArray_Impl *pNewArr = 0;
842cdf0e10cSrcweir 		SfxPoolItem *pDefItem = 0;
843cdf0e10cSrcweir 		if ( bKnownItem )
844cdf0e10cSrcweir 		{
845cdf0e10cSrcweir 			if ( !bOwnPool )
846cdf0e10cSrcweir 				nWhich = nMappedWhich;
847cdf0e10cSrcweir 
848cdf0e10cSrcweir 			//!SFX_ASSERTWARNING( !nSlot || !HasMap() ||
849cdf0e10cSrcweir 			//!			( nSlot == GetSlotId( nWhich, sal_False ) ) ||
850cdf0e10cSrcweir 			//!			!GetSlotId( nWhich, sal_False ),
851cdf0e10cSrcweir 			//!			nWhich, "Slot/Which mismatch" );
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 			sal_uInt16 nIndex = GetIndex_Impl(nWhich);
854cdf0e10cSrcweir 			ppArr = pImp->ppPoolItems + nIndex;
855cdf0e10cSrcweir 			pNewArr = new SfxPoolItemArray_Impl();
856cdf0e10cSrcweir 			pDefItem = *(ppStaticDefaults + nIndex);
857cdf0e10cSrcweir 		}
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 		// Position vor ersten Item merken
860cdf0e10cSrcweir 		sal_uLong nLastPos = rStream.Tell();
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 		// SfxSetItems k"onnten Items aus Sekund"arpools beinhalten
863cdf0e10cSrcweir 		if ( !bSecondaryLoaded && pSecondary && pDefItem->ISA(SfxSetItem) )
864cdf0e10cSrcweir 		{
865cdf0e10cSrcweir 			// an das Ende des eigenen Pools seeken
866cdf0e10cSrcweir 			rStream.Seek(nEndOfSizes);
867cdf0e10cSrcweir             CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr );
868cdf0e10cSrcweir             CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr );
869cdf0e10cSrcweir 
870cdf0e10cSrcweir 			// Sekund"arpool einlesen
871cdf0e10cSrcweir 			pSecondary->Load1_Impl( rStream );
872cdf0e10cSrcweir 			bSecondaryLoaded = sal_True;
873cdf0e10cSrcweir 			nSecondaryEnd = rStream.Tell();
874cdf0e10cSrcweir 
875cdf0e10cSrcweir 			// zur"uck zu unseren eigenen Items
876cdf0e10cSrcweir 			rStream.Seek(nLastPos);
877cdf0e10cSrcweir 		}
878cdf0e10cSrcweir 
879cdf0e10cSrcweir 		// Items an sich lesen
880cdf0e10cSrcweir 		for ( sal_uInt16 j = 0; j < nCount; ++j )
881cdf0e10cSrcweir 		{
882cdf0e10cSrcweir 			sal_uLong nPos = nLastPos;
883cdf0e10cSrcweir 			rStream >> nRef;
884cdf0e10cSrcweir 
885cdf0e10cSrcweir 			if ( bKnownItem )
886cdf0e10cSrcweir 			{
887cdf0e10cSrcweir 				SfxPoolItem *pItem = 0;
888cdf0e10cSrcweir 				if ( nRef )
889cdf0e10cSrcweir 				{
890cdf0e10cSrcweir 					pItem = pDefItem->Create(rStream, nVersion);
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 					if ( !bPersistentRefCounts )
893cdf0e10cSrcweir 						// bis <SfxItemPool::LoadCompleted()> festhalten
894cdf0e10cSrcweir 						AddRef(*pItem, 1);
895cdf0e10cSrcweir 					else
896cdf0e10cSrcweir 					{
897cdf0e10cSrcweir 						if ( nRef > SFX_ITEMS_OLD_MAXREF )
898cdf0e10cSrcweir 							pItem->SetKind( nRef );
899cdf0e10cSrcweir 						else
900cdf0e10cSrcweir 							AddRef(*pItem, nRef);
901cdf0e10cSrcweir 					}
902cdf0e10cSrcweir 				}
903cdf0e10cSrcweir 				//pNewArr->insert( pItem, j );
904cdf0e10cSrcweir 				pNewArr->push_back( (SfxPoolItem*) pItem );
905cdf0e10cSrcweir 
906cdf0e10cSrcweir 				// restliche gespeicherte Laenge skippen (neueres Format)
907cdf0e10cSrcweir 				nLastPos = rStream.Tell();
908cdf0e10cSrcweir 			}
909cdf0e10cSrcweir 
910cdf0e10cSrcweir 			aSizeTable >> nAttrSize;
911cdf0e10cSrcweir 			SFX_ASSERT( !bKnownItem || ( nPos + nAttrSize) >= nLastPos,
912cdf0e10cSrcweir 						nPos,
913cdf0e10cSrcweir 						"too many bytes read - version mismatch?" );
914cdf0e10cSrcweir 
915cdf0e10cSrcweir 			if ( !bKnownItem || ( nLastPos < (nPos + nAttrSize) ) )
916cdf0e10cSrcweir 			{
917cdf0e10cSrcweir 				nLastPos = nPos + nAttrSize;
918cdf0e10cSrcweir 				rStream.Seek( nLastPos );
919cdf0e10cSrcweir 			}
920cdf0e10cSrcweir 		}
921cdf0e10cSrcweir 
922cdf0e10cSrcweir 		if ( bKnownItem )
923cdf0e10cSrcweir 		{
924cdf0e10cSrcweir 			SfxPoolItemArray_Impl *pOldArr = *ppArr;
925cdf0e10cSrcweir 			*ppArr = pNewArr;
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 			// die Items merken, die schon im Pool sind
928cdf0e10cSrcweir 			int bEmpty = sal_True;
929cdf0e10cSrcweir 			if ( 0 != pOldArr )
930cdf0e10cSrcweir 				for ( size_t n = 0; bEmpty && n < pOldArr->size(); ++n )
931cdf0e10cSrcweir 					bEmpty = pOldArr->operator[](n) == 0;
932cdf0e10cSrcweir 			DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" );
933cdf0e10cSrcweir 			if ( !bEmpty )
934cdf0e10cSrcweir 			{
935cdf0e10cSrcweir 				// f"ur alle alten suchen, ob ein gleiches neues existiert
936cdf0e10cSrcweir 				for ( size_t nOld = 0; nOld < pOldArr->size(); ++nOld )
937cdf0e10cSrcweir 				{
938cdf0e10cSrcweir 					SfxPoolItem *pOldItem = (*pOldArr)[nOld];
939cdf0e10cSrcweir 					if ( pOldItem )
940cdf0e10cSrcweir 					{
941cdf0e10cSrcweir 						bool bFound = false;
942cdf0e10cSrcweir 						for ( size_t nNew = 0;
943cdf0e10cSrcweir 							  nNew < (*ppArr)->size();  ++nNew )
944cdf0e10cSrcweir 						{
945cdf0e10cSrcweir 							SfxPoolItem *&rpNewItem =
946cdf0e10cSrcweir 								(SfxPoolItem*&)(*ppArr)->operator[](nNew);
947cdf0e10cSrcweir 
948cdf0e10cSrcweir 							if ( rpNewItem && *rpNewItem == *pOldItem )
949cdf0e10cSrcweir 							{
950cdf0e10cSrcweir 								AddRef( *pOldItem, rpNewItem->GetRefCount() );
951cdf0e10cSrcweir 								SetRefCount( *rpNewItem, 0 );
952cdf0e10cSrcweir 								delete rpNewItem;
953cdf0e10cSrcweir 								rpNewItem = pOldItem;
954cdf0e10cSrcweir 								bFound = true;
955cdf0e10cSrcweir 								SFX_TRACE( "reusing item", pOldItem );
956cdf0e10cSrcweir 								break;
957cdf0e10cSrcweir 							}
958cdf0e10cSrcweir 						}
959cdf0e10cSrcweir 						if ( !bFound )
960cdf0e10cSrcweir                         {
961cdf0e10cSrcweir 							SFX_TRACE( "item not found: ", pOldItem );
962cdf0e10cSrcweir                         }
963cdf0e10cSrcweir 					}
964cdf0e10cSrcweir 				}
965cdf0e10cSrcweir 			}
966cdf0e10cSrcweir 			delete pOldArr; /* @@@ */
967cdf0e10cSrcweir 		}
968cdf0e10cSrcweir 	}
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 	// Pool-Defaults lesen
971cdf0e10cSrcweir 	if ( pImp->nMajorVer > 1 || pImp->nMinorVer > 0 )
972cdf0e10cSrcweir 		CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_DEFAULTS );
973cdf0e10cSrcweir 
974cdf0e10cSrcweir 	sal_uLong nLastPos = rStream.Tell();
975cdf0e10cSrcweir 	while ( rStream >> nWhich, nWhich )
976cdf0e10cSrcweir 	{
977cdf0e10cSrcweir 		// ggf. Which-Id aus alter Version verschieben?
978cdf0e10cSrcweir 		if ( pImp->nLoadingVersion != pImp->nVersion )
979cdf0e10cSrcweir 			nWhich = GetNewWhich( nWhich );
980cdf0e10cSrcweir 
981cdf0e10cSrcweir 		rStream >> nSlot;
982cdf0e10cSrcweir 		sal_uInt16 nMappedWhich = GetWhich(nSlot, sal_False);
983cdf0e10cSrcweir 		int bKnownItem = bOwnPool || IsWhich(nMappedWhich);
984cdf0e10cSrcweir 
985cdf0e10cSrcweir 		sal_uLong nPos = nLastPos;
986*6fb30688SEike Rathke 		sal_uInt32 nSize(0);
987*6fb30688SEike Rathke 		sal_uInt16 nVersion(0);
988cdf0e10cSrcweir 		rStream >> nVersion;
989cdf0e10cSrcweir 
990cdf0e10cSrcweir 		if ( bKnownItem )
991cdf0e10cSrcweir 		{
992cdf0e10cSrcweir 			if ( !bOwnPool )
993cdf0e10cSrcweir 				nWhich = nMappedWhich;
994cdf0e10cSrcweir 			SfxPoolItem *pItem =
995cdf0e10cSrcweir 				( *( ppStaticDefaults + GetIndex_Impl(nWhich) ) )
996cdf0e10cSrcweir 				->Create( rStream, nVersion );
997cdf0e10cSrcweir 			pItem->SetKind( SFX_ITEMS_POOLDEFAULT );
998cdf0e10cSrcweir 			*( ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem;
999cdf0e10cSrcweir 		}
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 		nLastPos = rStream.Tell();
1002cdf0e10cSrcweir 		aSizeTable >> nSize;
1003cdf0e10cSrcweir 		SFX_ASSERT( ( nPos + nSize) >= nLastPos, nPos,
1004cdf0e10cSrcweir 					"too many bytes read - version mismatch?" );
1005cdf0e10cSrcweir 		if ( nLastPos < (nPos + nSize) )
1006cdf0e10cSrcweir 			rStream.Seek( nPos + nSize );
1007cdf0e10cSrcweir 	}
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir 	delete[] pBuf;
1010cdf0e10cSrcweir 	rStream.Seek(nEndOfSizes);
1011cdf0e10cSrcweir 	CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL );
1012cdf0e10cSrcweir 	CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL );
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir 	if ( pSecondary )
1015cdf0e10cSrcweir 	{
1016cdf0e10cSrcweir 		if ( !bSecondaryLoaded )
1017cdf0e10cSrcweir 			pSecondary->Load1_Impl( rStream );
1018cdf0e10cSrcweir 		else
1019cdf0e10cSrcweir 			rStream.Seek( nSecondaryEnd );
1020cdf0e10cSrcweir 	}
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir 	if ( aExternName != aName )
1023cdf0e10cSrcweir 		aName.Erase();
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir 	pImp->bStreaming = sal_False;
1026cdf0e10cSrcweir 	return rStream;
1027cdf0e10cSrcweir }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir // -----------------------------------------------------------------------
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir const SfxPoolItem* SfxItemPool::LoadSurrogate
1032cdf0e10cSrcweir (
1033cdf0e10cSrcweir 	SvStream&			rStream,	// vor einem Surrogat positionierter Stream
1034cdf0e10cSrcweir 	sal_uInt16& 			rWhich, 	// Which-Id des zu ladenden <SfxPoolItem>s
1035cdf0e10cSrcweir 	sal_uInt16				nSlotId,	// Slot-Id des zu ladenden <SfxPoolItem>s
1036cdf0e10cSrcweir 	const SfxItemPool*	pRefPool	// <SfxItemPool> in dem das Surrogat gilt
1037cdf0e10cSrcweir )
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir /*	[Beschreibung]
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir 	L"adt Surrogat aus 'rStream' und liefert das dadurch in 'rRefPool'
1042cdf0e10cSrcweir 	repr"asentierte SfxPoolItem zu"ruck. Ist das im Stream befindliche
1043cdf0e10cSrcweir 	Surrogat == SFX_ITEMS_DIRECT (!SFX_ITEM_POOLABLE) wird 0 zur"uckgegeben,
1044cdf0e10cSrcweir 	das Item ist direkt aus dem Stream zu laden. Bei 0xfffffff0 (SFX_ITEMS_NULL)
1045cdf0e10cSrcweir 	wird auch 0 zurueckgegeben und rWhich auf 0 gesetzt, das Item ist nicht
1046cdf0e10cSrcweir 	verfuegbar.
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir 	Ansonsten wird ber"ucksichtigt, ob der betroffene Pool ohne Ref-Counts
1049cdf0e10cSrcweir 	geladen wird, ob aus einem neuen Pool nachgeladen wird (&rRefPool != this)
1050cdf0e10cSrcweir 	oder ob aus einem g"anzlich anders aufgebauten Pool geladen wird.
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir 	Wird aus einem anders aufgebauten Pool geladen und die 'nSlotId' kann
1053cdf0e10cSrcweir 	nicht in eine Which-Id dieses Pools gemappt werden, wird ebenfalls 0
1054cdf0e10cSrcweir 	zur"uckgeliefert.
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir 	Preconditions:	- Pool mu\s geladen sein
1057cdf0e10cSrcweir 					- LoadCompleted darf noch nicht gerufen worden sein
1058cdf0e10cSrcweir 					- 'rStream' steht genau an der Position, an der ein
1059cdf0e10cSrcweir 					  Surrogat f"ur ein Item mit der SlotId 'nSlotId' und
1060cdf0e10cSrcweir 					  der WhichId 'rWhichId' mit StoreSurrogate gepeichert
1061cdf0e10cSrcweir 					  wurde
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	Postconditions:	- 'rStream' ist so positioniert, wie auch StoreSurrogate
1064cdf0e10cSrcweir 					  sein speichern beendet hatte
1065cdf0e10cSrcweir 					- konnte ein Item geladen werden, befindet es sich
1066cdf0e10cSrcweir 					  in diesem SfxItemPool
1067cdf0e10cSrcweir 					- 'rWhichId' enth"alt die ggf. gemappte Which-Id
1068cdf0e10cSrcweir 	Laufzeit:       Tiefe des Ziel Sekund"arpools * 10 + 10
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir 	[Querverweise]
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir 	<SfxItemPool::StoreSurrogate(SvStream&,const SfxPoolItem &)const>
1073cdf0e10cSrcweir */
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir 	// Read the first surrogate
1077*6fb30688SEike Rathke 	sal_uInt32 nSurrogat(0);
1078cdf0e10cSrcweir 	rStream >> nSurrogat;
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 	// Is item stored directly?
1081cdf0e10cSrcweir 	if ( SFX_ITEMS_DIRECT == nSurrogat )
1082cdf0e10cSrcweir 		return 0;
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir 	// Item does not exist?
1085cdf0e10cSrcweir 	if ( SFX_ITEMS_NULL == nSurrogat )
1086cdf0e10cSrcweir 	{
1087cdf0e10cSrcweir 		rWhich = 0;
1088cdf0e10cSrcweir 		return 0;
1089cdf0e10cSrcweir 	}
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir 	// Bei einem identisch aufgebauten Pool (im Stream) kann das Surrogat
1092cdf0e10cSrcweir 	// auf jeden Fall aufgel"ost werden.
1093cdf0e10cSrcweir 	if ( !pRefPool )
1094cdf0e10cSrcweir 		pRefPool = this;
1095cdf0e10cSrcweir 	FASTBOOL bResolvable = pRefPool->GetName().Len() > 0;
1096cdf0e10cSrcweir 	if ( !bResolvable )
1097cdf0e10cSrcweir 	{
1098cdf0e10cSrcweir 		// Bei einem anders aufgebauten Pool im Stream, mu\s die SlotId
1099cdf0e10cSrcweir 		// aus dem Stream in eine Which-Id gemappt werden k"onnen.
1100cdf0e10cSrcweir 		sal_uInt16 nMappedWhich = nSlotId ? GetWhich(nSlotId, sal_True) : 0;
1101cdf0e10cSrcweir 		if ( IsWhich(nMappedWhich) )
1102cdf0e10cSrcweir 		{
1103cdf0e10cSrcweir 			// gemappte SlotId kann "ubernommen werden
1104cdf0e10cSrcweir 			rWhich = nMappedWhich;
1105cdf0e10cSrcweir 			bResolvable = sal_True;
1106cdf0e10cSrcweir 		}
1107cdf0e10cSrcweir 	}
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir 	// kann Surrogat aufgel"ost werden?
1110cdf0e10cSrcweir 	const SfxPoolItem *pItem = 0;
1111cdf0e10cSrcweir 	if ( bResolvable )
1112cdf0e10cSrcweir 	{
1113cdf0e10cSrcweir 		for ( SfxItemPool *pTarget = this; pTarget; pTarget = pTarget->pSecondary )
1114cdf0e10cSrcweir 		{
1115cdf0e10cSrcweir 			// richtigen (Folge-) Pool gefunden?
1116cdf0e10cSrcweir 			if ( pTarget->IsInRange(rWhich) )
1117cdf0e10cSrcweir 			{
1118cdf0e10cSrcweir 				// dflt-Attribut?
1119cdf0e10cSrcweir 				if ( SFX_ITEMS_DEFAULT == nSurrogat )
1120cdf0e10cSrcweir 					return *(pTarget->ppStaticDefaults +
1121cdf0e10cSrcweir 							pTarget->GetIndex_Impl(rWhich));
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir 				SfxPoolItemArray_Impl* pItemArr = *(pTarget->pImp->ppPoolItems +
1124cdf0e10cSrcweir 						pTarget->GetIndex_Impl(rWhich));
1125cdf0e10cSrcweir 				pItem = pItemArr && nSurrogat < pItemArr->size()
1126cdf0e10cSrcweir 							? (*pItemArr)[nSurrogat]
1127cdf0e10cSrcweir 							: 0;
1128cdf0e10cSrcweir 				if ( !pItem )
1129cdf0e10cSrcweir 				{
1130cdf0e10cSrcweir 					DBG_ERROR( "can't resolve surrogate" );
1131cdf0e10cSrcweir 					rWhich = 0; // nur zur Sicherheit fuer richtige Stream-Pos
1132cdf0e10cSrcweir 					return 0;
1133cdf0e10cSrcweir 				}
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir 				// Nachladen aus Ref-Pool?
1136cdf0e10cSrcweir 				if ( pRefPool != pMaster )
1137cdf0e10cSrcweir 					return &pTarget->Put( *pItem );
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir 				// Referenzen sind NICHT schon mit Pool geladen worden?
1140cdf0e10cSrcweir 				if ( !pTarget->HasPersistentRefCounts() )
1141cdf0e10cSrcweir 					AddRef( *pItem, 1 );
1142cdf0e10cSrcweir 				else
1143cdf0e10cSrcweir 					return pItem;
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir 				return pItem;
1146cdf0e10cSrcweir 			}
1147cdf0e10cSrcweir 		}
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir 		SFX_ASSERT( sal_False, rWhich, "can't resolve Which-Id in LoadSurrogate" );
1150cdf0e10cSrcweir 	}
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 	return 0;
1153cdf0e10cSrcweir }
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir //-------------------------------------------------------------------------
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir FASTBOOL SfxItemPool::StoreSurrogate
1159cdf0e10cSrcweir (
1160cdf0e10cSrcweir 	SvStream&			rStream,
1161cdf0e10cSrcweir 	const SfxPoolItem* 	pItem
1162cdf0e10cSrcweir )	const
1163cdf0e10cSrcweir 
1164cdf0e10cSrcweir /*	[Beschreibung]
1165cdf0e10cSrcweir 
1166cdf0e10cSrcweir 	Speichert ein Surrogat f"ur '*pItem' in 'rStream'.
1167cdf0e10cSrcweir 
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir 	[R"uckgabewert]
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir 	FASTBOOL				sal_True
1172cdf0e10cSrcweir 							es wurde ein echtes Surrogat gespeichert, auch
1173cdf0e10cSrcweir 							SFX_ITEMS_NULL bei 'pItem==0',
1174cdf0e10cSrcweir 							SFX_ITEMS_STATICDEFAULT und SFX_ITEMS_POOLDEFAULT
1175cdf0e10cSrcweir 							gelten als 'echte' Surrogate
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir 							sal_False
1178cdf0e10cSrcweir 							es wurde ein Dummy-Surrogat (SFX_ITEMS_DIRECT)
1179cdf0e10cSrcweir 							gespeichert, das eigentliche Item mu\s direkt
1180cdf0e10cSrcweir 							hinterher selbst gespeichert werden
1181cdf0e10cSrcweir */
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir {
1184cdf0e10cSrcweir 	if ( pItem )
1185cdf0e10cSrcweir 	{
1186cdf0e10cSrcweir 		FASTBOOL bRealSurrogate = IsItemFlag(*pItem, SFX_ITEM_POOLABLE);
1187cdf0e10cSrcweir 		rStream << ( bRealSurrogate
1188cdf0e10cSrcweir 						? GetSurrogate( pItem )
1189cdf0e10cSrcweir 						: SFX_ITEMS_DIRECT );
1190cdf0e10cSrcweir 		return bRealSurrogate;
1191cdf0e10cSrcweir 	}
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir     rStream << SFX_ITEMS_NULL;
1194cdf0e10cSrcweir 	return sal_True;
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir // -----------------------------------------------------------------------
1198cdf0e10cSrcweir 
1199cdf0e10cSrcweir sal_uInt32 SfxItemPool::GetSurrogate(const SfxPoolItem *pItem) const
1200cdf0e10cSrcweir {
1201cdf0e10cSrcweir 	DBG_CHKTHIS(SfxItemPool, 0);
1202cdf0e10cSrcweir 	DBG_ASSERT( pItem, "no 0-Pointer Surrogate" );
1203cdf0e10cSrcweir 	DBG_ASSERT( !IsInvalidItem(pItem), "no Invalid-Item Surrogate" );
1204cdf0e10cSrcweir 	DBG_ASSERT( !IsPoolDefaultItem(pItem), "no Pool-Default-Item Surrogate" );
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir 	if ( !IsInRange(pItem->Which()) )
1207cdf0e10cSrcweir 	{
1208cdf0e10cSrcweir 		if ( pSecondary )
1209cdf0e10cSrcweir 			return pSecondary->GetSurrogate( pItem );
1210cdf0e10cSrcweir 		SFX_ASSERT( 0, pItem->Which(), "unknown Which-Id - dont ask me for surrogates" );
1211cdf0e10cSrcweir 	}
1212cdf0e10cSrcweir 
1213cdf0e10cSrcweir 	// Pointer auf static- oder pool-dflt-Attribut?
1214cdf0e10cSrcweir 	if( IsStaticDefaultItem(pItem) || IsPoolDefaultItem(pItem) )
1215cdf0e10cSrcweir 		return SFX_ITEMS_DEFAULT;
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir 	SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(pItem->Which()));
1218cdf0e10cSrcweir 	DBG_ASSERT(pItemArr, "ItemArr is not available");
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir 	for ( size_t i = 0; i < pItemArr->size(); ++i )
1221cdf0e10cSrcweir 	{
1222cdf0e10cSrcweir 		const SfxPoolItem *p = (*pItemArr)[i];
1223cdf0e10cSrcweir 		if ( p == pItem )
1224cdf0e10cSrcweir 			return i;
1225cdf0e10cSrcweir 	}
1226cdf0e10cSrcweir 	SFX_ASSERT( 0, pItem->Which(), "Item not in the pool");
1227cdf0e10cSrcweir 	return SFX_ITEMS_NULL;
1228cdf0e10cSrcweir }
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir // -----------------------------------------------------------------------
1231cdf0e10cSrcweir 
1232cdf0e10cSrcweir FASTBOOL SfxItemPool::IsInStoringRange( sal_uInt16 nWhich ) const
1233cdf0e10cSrcweir {
1234cdf0e10cSrcweir 	return nWhich >= pImp->nStoringStart &&
1235cdf0e10cSrcweir 		   nWhich <= pImp->nStoringEnd;
1236cdf0e10cSrcweir }
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir //------------------------------------------------------------------------
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir void SfxItemPool::SetStoringRange( sal_uInt16 nFrom, sal_uInt16 nTo )
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir /*	[Beschreibung]
1243cdf0e10cSrcweir 
1244cdf0e10cSrcweir 	Mit dieser Methode kann der Which-Bereich eingeengt werden, der
1245cdf0e10cSrcweir 	von ItemSets dieses Pool (und dem Pool selbst) gespeichert wird.
1246cdf0e10cSrcweir 	Die Methode muss dazu vor <SfxItemPool::Store()> gerufen werden
1247cdf0e10cSrcweir 	und die Werte muessen auch noch gesetzt sein, wenn das eigentliche
1248cdf0e10cSrcweir 	Dokument (also die ItemSets gespeicher werden).
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 	Ein Zuruecksetzen ist dann nicht noetig, wenn dieser Range vor
1251cdf0e10cSrcweir 	JEDEM Speichern richtig gesetzt wird, da er nur beim Speichern
1252cdf0e10cSrcweir 	beruecksichtigt wird.
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir 	Dieses muss fuer das 3.1-Format gemacht werden, da dort eine
1255cdf0e10cSrcweir 	Bug in der Pool-Lade-Methode vorliegt.
1256cdf0e10cSrcweir */
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir {
1259cdf0e10cSrcweir 	pImp->nStoringStart = nFrom;
1260cdf0e10cSrcweir 	pImp->nStoringEnd = nTo;
1261cdf0e10cSrcweir }
1262cdf0e10cSrcweir 
1263cdf0e10cSrcweir // -----------------------------------------------------------------------
1264cdf0e10cSrcweir 
1265cdf0e10cSrcweir void SfxItemPool::SetVersionMap
1266cdf0e10cSrcweir (
1267cdf0e10cSrcweir 	sal_uInt16 	nVer, 				/* 	neue Versionsnummer */
1268cdf0e10cSrcweir 	sal_uInt16  nOldStart,          /*  alte erste Which-Id */
1269cdf0e10cSrcweir 	sal_uInt16  nOldEnd,            /*  alte letzte Which-Id */
1270cdf0e10cSrcweir 	sal_uInt16*	pOldWhichIdTab		/* 	Array mit genau dem Aufbau der Which-Ids
1271cdf0e10cSrcweir 									der vorhergehenden Version, in denen
1272cdf0e10cSrcweir 									die jeweils neue Which-Id steht. */
1273cdf0e10cSrcweir )
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir /*	[Beschreibung]
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir 	Mit dieser Methode k"onnen neue, inkompatible Which-Id-Folgen oder
1278cdf0e10cSrcweir 	Verteilungen realisiert werden. Pools, die noch mit alten Versionen
1279cdf0e10cSrcweir 	gespeichert wurden, werden dann "uber die angegebene Tabelle solange
1280cdf0e10cSrcweir 	gemappt, bis die aktuelle Version erreicht ist. Neuere Pools k"onnen
1281cdf0e10cSrcweir 	unter Verlust neuer Attribute geladen werden, da die Map mit dem Pool
1282cdf0e10cSrcweir 	gespeichert wird.
1283cdf0e10cSrcweir 
1284cdf0e10cSrcweir 	Precondition:	Pool darf noch nicht geladen sein
1285cdf0e10cSrcweir 	Postcondition:	Which-Ids aus fr"uheren Versionen k"onnen bei Laden auf
1286cdf0e10cSrcweir 					Version 'nVer' gemappt werden
1287cdf0e10cSrcweir 	Laufzeit:       1.5 * new + 10
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir 	[Anmerkung]
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir 	F"ur neue Which-Ranges (nStart,nEnd) m"ssen im Vergleich zur Vorg"anger-
1292cdf0e10cSrcweir 	Version (nOldStart,nOldEnd) immer gelten, da\s (nOldStart,nOldEnd)
1293cdf0e10cSrcweir 	vollst"andig in (nStart,nEnd) enthalten ist. Es ist also zul"assig, den
1294cdf0e10cSrcweir 	Which-Range in beide Richtungen zu erweitern, auch durch Einf"ugung
1295cdf0e10cSrcweir 	von Which-Ids, nicht aber ihn zu beschneiden.
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 	Diese Methode sollte nur im oder direkt nach Aufruf des Konstruktors
1298cdf0e10cSrcweir 	gerufen werden.
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir 	Das Array mu\s statisch sein, da es nicht kopiert wird und au\serdem
1301cdf0e10cSrcweir 	im Copy-Ctor des SfxItemPool wiederverwendet wird.
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir 	[Beispiel]
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir 	Urspr"unglich (Version 0) hatte der Pool folgende Which-Ids:
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir 		1:A, 2:B, 3:C, 4:D
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir 	Nun soll eine neue Version (Version 1) zwei zus"atzliche Ids X und Y
1311cdf0e10cSrcweir 	zwischen B und C erhalten, also wie folgt aussehen:
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir 		1:A, 2:B, 3:X, 4:Y, 5:C, 6:D
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir 	Dabei haben sich also die Ids 3 und 4 ge"andert. F"ur die neue Version
1316cdf0e10cSrcweir 	m"u\ste am Pool folgendes gesetzt werden:
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir 		static sal_uInt16 nVersion1Map = { 1, 2, 5, 6 };
1319cdf0e10cSrcweir 		pPool->SetVersionMap( 1, 1, 4, &nVersion1Map );
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir 	[Querverweise]
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir 	<SfxItemPool::IsLoadingVersionCurrent()const>
1325cdf0e10cSrcweir 	<SfxItemPool::GetNewWhich(sal_uInt16)>
1326cdf0e10cSrcweir 	<SfxItemPool::GetVersion()const>
1327cdf0e10cSrcweir 	<SfxItemPool::GetLoadingVersion()const>
1328cdf0e10cSrcweir */
1329cdf0e10cSrcweir 
1330cdf0e10cSrcweir {
1331cdf0e10cSrcweir 	// create new map entry to insert
1332cdf0e10cSrcweir 	const SfxPoolVersion_ImplPtr pVerMap = SfxPoolVersion_ImplPtr( new SfxPoolVersion_Impl(
1333cdf0e10cSrcweir 				nVer, nOldStart, nOldEnd, pOldWhichIdTab ) );
1334cdf0e10cSrcweir 	pImp->aVersions.push_back( pVerMap );
1335cdf0e10cSrcweir 
1336cdf0e10cSrcweir 	DBG_ASSERT( nVer > pImp->nVersion, "Versions not sorted" );
1337cdf0e10cSrcweir 	pImp->nVersion = nVer;
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir 	// Versions-Range anpassen
1340cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < nOldEnd-nOldStart+1; ++n )
1341cdf0e10cSrcweir 	{
1342cdf0e10cSrcweir 		sal_uInt16 nWhich = pOldWhichIdTab[n];
1343cdf0e10cSrcweir 		if ( nWhich < pImp->nVerStart )
1344cdf0e10cSrcweir 		{
1345cdf0e10cSrcweir 			if ( !nWhich )
1346cdf0e10cSrcweir 				nWhich = 0;
1347cdf0e10cSrcweir 			pImp->nVerStart = nWhich;
1348cdf0e10cSrcweir 		}
1349cdf0e10cSrcweir 		else if ( nWhich > pImp->nVerEnd )
1350cdf0e10cSrcweir 			pImp->nVerEnd = nWhich;
1351cdf0e10cSrcweir 	}
1352cdf0e10cSrcweir }
1353cdf0e10cSrcweir 
1354cdf0e10cSrcweir // -----------------------------------------------------------------------
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir sal_uInt16 SfxItemPool::GetNewWhich
1357cdf0e10cSrcweir (
1358cdf0e10cSrcweir 	sal_uInt16	nFileWhich		// die aus dem Stream geladene Which-Id
1359cdf0e10cSrcweir )	const
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir /*	[Beschreibung]
1362cdf0e10cSrcweir 
1363cdf0e10cSrcweir 	Diese Methoden rechnet Which-Ids aus einem File-Format in die der
1364cdf0e10cSrcweir 	aktuellen Pool-Version um. Ist das File-Format "alter, werden die vom
1365cdf0e10cSrcweir 	Pool-Entwickler mit SetVersion() gesetzten Tabellen verwendet,
1366cdf0e10cSrcweir 	ist das File-Format neuer, dann die aus dem File geladenen Tabellen.
1367cdf0e10cSrcweir 	Im letzteren Fall kann ggf. nicht jede Which-Id gemappt werden,
1368cdf0e10cSrcweir 	so da\s 0 zur"uckgeliefert wird.
1369cdf0e10cSrcweir 
1370cdf0e10cSrcweir 	Die Berechnung ist nur f"ur Which-Ids definiert, die in der betreffenden
1371cdf0e10cSrcweir 	File-Version unterst"utzt wurden. Dies ist per Assertion abgesichert.
1372cdf0e10cSrcweir 
1373cdf0e10cSrcweir 	Precondition:	Pool mu\s geladen sein
1374cdf0e10cSrcweir 	Postcondition:	unver"andert
1375cdf0e10cSrcweir 	Laufzeit:		linear(Anzahl der Sekund"arpools) +
1376cdf0e10cSrcweir 					linear(Differenz zwischen alter und neuer Version)
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir 	[Querverweise]
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir 	<SfxItemPool::IsLoadingVersionCurrent()const>
1382cdf0e10cSrcweir 	<SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)>
1383cdf0e10cSrcweir 	<SfxItemPool::GetVersion()const>
1384cdf0e10cSrcweir 	<SfxItemPool::GetLoadingVersion()const>
1385cdf0e10cSrcweir */
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir 	// (Sekund"ar-) Pool bestimmen
1389cdf0e10cSrcweir 	if ( !IsInVersionsRange(nFileWhich) )
1390cdf0e10cSrcweir 	{
1391cdf0e10cSrcweir 		if ( pSecondary )
1392cdf0e10cSrcweir 			return pSecondary->GetNewWhich( nFileWhich );
1393cdf0e10cSrcweir 		SFX_ASSERT( 0, nFileWhich, "unknown which in GetNewWhich()" );
1394cdf0e10cSrcweir 	}
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir 	// Version neuer/gleich/"alter?
1397cdf0e10cSrcweir 	short nDiff = (short)pImp->nLoadingVersion - (short)pImp->nVersion;
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir 	// Which-Id einer neueren Version?
1400cdf0e10cSrcweir 	if ( nDiff > 0 )
1401cdf0e10cSrcweir 	{
1402cdf0e10cSrcweir 		// von der Top-Version bis runter zur File-Version stufenweise mappen
1403cdf0e10cSrcweir 		for ( size_t nMap = pImp->aVersions.size(); nMap > 0; --nMap )
1404cdf0e10cSrcweir 		{
1405cdf0e10cSrcweir 			SfxPoolVersion_ImplPtr pVerInfo = pImp->aVersions[nMap-1];
1406cdf0e10cSrcweir 			if ( pVerInfo->_nVer > pImp->nVersion )
1407cdf0e10cSrcweir 			{	sal_uInt16 nOfs;
1408cdf0e10cSrcweir 				sal_uInt16 nCount = pVerInfo->_nEnd - pVerInfo->_nStart + 1;
1409cdf0e10cSrcweir 				for ( nOfs = 0;
1410cdf0e10cSrcweir 					  nOfs <= nCount &&
1411cdf0e10cSrcweir 						pVerInfo->_pMap[nOfs] != nFileWhich;
1412cdf0e10cSrcweir 					  ++nOfs )
1413cdf0e10cSrcweir 					continue;
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 				if ( pVerInfo->_pMap[nOfs] == nFileWhich )
1416cdf0e10cSrcweir 					nFileWhich = pVerInfo->_nStart + nOfs;
1417cdf0e10cSrcweir 				else
1418cdf0e10cSrcweir 					return 0;
1419cdf0e10cSrcweir 			}
1420cdf0e10cSrcweir 			else
1421cdf0e10cSrcweir 				break;
1422cdf0e10cSrcweir 		}
1423cdf0e10cSrcweir 	}
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 	// Which-Id einer neueren Version?
1426cdf0e10cSrcweir 	else if ( nDiff < 0 )
1427cdf0e10cSrcweir 	{
1428cdf0e10cSrcweir 		// von der File-Version bis zur aktuellen Version stufenweise mappen
1429cdf0e10cSrcweir 		for ( size_t nMap = 0; nMap < pImp->aVersions.size(); ++nMap )
1430cdf0e10cSrcweir 		{
1431cdf0e10cSrcweir 			SfxPoolVersion_ImplPtr pVerInfo = pImp->aVersions[nMap];
1432cdf0e10cSrcweir 			if ( pVerInfo->_nVer > pImp->nLoadingVersion )
1433cdf0e10cSrcweir 			{
1434cdf0e10cSrcweir 				DBG_ASSERT( nFileWhich >= pVerInfo->_nStart &&
1435cdf0e10cSrcweir 							nFileWhich <= pVerInfo->_nEnd,
1436cdf0e10cSrcweir 							"which-id unknown in version" );
1437cdf0e10cSrcweir 				nFileWhich = pVerInfo->_pMap[nFileWhich - pVerInfo->_nStart];
1438cdf0e10cSrcweir 			}
1439cdf0e10cSrcweir 		}
1440cdf0e10cSrcweir 	}
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir 	// originale (nDiff==0) bzw. gemappte (nDiff!=0) Id zur"uckliefern
1443cdf0e10cSrcweir 	return nFileWhich;
1444cdf0e10cSrcweir }
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir // -----------------------------------------------------------------------
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir FASTBOOL SfxItemPool::IsInVersionsRange( sal_uInt16 nWhich ) const
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir 	return nWhich >= pImp->nVerStart && nWhich <= pImp->nVerEnd;
1452cdf0e10cSrcweir }
1453cdf0e10cSrcweir 
1454cdf0e10cSrcweir // -----------------------------------------------------------------------
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir FASTBOOL SfxItemPool::IsCurrentVersionLoading() const
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir /*	[Beschreibung]
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir 	Mit dieser Methode kann festgestellt werden, ob die geladene Pool-Version
1461cdf0e10cSrcweir 	dem aktuellen Pool-Aufbau entspricht.
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir 	Precondition:	Pool mu\s geladen sein
1464cdf0e10cSrcweir 	Postcondition:	unver"andert
1465cdf0e10cSrcweir 	Laufzeit:		linear(Anzahl der Sekund"arpools)
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 
1468cdf0e10cSrcweir 	[Querverweise]
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir 	<SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)>
1471cdf0e10cSrcweir 	<SfxItemPool::GetNewWhich(sal_uInt16)const>
1472cdf0e10cSrcweir 	<SfxItemPool::GetVersion()const>
1473cdf0e10cSrcweir 	<SfxItemPool::GetLoadingVersion()const>
1474cdf0e10cSrcweir */
1475cdf0e10cSrcweir 
1476cdf0e10cSrcweir {
1477cdf0e10cSrcweir 	return ( pImp->nVersion == pImp->nLoadingVersion ) &&
1478cdf0e10cSrcweir 		   ( !pSecondary || pSecondary->IsCurrentVersionLoading() );
1479cdf0e10cSrcweir }
1480cdf0e10cSrcweir 
1481cdf0e10cSrcweir // -----------------------------------------------------------------------
1482cdf0e10cSrcweir 
1483cdf0e10cSrcweir sal_uInt16 SfxItemPool::GetVersion() const
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir /*	[Beschreibung]
1486cdf0e10cSrcweir 
1487cdf0e10cSrcweir 	Diese Methode liefert die aktuelle Versionsnummer des SfxItemPool-Aufbaus
1488cdf0e10cSrcweir 	(also des Which-Bereichs).
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 	Precondition:	keine
1491cdf0e10cSrcweir 	Postcondition:	unver"andert
1492cdf0e10cSrcweir 	Laufzeit:       2
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir 	[Anmerkung]
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir 	Achtung: Es mu\s ggf. die Versionsnummer von Sekund"arpools
1498cdf0e10cSrcweir 	ber"ucksichtigt werden.
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir 	[Querverweise]
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir 	<SfxItemPool::IsLoadingVersionCurrent()const>
1504cdf0e10cSrcweir 	<SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)>
1505cdf0e10cSrcweir 	<SfxItemPool::GetNewWhich(sal_uInt16)const>
1506cdf0e10cSrcweir 	<SfxItemPool::GetLoadingVersion()const>
1507cdf0e10cSrcweir */
1508cdf0e10cSrcweir 
1509cdf0e10cSrcweir {
1510cdf0e10cSrcweir 	return pImp->nVersion;
1511cdf0e10cSrcweir }
1512cdf0e10cSrcweir 
1513cdf0e10cSrcweir // -----------------------------------------------------------------------
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir sal_uInt16 SfxItemPool::GetLoadingVersion() const
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir /*	[Beschreibung]
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir 	Diese Methode liefert die Versionsnummer des SfxItemPool-Aufbaus
1520cdf0e10cSrcweir 	(also des Which-Bereichs), die bei Laden vorgefunden wurde.
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 	Precondition:	Pool mu\s geladen sein
1523cdf0e10cSrcweir 	Postcondition:	unver"andert
1524cdf0e10cSrcweir 	Laufzeit:       2
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir 
1527cdf0e10cSrcweir 	[Anmerkung]
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir 	Achtung: Es mu\s ggf. die Versionsnummer von Sekund"arpools
1530cdf0e10cSrcweir 	ber"ucksichtigt werden.
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir 
1533cdf0e10cSrcweir 	[Querverweise]
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir 	<SfxItemPool::IsLoadingVersionCurrent()const>
1536cdf0e10cSrcweir 	<SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)>
1537cdf0e10cSrcweir 	<SfxItemPool::GetNewWhich(sal_uInt16)const>
1538cdf0e10cSrcweir 	<SfxItemPool::GetVersion()const>
1539cdf0e10cSrcweir */
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir {
1542cdf0e10cSrcweir 	return pImp->nLoadingVersion;
1543cdf0e10cSrcweir }
1544cdf0e10cSrcweir 
1545cdf0e10cSrcweir //-------------------------------------------------------------------------
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir FASTBOOL SfxItemPool::IsVer2_Impl() const
1548cdf0e10cSrcweir {
1549cdf0e10cSrcweir 	return pMaster->pImp->nMajorVer >= 2;
1550cdf0e10cSrcweir }
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir //-------------------------------------------------------------------------
1553cdf0e10cSrcweir 
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir FASTBOOL SfxItemPool::StoreItem( SvStream &rStream, const SfxPoolItem &rItem,
1556cdf0e10cSrcweir 								 FASTBOOL bDirect ) const
1557cdf0e10cSrcweir 
1558cdf0e10cSrcweir /*	[Beschreibung]
1559cdf0e10cSrcweir 
1560cdf0e10cSrcweir 	Speichert das <SfxPoolItem> 'rItem' in den <SvStream> 'rStream'
1561cdf0e10cSrcweir 	entweder als Surrogat ('bDirect == sal_False') oder direkt mit 'rItem.Store()'.
1562cdf0e10cSrcweir 	Nicht poolable Items werden immer direkt gespeichert. Items ohne Which-Id,
1563cdf0e10cSrcweir 	also SID-Items, werden nicht gespeichert, ebenso wenn Items, die in der
1564cdf0e10cSrcweir 	File-Format-Version noch nicht vorhanden waren (return sal_False).
1565cdf0e10cSrcweir 
1566cdf0e10cSrcweir 	Das Item wird im Stream wie folgt abgelegt:
1567cdf0e10cSrcweir 
1568cdf0e10cSrcweir 	sal_uInt16	rItem.Which()
1569cdf0e10cSrcweir 	sal_uInt16	GetSlotId( rItem.Which() ) bzw. 0 falls nicht verf"urbar
1570cdf0e10cSrcweir 	sal_uInt16	GetSurrogate( &rItem ) bzw. SFX_ITEM_DIRECT bei '!SFX_ITEM_POOLBLE'
1571cdf0e10cSrcweir 
1572cdf0e10cSrcweir 	optional (falls 'bDirect == sal_True' oder '!rItem.IsPoolable()':
1573cdf0e10cSrcweir 
1574cdf0e10cSrcweir 	sal_uInt16  rItem.GetVersion()
1575cdf0e10cSrcweir 	sal_uLong 	Size
1576cdf0e10cSrcweir 	Size    rItem.Store()
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir 	[Querverweise]
1580cdf0e10cSrcweir 
1581cdf0e10cSrcweir 	<SfxItemPool::LoadItem(SvStream&,FASTBOOL)const>
1582cdf0e10cSrcweir */
1583cdf0e10cSrcweir 
1584cdf0e10cSrcweir {
1585cdf0e10cSrcweir 	DBG_ASSERT( !IsInvalidItem(&rItem), "cannot store invalid items" );
1586cdf0e10cSrcweir 
1587cdf0e10cSrcweir 	if ( IsSlot( rItem.Which() ) )
1588cdf0e10cSrcweir 		return sal_False;
1589cdf0e10cSrcweir 	const SfxItemPool *pPool = this;
1590cdf0e10cSrcweir 	while ( !pPool->IsInStoringRange(rItem.Which()) )
1591cdf0e10cSrcweir 		if ( 0 == ( pPool = pPool->pSecondary ) )
1592cdf0e10cSrcweir 			return sal_False;
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir 	DBG_ASSERT( !pImp->bInSetItem || !rItem.ISA(SfxSetItem),
1595cdf0e10cSrcweir 				"SetItem contains ItemSet with SetItem" );
1596cdf0e10cSrcweir 
1597cdf0e10cSrcweir 	sal_uInt16 nSlotId = pPool->GetSlotId( rItem.Which(), sal_True );
1598cdf0e10cSrcweir 	sal_uInt16 nItemVersion = rItem.GetVersion(_nFileFormatVersion);
1599cdf0e10cSrcweir 	if ( USHRT_MAX == nItemVersion )
1600cdf0e10cSrcweir 		return sal_False;
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir 	rStream << rItem.Which() << nSlotId;
1603cdf0e10cSrcweir 	if ( bDirect || !pPool->StoreSurrogate( rStream, &rItem ) )
1604cdf0e10cSrcweir 	{
1605cdf0e10cSrcweir 		rStream << nItemVersion;
1606cdf0e10cSrcweir 		rStream << (sal_uInt32) 0L; 		  // Platz fuer Laenge in Bytes
1607cdf0e10cSrcweir 		sal_uLong nIStart = rStream.Tell();
1608cdf0e10cSrcweir 		rItem.Store(rStream, nItemVersion);
1609cdf0e10cSrcweir 		sal_uLong nIEnd = rStream.Tell();
1610cdf0e10cSrcweir 		rStream.Seek( nIStart-4 );
1611cdf0e10cSrcweir 		rStream << (sal_Int32) ( nIEnd-nIStart );
1612cdf0e10cSrcweir 		rStream.Seek( nIEnd );
1613cdf0e10cSrcweir 	}
1614cdf0e10cSrcweir 
1615cdf0e10cSrcweir 	return sal_True;
1616cdf0e10cSrcweir }
1617cdf0e10cSrcweir 
1618cdf0e10cSrcweir //-------------------------------------------------------------------------
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir const SfxPoolItem* SfxItemPool::LoadItem( SvStream &rStream, FASTBOOL bDirect,
1622cdf0e10cSrcweir 										  const SfxItemPool *pRefPool )
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir // pRefPool==-1 => nicht putten!
1625cdf0e10cSrcweir 
1626cdf0e10cSrcweir {
1627*6fb30688SEike Rathke 	sal_uInt16 nWhich(0), nSlot(0); // nSurrogate;
1628cdf0e10cSrcweir 	rStream >> nWhich >> nSlot;
1629cdf0e10cSrcweir 
1630cdf0e10cSrcweir 	sal_Bool bDontPut = (SfxItemPool*)-1 == pRefPool;
1631cdf0e10cSrcweir 	if ( bDontPut || !pRefPool )
1632cdf0e10cSrcweir 		pRefPool = this;
1633cdf0e10cSrcweir 
1634cdf0e10cSrcweir 	// richtigen Sekund"ar-Pool finden
1635cdf0e10cSrcweir 	while ( !pRefPool->IsInVersionsRange(nWhich) )
1636cdf0e10cSrcweir 	{
1637cdf0e10cSrcweir 		if ( pRefPool->pSecondary )
1638cdf0e10cSrcweir 			pRefPool = pRefPool->pSecondary;
1639cdf0e10cSrcweir 		else
1640cdf0e10cSrcweir 		{
1641cdf0e10cSrcweir 			// WID in der Version nicht vorhanden => ueberspringen
1642*6fb30688SEike Rathke 			sal_uInt32 nSurro(0);
1643*6fb30688SEike Rathke 			sal_uInt16 nVersion(0), nLen(0);
1644cdf0e10cSrcweir 			rStream >> nSurro;
1645cdf0e10cSrcweir 			if ( SFX_ITEMS_DIRECT == nSurro )
1646cdf0e10cSrcweir 			{
1647cdf0e10cSrcweir 				rStream >> nVersion >> nLen;
1648cdf0e10cSrcweir 				rStream.SeekRel( nLen );
1649cdf0e10cSrcweir 			}
1650cdf0e10cSrcweir 			return 0;
1651cdf0e10cSrcweir 		}
1652cdf0e10cSrcweir 	}
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir 	// wird eine andere Version geladen?
1655cdf0e10cSrcweir 	FASTBOOL bCurVersion = pRefPool->IsCurrentVersionLoading();
1656cdf0e10cSrcweir 	if ( !bCurVersion )
1657cdf0e10cSrcweir 		// Which-Id auf neue Version mappen
1658cdf0e10cSrcweir 		nWhich = pRefPool->GetNewWhich( nWhich );
1659cdf0e10cSrcweir 
1660cdf0e10cSrcweir 	DBG_ASSERT( !nWhich || !pImp->bInSetItem ||
1661cdf0e10cSrcweir 				!pRefPool->ppStaticDefaults[pRefPool->GetIndex_Impl(nWhich)]->ISA(SfxSetItem),
1662cdf0e10cSrcweir 				"loading SetItem in ItemSet of SetItem" );
1663cdf0e10cSrcweir 
1664cdf0e10cSrcweir 	// soll "uber Surrogat geladen werden?
1665cdf0e10cSrcweir 	const SfxPoolItem *pItem = 0;
1666cdf0e10cSrcweir 	if ( !bDirect )
1667cdf0e10cSrcweir 	{
1668cdf0e10cSrcweir 		// Which-Id in dieser Version bekannt?
1669cdf0e10cSrcweir 		if ( nWhich )
1670cdf0e10cSrcweir 			// Surrogat laden, reagieren falls keins vorhanden
1671cdf0e10cSrcweir 			pItem = LoadSurrogate( rStream, nWhich, nSlot, pRefPool );
1672cdf0e10cSrcweir 		else
1673cdf0e10cSrcweir 			// sonst "uberspringen
1674cdf0e10cSrcweir 			rStream.SeekRel( sizeof(sal_uInt16) );
1675cdf0e10cSrcweir 	}
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir 	// wird direkt, also nicht "uber Surrogat geladen?
1678cdf0e10cSrcweir 	if ( bDirect || ( nWhich && !pItem ) )
1679cdf0e10cSrcweir 	{
1680cdf0e10cSrcweir 		// bDirekt bzw. nicht IsPoolable() => Item direkt laden
1681*6fb30688SEike Rathke 		sal_uInt16 nVersion(0);
1682*6fb30688SEike Rathke 		sal_uInt32 nLen(0);
1683cdf0e10cSrcweir 		rStream >> nVersion >> nLen;
1684cdf0e10cSrcweir 		sal_uLong nIStart = rStream.Tell();
1685cdf0e10cSrcweir 
1686cdf0e10cSrcweir 		// Which-Id in dieser Version bekannt?
1687cdf0e10cSrcweir 		if ( nWhich )
1688cdf0e10cSrcweir 		{
1689cdf0e10cSrcweir 			// Item direkt laden
1690cdf0e10cSrcweir 			SfxPoolItem *pNewItem =
1691cdf0e10cSrcweir 					pRefPool->GetDefaultItem(nWhich).Create(rStream, nVersion);
1692cdf0e10cSrcweir 			if ( bDontPut )
1693cdf0e10cSrcweir 				pItem = pNewItem;
1694cdf0e10cSrcweir 			else
1695cdf0e10cSrcweir 				if ( pNewItem )
1696cdf0e10cSrcweir 				{
1697cdf0e10cSrcweir 					pItem = &Put(*pNewItem);
1698cdf0e10cSrcweir 					delete pNewItem;
1699cdf0e10cSrcweir 				}
1700cdf0e10cSrcweir 				else
1701cdf0e10cSrcweir 					pItem = 0;
1702cdf0e10cSrcweir 			sal_uLong nIEnd = rStream.Tell();
1703cdf0e10cSrcweir 			DBG_ASSERT( nIEnd <= (nIStart+nLen), "read past end of item" );
1704cdf0e10cSrcweir 			if ( (nIStart+nLen) != nIEnd )
1705cdf0e10cSrcweir 				rStream.Seek( nIStart+nLen );
1706cdf0e10cSrcweir 		}
1707cdf0e10cSrcweir 		else
1708cdf0e10cSrcweir 			// Item "uberspringen
1709cdf0e10cSrcweir 			rStream.Seek( nIStart+nLen );
1710cdf0e10cSrcweir 	}
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir 	return pItem;
1713cdf0e10cSrcweir }
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir 
1716