LCOV - code coverage report
Current view: top level - svl/source/items - poolio.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 121 591 20.5 %
Date: 2014-04-11 Functions: 12 23 52.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10