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