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

Generated by: LCOV version 1.10