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