LCOV - code coverage report
Current view: top level - svl/source/items - poolio.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 124 623 19.9 %
Date: 2014-11-03 Functions: 13 29 44.8 %
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/SfxBroadcaster.hxx>
      29             : #include <svl/filerec.hxx>
      30             : #include "poolio.hxx"
      31             : #include <boost/scoped_ptr.hpp>
      32             : #include <boost/scoped_array.hpp>
      33             : 
      34             : /**
      35             :  * Returns the <SfxItemPool> that is being saved.
      36             :  * This should only be used in very exceptional cases e.g.
      37             :  * when guaranteeing file format compatibility:
      38             :  * When overloading a <SfxPoolItem::Store()> getting additional data from the Pool
      39             :  */
      40           0 : const SfxItemPool* SfxItemPool::GetStoringPool()
      41             : {
      42           0 :     return pStoringPool_;
      43             : }
      44             : 
      45           0 : static sal_uInt16 convertSfxItemKindToUInt16(SfxItemKind x)
      46             : {
      47           0 :     if ( x == SFX_ITEMS_NONE )
      48           0 :         return 0;
      49           0 :     if ( x == SFX_ITEMS_DELETEONIDLE )
      50           0 :         return 0xfffd;
      51           0 :     if ( x == SFX_ITEMS_STATICDEFAULT )
      52           0 :         return 0xfffe;
      53           0 :     if ( x == SFX_ITEMS_POOLDEFAULT )
      54           0 :         return 0xffff;
      55             :     assert(false);
      56           0 :     abort();
      57             : }
      58             : 
      59           0 : static SfxItemKind convertUInt16ToSfxItemKind(sal_uInt16 x)
      60             : {
      61           0 :     if ( x == 0 )
      62           0 :         return SFX_ITEMS_NONE;
      63           0 :     if ( x == 0xfffd )
      64           0 :         return SFX_ITEMS_DELETEONIDLE;
      65           0 :     if ( x == 0xfffe )
      66           0 :         return SFX_ITEMS_STATICDEFAULT;
      67           0 :     if ( x == 0xffff )
      68           0 :         return SFX_ITEMS_POOLDEFAULT;
      69             :     assert(false);
      70           0 :     abort();
      71             : }
      72             : 
      73             : 
      74             : 
      75             : /**
      76             :  * The SfxItemPool is saved to the specified Stream (together with all its
      77             :  * secondary Pools) using its Pool Defaults and pooled Items.
      78             :  * The static defaults are not saved.
      79             :  * [Fileformat]
      80             :  *
      81             :  *  ;First, a compatibility header section
      82             :  *    Start:      0x1111  SFX_ITEMPOOL_TAG_STARTPOOLS(_4/_5)
      83             :  *                sal_uInt8   MAJOR_VER                   ;SfxItemPool version
      84             :  *               sal_uInt8   MINOR_VER                   ;"
      85             :  *               0xFFFF  SFX_ITEMPOOL_TAG_TRICK4OLD      ;ex. GetVersion()
      86             :  *               sal_uInt16  0x0000                      ;Pseudo StyleSheetPool
      87             :  *               sal_uInt16  0x0000                      ;Pseudo StyleSheetPool
      88             :  *
      89             :  *   ;The whole Pool into a record
      90             :  *              record  SfxMiniRecod(SFX_ITEMPOOL_REC)
      91             :  *
      92             :  *   ;Start with a Header for each
      93             :  *   Header:     record      SfxMiniRecord(SFX_ITEMPOOL_REC_HEADER)
      94             :  *               sal_uInt16          GetVersion()        ;Which-Ranges etc.
      95             :  *               String          GetName()               ;Pool name
      96             :  *
      97             :  *  ;The version map: in order to be able to map WhichIds of new file version
      98             :  *    Versions:   record      SfxMultiRecord(SFX_ITEMPOOL_REC_VERSIONS, 0)
      99             :  *               sal_uInt16          OldVersion
     100             :  *               sal_uInt16          OldStartWhich
     101             :  *               sal_uInt16          OldEndWhich
     102             :  *               sal_uInt16[]        NewWhich (OldEndWhich-OldStartWhich+1)
     103             :  *
     104             :  *   ;Now the pooled Items (first the non-SfxSetItems)
     105             :  *   Items:      record      SfxMultiRecord(SFX_ITEMPOOL_REC_WHICHIDS, 0)
     106             :  *                content         SlotId, 0
     107             :  *               sal_uInt16          WhichId
     108             :  *               sal_uInt16          pItem->GetVersion()
     109             :  *               sal_uInt16          Array-Size
     110             :  *               record          SfxMultiRecord(SFX_, 0)
     111             :  *               content             Surrogate
     112             :  *               sal_uInt16              RefCount
     113             :  *               unknown             pItem->Store()
     114             :  *
     115             :  *   ;Now the set Pool defaults
     116             :  *   Defaults:   record      SfxMultiRecord(SFX_ITEMPOOL_REC_DEFAULTS, 0)
     117             :  *               content         SlotId, 0
     118             :  *               sal_uInt16          WhichId
     119             :  *               sal_uInt16          pPoolDef->GetVersion()
     120             :  *               unknown         pPoolDef->Store();
     121             :  *
     122             :  *   ;Hereafter the secondary follows (if present) without compatibility header section
     123             :  */
     124       10704 : SvStream &SfxItemPool::Store(SvStream &rStream) const
     125             : {
     126             :     // Find StoreMaster
     127       10704 :     SfxItemPool *pStoreMaster = pImp->mpMaster != this ? pImp->mpMaster : 0;
     128       21408 :     while ( pStoreMaster && !pStoreMaster->pImp->bStreaming )
     129           0 :         pStoreMaster = pStoreMaster->pImp->mpSecondary;
     130             : 
     131             :     // Old header (version of the Pool and content version is 0xffff by default)
     132       10704 :     pImp->bStreaming = true;
     133       10704 :     if ( !pStoreMaster )
     134             :     {
     135       10704 :         rStream.WriteUInt16(  rStream.GetVersion() >= SOFFICE_FILEFORMAT_50
     136             :                 ? SFX_ITEMPOOL_TAG_STARTPOOL_5
     137       10704 :                 : SFX_ITEMPOOL_TAG_STARTPOOL_4  );
     138       10704 :         rStream.WriteUInt8( SFX_ITEMPOOL_VER_MAJOR ).WriteUInt8( SFX_ITEMPOOL_VER_MINOR );
     139       10704 :         rStream.WriteUInt16( SFX_ITEMPOOL_TAG_TRICK4OLD );
     140             : 
     141             :         // Work around SfxStyleSheet bug
     142       10704 :         rStream.WriteUInt16( 0 ); // Version
     143       10704 :         rStream.WriteUInt16( 0 ); // Count (or else 2nd loop breaks)
     144             :     }
     145             : 
     146             :     // Every Pool as a whole is a record
     147       10704 :     SfxMiniRecordWriter aPoolRec( &rStream, SFX_ITEMPOOL_REC );
     148       10704 :     pStoringPool_ = this;
     149             : 
     150             :     // Single header (content version and name)
     151             :     {
     152       10704 :         SfxMiniRecordWriter aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER);
     153       10704 :         rStream.WriteUInt16( pImp->nVersion );
     154       10704 :         writeByteString(rStream, pImp->aName);
     155             :     }
     156             : 
     157             :     // VersionMaps
     158             :     {
     159       10704 :         SfxMultiVarRecordWriter aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP, 0 );
     160       74928 :         for ( size_t nVerNo = 0; nVerNo < pImp->aVersions.size(); ++nVerNo )
     161             :         {
     162       64224 :             aVerRec.NewContent();
     163       64224 :             SfxPoolVersion_ImplPtr pVer = pImp->aVersions[nVerNo];
     164       64224 :             rStream.WriteUInt16( pVer->_nVer ).WriteUInt16( pVer->_nStart ).WriteUInt16( pVer->_nEnd );
     165       64224 :             sal_uInt16 nCount = pVer->_nEnd - pVer->_nStart + 1;
     166       64224 :             sal_uInt16 nNewWhich = 0;
     167     1990944 :             for ( sal_uInt16 n = 0; n < nCount; ++n )
     168             :             {
     169     1926720 :                 nNewWhich = pVer->_pMap[n];
     170     1926720 :                 rStream.WriteUInt16( nNewWhich );
     171             :             }
     172             : 
     173             :             // Workaround for bug in SetVersionMap 312
     174       64224 :             if ( SOFFICE_FILEFORMAT_31 == pImp->mnFileFormatVersion )
     175           0 :                 rStream.WriteUInt16( nNewWhich+1 );
     176       74928 :         }
     177             :     }
     178             : 
     179             :     // Pooled Items
     180             :     {
     181       10704 :         SfxMultiMixRecordWriter aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS, 0 );
     182             : 
     183             :         // First write the atomic Items and then write the Sets (important when loading)
     184       32112 :         for (int ft = 0 ; ft < 2 && !rStream.GetError(); ft++)
     185             :         {
     186       21408 :             pImp->bInSetItem = ft != 0;
     187             : 
     188       21408 :             std::vector<SfxPoolItemArray_Impl*>::iterator itrArr = pImp->maPoolItems.begin();
     189       21408 :             SfxPoolItem **ppDefItem = pImp->ppStaticDefaults;
     190       21408 :             const sal_uInt16 nSize = GetSize_Impl();
     191     1198848 :             for ( size_t i = 0; i < nSize && !rStream.GetError(); ++i, ++itrArr, ++ppDefItem )
     192             :             {
     193             :                 // Get version of the Item
     194     1177440 :                 sal_uInt16 nItemVersion = (*ppDefItem)->GetVersion( pImp->mnFileFormatVersion );
     195     1177440 :                 if ( USHRT_MAX == nItemVersion )
     196             :                     // => Was not present in the version that was supposed to be exported
     197       42816 :                     continue;
     198             : 
     199             :                 // ! Poolable is not even saved in the Pool
     200             :                 // And itemsets/plain-items depending on the round
     201     1171160 :                 if ( *itrArr && IsItemFlag(**ppDefItem, SFX_ITEM_POOLABLE) &&
     202       36536 :                      pImp->bInSetItem == (bool) (*ppDefItem)->ISA(SfxSetItem) )
     203             :                 {
     204             :                     // Own signature, global WhichId and ItemVersion
     205       18268 :                     sal_uInt16 nSlotId = GetSlotId( (*ppDefItem)->Which(), false );
     206       18268 :                     aWhichIdsRec.NewContent(nSlotId, 0);
     207       18268 :                     rStream.WriteUInt16( (*ppDefItem)->Which() );
     208       18268 :                     rStream.WriteUInt16( nItemVersion );
     209       18268 :                     const sal_uInt32 nCount = ::std::min<size_t>( (*itrArr)->size(), SAL_MAX_UINT32 );
     210             :                     DBG_ASSERT(nCount, "ItemArr is empty");
     211       18268 :                     rStream.WriteUInt32( nCount );
     212             : 
     213             :                     // Write Items
     214       18268 :                     SfxMultiMixRecordWriter aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS, 0 );
     215       38352 :                     for ( size_t j = 0; j < nCount; ++j )
     216             :                     {
     217             :                         // Get Item
     218       20084 :                         const SfxPoolItem *pItem = (*itrArr)->operator[](j);
     219       20084 :                         if ( pItem && pItem->GetRefCount() ) //! See other MI-REF
     220             :                         {
     221       20084 :                             aItemsRec.NewContent((sal_uInt16)j, 'X' );
     222             : 
     223       20084 :                             if ( pItem->GetRefCount() == SFX_ITEMS_SPECIAL )
     224           0 :                                 rStream.WriteUInt16( convertSfxItemKindToUInt16(pItem->GetKind()) );
     225             :                             else
     226             :                             {
     227       20084 :                                 rStream.WriteUInt16( pItem->GetRefCount() );
     228       20084 :                                 if( pItem->GetRefCount() > SFX_ITEMS_OLD_MAXREF )
     229           0 :                                     rStream.SetError( ERRCODE_IO_NOTSTORABLEINBINARYFORMAT );
     230             :                             }
     231             : 
     232       20084 :                             if ( !rStream.GetError() )
     233       20084 :                                 pItem->Store(rStream, nItemVersion);
     234             :                             else
     235           0 :                                 break;
     236             : #ifdef DBG_UTIL_MI
     237             :                             if ( !pItem->ISA(SfxSetItem) )
     238             :                             {
     239             :                                 sal_uLong nMark = rStream.Tell();
     240             :                                 rStream.Seek( nItemStartPos + sizeof(sal_uInt16) );
     241             :                                 boost::scoped_ptr<SfxPoolItem> pClone(pItem->Create(rStream, nItemVersion ));
     242             :                                 sal_uInt16 nWh = pItem->Which();
     243             :                                 SFX_ASSERT( rStream.Tell() == nMark, nWh,"asymmetric store/create" );
     244             :                                 SFX_ASSERT( *pClone == *pItem, nWh, "unequal after store/create" );
     245             :                             }
     246             : #endif
     247             :                         }
     248       18268 :                     }
     249             :                 }
     250             :             }
     251             :         }
     252             : 
     253       10704 :         pImp->bInSetItem = false;
     254             :     }
     255             : 
     256             :     // Save the set Defaults (PoolDefaults)
     257       10704 :     if ( !rStream.GetError() )
     258             :     {
     259       10704 :         SfxMultiMixRecordWriter aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS, 0 );
     260       10704 :         sal_uInt16 nCount = GetSize_Impl();
     261      599424 :         for ( sal_uInt16 n = 0; n < nCount; ++n )
     262             :         {
     263      588720 :             const SfxPoolItem* pDefaultItem = pImp->ppPoolDefaults[n];
     264      588720 :             if ( pDefaultItem )
     265             :             {
     266             :                 // Get version
     267           0 :                 sal_uInt16 nItemVersion = pDefaultItem->GetVersion( pImp->mnFileFormatVersion );
     268           0 :                 if ( USHRT_MAX == nItemVersion )
     269             :                     // => Was not present in the version yet
     270           0 :                     continue;
     271             : 
     272             :                 // Own signature, global signature, version
     273           0 :                 sal_uInt16 nSlotId = GetSlotId( pDefaultItem->Which(), false );
     274           0 :                 aDefsRec.NewContent( nSlotId, 0 );
     275           0 :                 rStream.WriteUInt16( pDefaultItem->Which() );
     276           0 :                 rStream.WriteUInt16( nItemVersion );
     277             : 
     278             :                 // Item
     279           0 :                 pDefaultItem->Store( rStream, nItemVersion );
     280             :             }
     281       10704 :         }
     282             :     }
     283             : 
     284             :     // Write out additional Pools
     285       10704 :     pStoringPool_ = 0;
     286       10704 :     aPoolRec.Close();
     287       10704 :     if ( !rStream.GetError() && pImp->mpSecondary )
     288           0 :         pImp->mpSecondary->Store( rStream );
     289             : 
     290       10704 :     pImp->bStreaming = false;
     291       10704 :     return rStream;
     292             : }
     293             : 
     294           0 : bool SfxItemPool::HasPersistentRefCounts() const
     295             : {
     296           0 :     return pImp->mbPersistentRefCounts;
     297             : }
     298             : 
     299             : /**
     300             :  * If the SfxItemPool was loaded with 'bRefCounts' == sal_False, we need
     301             :  * to finish the loading of the document contents with a call of this method.
     302             :  * In any other case calling this function has no meaning.
     303             :  *
     304             :  * When loading without RefCounts, they are actually set to 1 so that
     305             :  * SfxPoolItems that are needed during and after loading are not deleted.
     306             :  * This method resets the RefCount and also removes all items that are not
     307             :  * needed anymore.
     308             :  *
     309             :  * @see SfxItemPool::Load()
     310             : */
     311           0 : void SfxItemPool::LoadCompleted()
     312             : {
     313             :     // Did we load without RefCounts?
     314           0 :     if ( pImp->nInitRefCount > 1 )
     315             :     {
     316             :         // Iterate over all Which values
     317           0 :         std::vector<SfxPoolItemArray_Impl*>::iterator itrItemArr = pImp->maPoolItems.begin();
     318           0 :         for( sal_uInt16 nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++itrItemArr )
     319             :         {
     320             :             // Is there an item with the Which value present at all?
     321           0 :             if ( *itrItemArr )
     322             :             {
     323             :                 // Iterate over all items with this WhichId
     324           0 :                 SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
     325           0 :                 for( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
     326             :                 {
     327           0 :                     if (*ppHtArr)
     328             :                     {
     329           0 :                         if ( !ReleaseRef( **ppHtArr, 1 ) )
     330           0 :                             DELETEZ( *ppHtArr );
     331             :                     }
     332             :                 }
     333           0 :                 (*itrItemArr)->ReHash();
     334             :             }
     335             :         }
     336             : 
     337             :         // from now on normal initial ref count
     338           0 :         pImp->nInitRefCount = 1;
     339             :     }
     340             : 
     341             :     // notify secondary pool
     342           0 :     if ( pImp->mpSecondary )
     343           0 :         pImp->mpSecondary->LoadCompleted();
     344           0 : }
     345             : 
     346       38767 : sal_uInt16 SfxItemPool::GetFirstWhich() const
     347             : {
     348       38767 :     return pImp->mnStart;
     349             : }
     350             : 
     351     1876735 : sal_uInt16 SfxItemPool::GetLastWhich() const
     352             : {
     353     1876735 :     return pImp->mnEnd;
     354             : }
     355             : 
     356   239519760 : bool SfxItemPool::IsInRange( sal_uInt16 nWhich ) const
     357             : {
     358   239519760 :     return nWhich >= pImp->mnStart && nWhich <= pImp->mnEnd;
     359             : }
     360             : 
     361             : // This had to be moved to a method of its own to keep Solaris GCC happy:
     362           0 : void SfxItemPool_Impl::readTheItems (
     363             :     SvStream & rStream, sal_uInt32 nItemCount, sal_uInt16 nVer,
     364             :     SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** ppArr)
     365             : {
     366           0 :     SfxMultiRecordReader aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS );
     367             : 
     368           0 :     SfxPoolItemArray_Impl *pNewArr = new SfxPoolItemArray_Impl();
     369           0 :     SfxPoolItem *pItem = 0;
     370             : 
     371           0 :     sal_uLong n, nLastSurrogate = sal_uLong(-1);
     372           0 :     while (aItemsRec.GetContent())
     373             :     {
     374             :         // Get next surrogate
     375           0 :         sal_uInt16 nSurrogate = aItemsRec.GetContentTag();
     376             :         DBG_ASSERT( aItemsRec.GetContentVersion() == 'X',
     377             :                     "not an item content" );
     378             : 
     379             :         // Fill up missing ones
     380           0 :         for ( pItem = 0, n = nLastSurrogate+1; n < nSurrogate; ++n )
     381           0 :             pNewArr->push_back( (SfxPoolItem*) pItem );
     382           0 :         nLastSurrogate = nSurrogate;
     383             : 
     384             :         // Load RefCount and Item
     385           0 :         sal_uInt16 nRef(0);
     386           0 :         rStream.ReadUInt16( nRef );
     387             : 
     388           0 :         pItem = pDefItem->Create(rStream, nVer);
     389           0 :         pNewArr->push_back( (SfxPoolItem*) pItem );
     390             : 
     391           0 :         if ( !mbPersistentRefCounts )
     392             :             // Hold onto it until SfxItemPool::LoadCompleted()
     393           0 :             SfxItemPool::AddRef(*pItem, 1);
     394             :         else
     395             :         {
     396           0 :             if ( nRef > SFX_ITEMS_OLD_MAXREF )
     397           0 :                 SfxItemPool::SetKind(*pItem, convertUInt16ToSfxItemKind(nRef));
     398             :             else
     399           0 :                 SfxItemPool::AddRef(*pItem, nRef);
     400             :         }
     401             :     }
     402             : 
     403             :     // Fill up missing ones
     404           0 :     for ( pItem = 0, n = nLastSurrogate+1; n < nItemCount; ++n )
     405           0 :         pNewArr->push_back( (SfxPoolItem*) pItem );
     406             : 
     407           0 :     SfxPoolItemArray_Impl *pOldArr = *ppArr;
     408           0 :     *ppArr = pNewArr;
     409             : 
     410             :     // Remember items that are already in the pool
     411           0 :     bool bEmpty = true;
     412           0 :     if ( 0 != pOldArr )
     413           0 :         for ( n = 0; bEmpty && n < pOldArr->size(); ++n )
     414           0 :             bEmpty = pOldArr->operator[](n) == 0;
     415             :     DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" );
     416           0 :     if ( !bEmpty )
     417             :     {
     418             :         // See if there's a new one for all old ones
     419           0 :         for ( size_t nOld = 0; nOld < pOldArr->size(); ++nOld )
     420             :         {
     421           0 :             SfxPoolItem *pOldItem = (*pOldArr)[nOld];
     422           0 :             if ( pOldItem )
     423             :             {
     424           0 :                 sal_uInt32 nFree = SAL_MAX_UINT32;
     425           0 :                 bool bFound = false;
     426           0 :                 for ( size_t nNew = (*ppArr)->size(); nNew--; )
     427             :                 {
     428             :                     // Loaded Item
     429             :                     SfxPoolItem *&rpNewItem =
     430           0 :                         (SfxPoolItem*&)(*ppArr)->operator[](nNew);
     431             : 
     432             :                     // Unused surrogate?
     433           0 :                     if ( !rpNewItem )
     434           0 :                         nFree = nNew;
     435             : 
     436             :                     // Found it?
     437           0 :                     else if ( *rpNewItem == *pOldItem )
     438             :                     {
     439             :                         // Reuse
     440           0 :                         SfxItemPool::AddRef( *pOldItem, rpNewItem->GetRefCount() );
     441           0 :                         SfxItemPool::SetRefCount( *rpNewItem, 0 );
     442           0 :                         delete rpNewItem;
     443           0 :                         rpNewItem = pOldItem;
     444           0 :                         bFound = true;
     445           0 :                         break;
     446             :                     }
     447             :                 }
     448             : 
     449             :                 // Take over the ones that were previously present, but had not been loaded
     450           0 :                 if ( !bFound )
     451             :                 {
     452           0 :                     if ( nFree != SAL_MAX_UINT32 )
     453           0 :                         (SfxPoolItem*&)(*ppArr)->operator[](nFree) = pOldItem;
     454             :                     else
     455           0 :                         (*ppArr)->push_back( (SfxPoolItem*) pOldItem );
     456             :                 }
     457             :             }
     458             :         }
     459             :     }
     460           0 :     delete pOldArr;
     461             : 
     462           0 :     (*ppArr)->ReHash(); // paranoid
     463           0 : }
     464             : 
     465           0 : SvStream &SfxItemPool::Load(SvStream &rStream)
     466             : {
     467             :     DBG_ASSERT(pImp->ppStaticDefaults, "No DefaultArray");
     468             : 
     469             :     // Protect items by increasing ref count
     470           0 :     if ( !pImp->mbPersistentRefCounts )
     471             :     {
     472             : 
     473             :         // Iterate over all Which values
     474           0 :         std::vector<SfxPoolItemArray_Impl*>::iterator itrItemArr = pImp->maPoolItems.begin();
     475           0 :         for( size_t nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++itrItemArr )
     476             :         {
     477             :             // Is there an Item with that Which value present at all?
     478           0 :             if ( *itrItemArr )
     479             :             {
     480           0 :                 SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
     481           0 :                 for( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
     482           0 :                     if (*ppHtArr)
     483             :                     {
     484             :                         DBG_WARNING( "loading non-empty ItemPool" );
     485             : 
     486           0 :                         AddRef( **ppHtArr, 1 );
     487             :                     }
     488             :             }
     489             :         }
     490             : 
     491             :         // During loading (until LoadCompleted()) protect all items
     492           0 :         pImp->nInitRefCount = 2;
     493             :     }
     494             : 
     495             :     // Find LoadMaster
     496           0 :     SfxItemPool *pLoadMaster = pImp->mpMaster != this ? pImp->mpMaster : 0;
     497           0 :     while ( pLoadMaster && !pLoadMaster->pImp->bStreaming )
     498           0 :         pLoadMaster = pLoadMaster->pImp->mpSecondary;
     499             : 
     500             :     // Read whole Header
     501           0 :     pImp->bStreaming = true;
     502           0 :     if ( !pLoadMaster )
     503             :     {
     504             :         // Load format version
     505           0 :         CHECK_FILEFORMAT2( rStream,
     506             :                 SFX_ITEMPOOL_TAG_STARTPOOL_5, SFX_ITEMPOOL_TAG_STARTPOOL_4 );
     507           0 :         rStream.ReadUChar( pImp->nMajorVer ).ReadUChar( pImp->nMinorVer );
     508             : 
     509             :         // Take over format version to MasterPool
     510           0 :         pImp->mpMaster->pImp->nMajorVer = pImp->nMajorVer;
     511           0 :         pImp->mpMaster->pImp->nMinorVer = pImp->nMinorVer;
     512             : 
     513             :         // Old Format?
     514           0 :         if ( pImp->nMajorVer < 2 )
     515             :             // pImp->bStreaming is reset by Load1_Impl()
     516           0 :             return Load1_Impl( rStream );
     517             : 
     518             :         // New Format?
     519           0 :         if ( pImp->nMajorVer > SFX_ITEMPOOL_VER_MAJOR )
     520             :         {
     521           0 :             rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
     522           0 :             pImp->bStreaming = false;
     523           0 :             return rStream;
     524             :         }
     525             : 
     526             :         // Trick for version 1.2: skip data
     527           0 :         CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_TRICK4OLD );
     528           0 :         rStream.SeekRel( 4 ); // Hack: Skip data due to SfxStyleSheetPool bug
     529             :     }
     530             : 
     531             :     // New record-oriented format
     532           0 :     SfxMiniRecordReader aPoolRec( &rStream, SFX_ITEMPOOL_REC );
     533           0 :     if ( rStream.GetError() )
     534             :     {
     535           0 :         pImp->bStreaming = false;
     536           0 :         return rStream;
     537             :     }
     538             : 
     539             :     // Single header
     540           0 :     OUString aExternName;
     541             :     {
     542             :         // Find HeaderRecord
     543           0 :         SfxMiniRecordReader aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER );
     544           0 :         if ( rStream.GetError() )
     545             :         {
     546           0 :             pImp->bStreaming = false;
     547           0 :             return rStream;
     548             :         }
     549             : 
     550             :         // Read Header
     551           0 :         rStream.ReadUInt16( pImp->nLoadingVersion );
     552           0 :         aExternName = readByteString(rStream);
     553           0 :         bool bOwnPool = aExternName == pImp->aName;
     554             : 
     555             :         //! As long as we cannot read foreign Pools
     556           0 :         if ( !bOwnPool )
     557             :         {
     558           0 :             rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
     559           0 :             aPoolRec.Skip();
     560           0 :             pImp->bStreaming = false;
     561           0 :             return rStream;
     562           0 :         }
     563             :     }
     564             : 
     565             :     // Version maps
     566             :     {
     567           0 :         SfxMultiRecordReader aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP );
     568           0 :         if ( rStream.GetError() )
     569             :         {
     570           0 :             pImp->bStreaming = false;
     571           0 :             return rStream;
     572             :         }
     573             : 
     574             :         // Version maps einlesen
     575           0 :         sal_uInt16 nOwnVersion = pImp->nVersion;
     576           0 :         for ( sal_uInt16 nVerNo = 0; aVerRec.GetContent(); ++nVerNo )
     577             :         {
     578             :             // Read header for single versions
     579           0 :             sal_uInt16 nVersion(0), nHStart(0), nHEnd(0);
     580           0 :             rStream.ReadUInt16( nVersion ).ReadUInt16( nHStart ).ReadUInt16( nHEnd );
     581           0 :             sal_uInt16 nCount = nHEnd - nHStart + 1;
     582             : 
     583             :             // Is new version is known?
     584           0 :             if ( nVerNo >= pImp->aVersions.size() )
     585             :             {
     586             :                 // Add new Version
     587           0 :                 sal_uInt16 *pMap = new sal_uInt16[nCount];
     588           0 :                 memset(pMap, 0, nCount * sizeof(sal_uInt16));
     589           0 :                 for ( sal_uInt16 n = 0; n < nCount; ++n )
     590           0 :                     rStream.ReadUInt16( pMap[n] );
     591           0 :                 SetVersionMap( nVersion, nHStart, nHEnd, pMap );
     592             :             }
     593             :         }
     594           0 :         pImp->nVersion = nOwnVersion;
     595             :     }
     596             : 
     597             :     // Load Items
     598           0 :     bool bSecondaryLoaded = false;
     599           0 :     long nSecondaryEnd = 0;
     600             :     {
     601           0 :         SfxMultiRecordReader aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS);
     602           0 :         while ( aWhichIdsRec.GetContent() )
     603             :         {
     604             :             // Get SlotId, WhichId and Item version
     605           0 :             sal_uInt32 nCount(0);
     606           0 :             sal_uInt16 nVersion(0), nWhich(0);
     607             :             //!sal_uInt16 nSlotId = aWhichIdsRec.GetContentTag();
     608           0 :             rStream.ReadUInt16( nWhich );
     609           0 :             if ( pImp->nLoadingVersion != pImp->nVersion )
     610             :                 // Move WhichId from file version to Pool version
     611           0 :                 nWhich = GetNewWhich( nWhich );
     612             : 
     613             :             // Unknown Item from newer version
     614           0 :             if ( !IsInRange(nWhich) )
     615           0 :                 continue;
     616             : 
     617           0 :             rStream.ReadUInt16( nVersion );
     618           0 :             rStream.ReadUInt32( nCount );
     619             :             //!SFX_ASSERTWARNING( !nSlotId || !HasMap() ||
     620             :             //!         ( nSlotId == GetSlotId( nWhich, sal_False ) ) ||
     621             :             //!         !GetSlotId( nWhich, sal_False ),
     622             :             //!         nWhich, "Slot/Which mismatch" );
     623             : 
     624           0 :             sal_uInt16 nIndex = GetIndex_Impl(nWhich);
     625           0 :             SfxPoolItemArray_Impl **ppArr = &pImp->maPoolItems[0] + nIndex;
     626             : 
     627             :             // SfxSetItems could contain Items from secondary Pools
     628           0 :             SfxPoolItem *pDefItem = *(pImp->ppStaticDefaults + nIndex);
     629           0 :             pImp->bInSetItem = pDefItem->ISA(SfxSetItem);
     630           0 :             if ( !bSecondaryLoaded && pImp->mpSecondary && pImp->bInSetItem )
     631             :             {
     632             :                 // Seek to end of own Pool
     633           0 :                 sal_uLong nLastPos = rStream.Tell();
     634           0 :                 aPoolRec.Skip();
     635             : 
     636             :                 // Read secondary Pool
     637           0 :                 pImp->mpSecondary->Load( rStream );
     638           0 :                 bSecondaryLoaded = true;
     639           0 :                 nSecondaryEnd = rStream.Tell();
     640             : 
     641             :                 // Back to our own Items
     642           0 :                 rStream.Seek(nLastPos);
     643             :             }
     644             : 
     645             :             // Read Items
     646           0 :             pImp->readTheItems(rStream, nCount, nVersion, pDefItem, ppArr);
     647             : 
     648           0 :             pImp->bInSetItem = false;
     649           0 :         }
     650             :     }
     651             : 
     652             :     // Read Pool defaults
     653             :     {
     654           0 :         SfxMultiRecordReader aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS );
     655             : 
     656           0 :         while ( aDefsRec.GetContent() )
     657             :         {
     658             :             // Get SlotId, WhichId and Item versions
     659           0 :             sal_uInt16 nVersion(0), nWhich(0);
     660             :             //!sal_uInt16 nSlotId = aDefsRec.GetContentTag();
     661           0 :             rStream.ReadUInt16( nWhich );
     662           0 :             if ( pImp->nLoadingVersion != pImp->nVersion )
     663             :                 // Move WhichId from file version to Pool version
     664           0 :                 nWhich = GetNewWhich( nWhich );
     665             : 
     666             :             // Unknown Item from newer version
     667           0 :             if ( !IsInRange(nWhich) )
     668           0 :                 continue;
     669             : 
     670           0 :             rStream.ReadUInt16( nVersion );
     671             :             //!SFX_ASSERTWARNING( !HasMap() || ( nSlotId == GetSlotId( nWhich, sal_False ) ),
     672             :             //!         nWhich, "Slot/Which mismatch" );
     673             : 
     674             :             // Load PoolDefaultItem
     675             :             SfxPoolItem *pItem =
     676           0 :                     ( *( pImp->ppStaticDefaults + GetIndex_Impl(nWhich) ) )
     677           0 :                     ->Create( rStream, nVersion );
     678           0 :             pItem->SetKind( SFX_ITEMS_POOLDEFAULT );
     679           0 :             *( pImp->ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem;
     680           0 :         }
     681             :     }
     682             : 
     683             :     // Load secondary Pool if needed
     684           0 :     aPoolRec.Skip();
     685           0 :     if ( pImp->mpSecondary )
     686             :     {
     687           0 :         if ( !bSecondaryLoaded )
     688           0 :             pImp->mpSecondary->Load( rStream );
     689             :         else
     690           0 :             rStream.Seek( nSecondaryEnd );
     691             :     }
     692             : 
     693             :     // If not own Pool, then no name
     694           0 :     if ( aExternName != pImp->aName )
     695           0 :         pImp->aName = OUString();
     696             : 
     697           0 :     pImp->bStreaming = false;
     698           0 :     return rStream;
     699             : };
     700             : 
     701   196111717 : sal_uInt16 SfxItemPool::GetIndex_Impl(sal_uInt16 nWhich) const
     702             : {
     703             :     DBG_ASSERT(nWhich >= pImp->mnStart && nWhich <= pImp->mnEnd, "WhichId not within the Pool range");
     704   196111717 :     return nWhich - pImp->mnStart;
     705             : }
     706             : 
     707      240454 : sal_uInt16 SfxItemPool::GetSize_Impl() const
     708             : {
     709      240454 :     return pImp->mnEnd - pImp->mnStart + 1;
     710             : }
     711             : 
     712             : 
     713           0 : SvStream &SfxItemPool::Load1_Impl(SvStream &rStream)
     714             : {
     715             :     // For the Master the Header has already been loaded in Load()
     716           0 :     if ( !pImp->bStreaming )
     717             :     {
     718             :         // Read the secondary's Header
     719           0 :         CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_STARTPOOL_4 );
     720           0 :         rStream.ReadUChar( pImp->nMajorVer ).ReadUChar( pImp->nMinorVer );
     721             :     }
     722           0 :     sal_uInt32 nAttribSize(0);
     723           0 :     OUString aExternName;
     724           0 :     if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 2 )
     725           0 :         rStream.ReadUInt16( pImp->nLoadingVersion );
     726           0 :     aExternName = readByteString(rStream);
     727           0 :     bool bOwnPool = aExternName == pImp->aName;
     728           0 :     pImp->bStreaming = true;
     729             : 
     730             :     //! As long as we cannot read foreign ones
     731           0 :     if ( !bOwnPool )
     732             :     {
     733           0 :         rStream.SetError(SVSTREAM_FILEFORMAT_ERROR);
     734           0 :         pImp->bStreaming = false;
     735           0 :         return rStream;
     736             :     }
     737             : 
     738             :     // Versions up to 1.3 cannot read WhichMoves
     739           0 :     if ( pImp->nMajorVer == 1 && pImp->nMinorVer <= 2 &&
     740           0 :          pImp->nVersion < pImp->nLoadingVersion )
     741             :     {
     742           0 :         rStream.SetError(ERRCODE_IO_WRONGVERSION);
     743           0 :         pImp->bStreaming = false;
     744           0 :         return rStream;
     745             :     }
     746             : 
     747             :     // SizeTable comes after the actual attributes
     748           0 :     rStream.ReadUInt32( nAttribSize );
     749             : 
     750             :     // Read SizeTable
     751           0 :     sal_uLong nStartPos = rStream.Tell();
     752           0 :     rStream.SeekRel( nAttribSize );
     753           0 :     CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_SIZES );
     754           0 :     sal_uInt32 nSizeTableLen(0);
     755           0 :     rStream.ReadUInt32( nSizeTableLen );
     756           0 :     boost::scoped_array<sal_Char> pBuf(new sal_Char[nSizeTableLen]);
     757           0 :     rStream.Read( pBuf.get(), nSizeTableLen );
     758           0 :     sal_uLong nEndOfSizes = rStream.Tell();
     759           0 :     SvMemoryStream aSizeTable( pBuf.get(), nSizeTableLen, STREAM_READ );
     760             : 
     761             :     // Starting with version 1.3 the SizeTable contains a versions map
     762           0 :     if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 3 )
     763             :     {
     764             :         // Find version map (last sal_uLong of the SizeTable determines position)
     765           0 :         rStream.Seek( nEndOfSizes - sizeof(sal_uInt32) );
     766           0 :         sal_uInt32 nVersionMapPos(0);
     767           0 :         rStream.ReadUInt32( nVersionMapPos );
     768           0 :         rStream.Seek( nVersionMapPos );
     769             : 
     770             :         // Read version maps
     771           0 :         CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_VERSIONMAP );
     772           0 :         sal_uInt16 nVerCount(0);
     773           0 :         rStream.ReadUInt16( nVerCount );
     774           0 :         for ( sal_uInt16 nVerNo = 0; nVerNo < nVerCount; ++nVerNo )
     775             :         {
     776             :             // Read Header for single versions
     777           0 :             sal_uInt16 nVersion(0), nHStart(0), nHEnd(0);
     778           0 :             rStream.ReadUInt16( nVersion ).ReadUInt16( nHStart ).ReadUInt16( nHEnd );
     779           0 :             sal_uInt16 nCount = nHEnd - nHStart + 1;
     780           0 :             sal_uInt16 nBytes = (nCount)*sizeof(sal_uInt16);
     781             : 
     782             :             // Is new version known?
     783           0 :             if ( nVerNo >= pImp->aVersions.size() )
     784             :             {
     785             :                 // Add new version
     786           0 :                 sal_uInt16 *pMap = new sal_uInt16[nCount];
     787           0 :                 memset(pMap, 0, nCount * sizeof(sal_uInt16));
     788           0 :                 for ( sal_uInt16 n = 0; n < nCount; ++n )
     789           0 :                     rStream.ReadUInt16( pMap[n] );
     790           0 :                 SetVersionMap( nVersion, nHStart, nHEnd, pMap );
     791             :             }
     792             :             else
     793             :                 // Skip known versions
     794           0 :                 rStream.SeekRel( nBytes );
     795             :         }
     796             :     }
     797             : 
     798             :     // Load Items
     799           0 :     rStream.Seek( nStartPos );
     800           0 :     CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ITEMS );
     801           0 :     bool bSecondaryLoaded = false;
     802           0 :     long nSecondaryEnd = 0;
     803           0 :     sal_uInt16 nWhich(0), nSlot(0);
     804           0 :     while ( rStream.ReadUInt16( nWhich ), nWhich )
     805             :     {
     806             :         // Move WhichId from old version?
     807           0 :         if ( pImp->nLoadingVersion != pImp->nVersion )
     808           0 :             nWhich = GetNewWhich( nWhich );
     809             : 
     810           0 :         rStream.ReadUInt16( nSlot );
     811             : 
     812           0 :         sal_uInt16 nRef(0), nCount(0), nVersion(0);
     813           0 :         sal_uInt32 nAttrSize(0);
     814           0 :         rStream.ReadUInt16( nVersion ).ReadUInt16( nCount );
     815             : 
     816             :         //!SFX_ASSERTWARNING( !nSlot || !HasMap() ||
     817             :         //!         ( nSlot == GetSlotId( nWhich, sal_False ) ) ||
     818             :         //!         !GetSlotId( nWhich, sal_False ),
     819             :         //!         nWhich, "Slot/Which mismatch" );
     820             : 
     821           0 :         sal_uInt16 nIndex = GetIndex_Impl(nWhich);
     822           0 :         std::vector<SfxPoolItemArray_Impl*>::iterator ppArr = pImp->maPoolItems.begin();
     823           0 :         std::advance(ppArr, nIndex);
     824           0 :         SfxPoolItemArray_Impl *pNewArr = new SfxPoolItemArray_Impl();
     825           0 :         SfxPoolItem *pDefItem = *(pImp->ppStaticDefaults + nIndex);
     826             : 
     827             :         // Remember position of first Item
     828           0 :         sal_uLong nLastPos = rStream.Tell();
     829             : 
     830             :         // SfxSetItems could contain Items from secondary Pool
     831           0 :         if ( !bSecondaryLoaded && pImp->mpSecondary && pDefItem->ISA(SfxSetItem) )
     832             :         {
     833             :             // Seek to end of own Pool
     834           0 :             rStream.Seek(nEndOfSizes);
     835           0 :             CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr );
     836           0 :             CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr );
     837             : 
     838             :             // Read secondary Pool
     839           0 :             pImp->mpSecondary->Load1_Impl( rStream );
     840           0 :             bSecondaryLoaded = true;
     841           0 :             nSecondaryEnd = rStream.Tell();
     842             : 
     843             :             // Back to our own Items
     844           0 :             rStream.Seek(nLastPos);
     845             :         }
     846             : 
     847             :         // Read Items
     848           0 :         for ( sal_uInt16 j = 0; j < nCount; ++j )
     849             :         {
     850           0 :             sal_uLong nPos = nLastPos;
     851           0 :             rStream.ReadUInt16( nRef );
     852             : 
     853           0 :             SfxPoolItem *pItem = 0;
     854           0 :             if ( nRef )
     855             :             {
     856           0 :                 pItem = pDefItem->Create(rStream, nVersion);
     857             : 
     858           0 :                 if ( !pImp->mbPersistentRefCounts )
     859             :                     // Hold onto them until SfxItemPool::LoadCompleted()
     860           0 :                     AddRef(*pItem, 1);
     861             :                 else
     862             :                 {
     863           0 :                     if ( nRef > SFX_ITEMS_OLD_MAXREF )
     864           0 :                         pItem->SetKind( convertUInt16ToSfxItemKind(nRef) );
     865             :                     else
     866           0 :                         AddRef(*pItem, nRef);
     867             :                 }
     868             :             }
     869             :             //pNewArr->insert( pItem, j );
     870           0 :             pNewArr->push_back( (SfxPoolItem*) pItem );
     871             : 
     872             :             // Skip the rest of the saved length (newer format)
     873           0 :             nLastPos = rStream.Tell();
     874             : 
     875           0 :             aSizeTable.ReadUInt32( nAttrSize );
     876             :             SFX_ASSERT( ( nPos + nAttrSize) >= nLastPos,
     877             :                         nPos,
     878             :                         "too many bytes read - version mismatch?" );
     879             : 
     880           0 :             if (nLastPos < (nPos + nAttrSize))
     881             :             {
     882           0 :                 nLastPos = nPos + nAttrSize;
     883           0 :                 rStream.Seek( nLastPos );
     884             :             }
     885             :         }
     886             : 
     887           0 :         SfxPoolItemArray_Impl *pOldArr = *ppArr;
     888           0 :         *ppArr = pNewArr;
     889             : 
     890             :         // Remember Items already in the Pool
     891           0 :         bool bEmpty = true;
     892           0 :         if ( 0 != pOldArr )
     893           0 :             for ( size_t n = 0; bEmpty && n < pOldArr->size(); ++n )
     894           0 :                 bEmpty = pOldArr->operator[](n) == 0;
     895             :         DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" );
     896           0 :         if ( !bEmpty )
     897             :         {
     898             :             // Find out for all old ones, whether there's a same new one
     899           0 :             for ( size_t nOld = 0; nOld < pOldArr->size(); ++nOld )
     900             :             {
     901           0 :                 SfxPoolItem *pOldItem = (*pOldArr)[nOld];
     902           0 :                 if ( pOldItem )
     903             :                 {
     904           0 :                     bool bFound = false;
     905           0 :                     for ( size_t nNew = 0;
     906           0 :                           nNew < (*ppArr)->size();  ++nNew )
     907             :                     {
     908             :                         SfxPoolItem *&rpNewItem =
     909           0 :                             (SfxPoolItem*&)(*ppArr)->operator[](nNew);
     910             : 
     911           0 :                         if ( rpNewItem && *rpNewItem == *pOldItem )
     912             :                         {
     913           0 :                             AddRef( *pOldItem, rpNewItem->GetRefCount() );
     914           0 :                             SetRefCount( *rpNewItem, 0 );
     915           0 :                             delete rpNewItem;
     916           0 :                             rpNewItem = pOldItem;
     917           0 :                             bFound = true;
     918             :                             SAL_INFO("svl", "reusing item" << pOldItem);
     919           0 :                             break;
     920             :                         }
     921             :                     }
     922             :                     SAL_INFO_IF(
     923             :                         !bFound, "svl", "item not found: " << pOldItem);
     924             :                 }
     925             :             }
     926             :         }
     927           0 :         delete pOldArr;
     928             :     }
     929             : 
     930             :     // Read Pool defaults
     931           0 :     if ( pImp->nMajorVer > 1 || pImp->nMinorVer > 0 )
     932           0 :         CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_DEFAULTS );
     933             : 
     934           0 :     sal_uLong nLastPos = rStream.Tell();
     935           0 :     while ( rStream.ReadUInt16( nWhich ), nWhich )
     936             :     {
     937             :         // Move WhichId from old version?
     938           0 :         if ( pImp->nLoadingVersion != pImp->nVersion )
     939           0 :             nWhich = GetNewWhich( nWhich );
     940             : 
     941           0 :         rStream.ReadUInt16( nSlot );
     942             : 
     943           0 :         sal_uLong nPos = nLastPos;
     944           0 :         sal_uInt32 nSize(0);
     945           0 :         sal_uInt16 nVersion(0);
     946           0 :         rStream.ReadUInt16( nVersion );
     947             : 
     948             :         SfxPoolItem *pItem =
     949           0 :             ( *( pImp->ppStaticDefaults + GetIndex_Impl(nWhich) ) )
     950           0 :             ->Create( rStream, nVersion );
     951           0 :         pItem->SetKind( SFX_ITEMS_POOLDEFAULT );
     952           0 :         *( pImp->ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem;
     953             : 
     954           0 :         nLastPos = rStream.Tell();
     955           0 :         aSizeTable.ReadUInt32( nSize );
     956             :         SFX_ASSERT( ( nPos + nSize) >= nLastPos, nPos,
     957             :                     "too many bytes read - version mismatch?" );
     958           0 :         if ( nLastPos < (nPos + nSize) )
     959           0 :             rStream.Seek( nPos + nSize );
     960             :     }
     961             : 
     962           0 :     pBuf.reset();
     963           0 :     rStream.Seek(nEndOfSizes);
     964           0 :     CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL );
     965           0 :     CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL );
     966             : 
     967           0 :     if ( pImp->mpSecondary )
     968             :     {
     969           0 :         if ( !bSecondaryLoaded )
     970           0 :             pImp->mpSecondary->Load1_Impl( rStream );
     971             :         else
     972           0 :             rStream.Seek( nSecondaryEnd );
     973             :     }
     974             : 
     975           0 :     if ( aExternName != pImp->aName )
     976           0 :         pImp->aName = OUString();
     977             : 
     978           0 :     pImp->bStreaming = false;
     979           0 :     return rStream;
     980             : }
     981             : 
     982             : 
     983             : /**
     984             :  * Loads surrogate from 'rStream' and returns the corresponding SfxPoolItem
     985             :  * from the rRefPool.
     986             :  * If the surrogate contained within the stream == SFX_ITEMS_DIRECT
     987             :  * (!SFX_ITEM_POOLABLE), we return 0 and the Item is to be loaded directly
     988             :  * from the stream.
     989             :  * We also return 0 for 0xfffffff0 (SFX_ITEMS_NULL) and rWhich is set to 0,
     990             :  * making the Items unavailable.
     991             :  *
     992             :  * Apart from that we also take into account whether the Pool is loaded without
     993             :  * RefCounts, if we reload from a new Pool (&rRefPool != this) or if we're
     994             :  * building from a differently constructed Pool.
     995             :  *
     996             :  * If we load from a differently constructed Pool and the 'nSlotId' cannot be
     997             :  * mapped to a WhichId of this Pool, we also return 0.
     998             :  *
     999             :  * Preconditions:   - Pool must be loaded
    1000             :  *                  - LoadCompleted must not have been called yet
    1001             :  *                  - 'rStream' is at the position at which a surrogate
    1002             :  *                    for an Item with the SlotId 'nSlotId', the WhichId
    1003             :  *                    'rWhichId' was saved with StoreSurrogate
    1004             :  *
    1005             :  * Postconditions:  - 'rStream' is at the same position as after StoreSurrogate
    1006             :  *                    had finished saving
    1007             :  *                  - If we were able to load an Item, it's now in this
    1008             :  *                    SfxItemPool
    1009             :  *                  - 'rWhichId' now contains the mapped WhichId
    1010             :  *
    1011             :  * Runtime: Depth of the traget secondary Pool * 10 + 10
    1012             :  *
    1013             :  * @see SfxItemPool::StoreSurrogate(SvStream&,const SfxPoolItem &)const
    1014             : */
    1015           0 : const SfxPoolItem* SfxItemPool::LoadSurrogate
    1016             : (
    1017             :     SvStream&           rStream,    // Stream before a surrogate
    1018             :     sal_uInt16&         rWhich,     // WhichId of the SfxPoolItem that is to be loaded
    1019             :     sal_uInt16          nSlotId,    // SlotId of the SfxPoolItem that is to be loaded
    1020             :     const SfxItemPool*  pRefPool    // SfxItemPool in which the surrogate is valid
    1021             : )
    1022             : {
    1023             :     // Read the first surrogate
    1024           0 :     sal_uInt32 nSurrogat(0);
    1025           0 :     rStream.ReadUInt32( nSurrogat );
    1026             : 
    1027             :     // Is item stored directly?
    1028           0 :     if ( SFX_ITEMS_DIRECT == nSurrogat )
    1029           0 :         return 0;
    1030             : 
    1031             :     // Item does not exist?
    1032           0 :     if ( SFX_ITEMS_NULL == nSurrogat )
    1033             :     {
    1034           0 :         rWhich = 0;
    1035           0 :         return 0;
    1036             :     }
    1037             : 
    1038             :     // If the Pool in the stream has the same structure, the surrogate
    1039             :     // can be resolved in any case
    1040           0 :     if ( !pRefPool )
    1041           0 :         pRefPool = this;
    1042             : 
    1043           0 :     bool bResolvable = !pRefPool->GetName().isEmpty();
    1044           0 :     if ( !bResolvable )
    1045             :     {
    1046             :         // If the pool in the stream has a different structure, the SlotId
    1047             :         // from the stream must be mapable to a WhichId
    1048           0 :         sal_uInt16 nMappedWhich = nSlotId ? GetWhich(nSlotId, true) : 0;
    1049           0 :         if ( IsWhich(nMappedWhich) )
    1050             :         {
    1051             :             // Mapped SlotId can be taken over
    1052           0 :             rWhich = nMappedWhich;
    1053           0 :             bResolvable = true;
    1054             :         }
    1055             :     }
    1056             : 
    1057             :     // Can the surrogate be resolved?
    1058           0 :     if ( bResolvable )
    1059             :     {
    1060           0 :         const SfxPoolItem *pItem = 0;
    1061           0 :         for ( SfxItemPool *pTarget = this; pTarget; pTarget = pTarget->pImp->mpSecondary )
    1062             :         {
    1063             :             // Found the right (Range-)Pool?
    1064           0 :             if ( pTarget->IsInRange(rWhich) )
    1065             :             {
    1066             :                 // Default attribute?
    1067           0 :                 if ( SFX_ITEMS_DEFAULT == nSurrogat )
    1068           0 :                     return *(pTarget->pImp->ppStaticDefaults +
    1069           0 :                             pTarget->GetIndex_Impl(rWhich));
    1070             : 
    1071             :                 SfxPoolItemArray_Impl* pItemArr =
    1072           0 :                     pTarget->pImp->maPoolItems[pTarget->GetIndex_Impl(rWhich)];
    1073           0 :                 pItem = pItemArr && nSurrogat < pItemArr->size()
    1074           0 :                             ? (*pItemArr)[nSurrogat]
    1075           0 :                             : 0;
    1076           0 :                 if ( !pItem )
    1077             :                 {
    1078             :                     OSL_FAIL( "can't resolve surrogate" );
    1079           0 :                     rWhich = 0; // Just to be sure; for the right StreamPos
    1080           0 :                     return 0;
    1081             :                 }
    1082             : 
    1083             :                 // Reload from RefPool?
    1084           0 :                 if ( pRefPool != pImp->mpMaster )
    1085           0 :                     return &pTarget->Put( *pItem );
    1086             : 
    1087             :                 // References have NOT been loaded together with the pool?
    1088           0 :                 if ( !pTarget->HasPersistentRefCounts() )
    1089           0 :                     AddRef( *pItem, 1 );
    1090             :                 else
    1091           0 :                     return pItem;
    1092             : 
    1093           0 :                 return pItem;
    1094             :             }
    1095             :         }
    1096             : 
    1097             :         SFX_ASSERT( false, rWhich, "can't resolve Which-Id in LoadSurrogate" );
    1098             :     }
    1099             : 
    1100           0 :     return 0;
    1101             : }
    1102             : 
    1103             : 
    1104             : /**
    1105             :  * Saves a surrogate for '*pItem' in 'rStream'
    1106             :  *
    1107             :  * @returns sal_True: a real surrogates has been saved
    1108             :  *                    SFX_ITEMS_NULL for 'pItem==0', SFX_ITEMS_STATICDEFAULT
    1109             :  *                    and SFX_ITEMS_POOLDEFAULT are 'real' surrogates
    1110             :  *
    1111             :  * @returns sal_False: a dummy surrogate (SFX_ITEMS_DIRECT) has been saved;
    1112             :  *                     the actual Item needs to be saved right after it on
    1113             :  *                     its own
    1114             : */
    1115       28658 : bool SfxItemPool::StoreSurrogate ( SvStream& rStream, const SfxPoolItem*  pItem) const
    1116             : {
    1117       28658 :     if ( pItem )
    1118             :     {
    1119       28658 :         bool bRealSurrogate = IsItemFlag(*pItem, SFX_ITEM_POOLABLE);
    1120             :         rStream.WriteUInt32(  bRealSurrogate
    1121             :                         ? GetSurrogate( pItem )
    1122       28658 :                         : SFX_ITEMS_DIRECT  );
    1123       28658 :         return bRealSurrogate;
    1124             :     }
    1125             : 
    1126           0 :     rStream.WriteUInt32( SFX_ITEMS_NULL );
    1127           0 :     return true;
    1128             : }
    1129             : 
    1130             : 
    1131             : 
    1132       27878 : sal_uInt32 SfxItemPool::GetSurrogate(const SfxPoolItem *pItem) const
    1133             : {
    1134             :     DBG_ASSERT( pItem, "no 0-Pointer Surrogate" );
    1135             :     DBG_ASSERT( !IsInvalidItem(pItem), "no Invalid-Item Surrogate" );
    1136             :     DBG_ASSERT( !IsPoolDefaultItem(pItem), "no Pool-Default-Item Surrogate" );
    1137             : 
    1138       27878 :     if ( !IsInRange(pItem->Which()) )
    1139             :     {
    1140           0 :         if ( pImp->mpSecondary )
    1141           0 :             return pImp->mpSecondary->GetSurrogate( pItem );
    1142             :         SFX_ASSERT( false, pItem->Which(), "unknown Which-Id - dont ask me for surrogates" );
    1143             :     }
    1144             : 
    1145             :     // Pointer on static or pool-default attribute?
    1146       27878 :     if( IsStaticDefaultItem(pItem) || IsPoolDefaultItem(pItem) )
    1147           0 :         return SFX_ITEMS_DEFAULT;
    1148             : 
    1149       27878 :     SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(pItem->Which())];
    1150             :     DBG_ASSERT(pItemArr, "ItemArr is not available");
    1151             : 
    1152       29742 :     for ( size_t i = 0; i < pItemArr->size(); ++i )
    1153             :     {
    1154       29742 :         const SfxPoolItem *p = (*pItemArr)[i];
    1155       29742 :         if ( p == pItem )
    1156       27878 :             return i;
    1157             :     }
    1158             :     SFX_ASSERT( false, pItem->Which(), "Item not in the pool");
    1159           0 :     return SFX_ITEMS_NULL;
    1160             : }
    1161             : 
    1162             : 
    1163       17768 : bool SfxItemPool::IsInStoringRange( sal_uInt16 nWhich ) const
    1164             : {
    1165       35536 :     return nWhich >= pImp->nStoringStart &&
    1166       35536 :            nWhich <= pImp->nStoringEnd;
    1167             : }
    1168             : 
    1169             : /**
    1170             :  * This method allows for restricting the WhichRange, which is saved
    1171             :  * by ItemSets of this Pool (and the Pool itself).
    1172             :  * The method must be called before SfxItemPool::Store() and the values
    1173             :  * must also be still set when the actual document (the ItemSets) is
    1174             :  * being saved.
    1175             :  *
    1176             :  * Resetting it is not necessary, if this range is set correctly before
    1177             :  * _every_ save, because its only accounted for when saving.
    1178             :  *
    1179             :  * We need to do this for the 3.1 format, because there's a bug in the
    1180             :  * Pool loading method.
    1181             : */
    1182       10704 : void SfxItemPool::SetStoringRange( sal_uInt16 nFrom, sal_uInt16 nTo )
    1183             : {
    1184       10704 :     pImp->nStoringStart = nFrom;
    1185       10704 :     pImp->nStoringEnd = nTo;
    1186       10704 : }
    1187             : 
    1188             : 
    1189             : /**
    1190             :  * This method allows for the creation of new and incompatible WhichId
    1191             :  * Ranges or distributions. Pools that were saved with old versions
    1192             :  * are mapped using the provided conversion table until the current
    1193             :  * version has been reached. Newer pools can be loaded, but will lose
    1194             :  * newer attributes, because the map is saved in conjunction with the pool.
    1195             :  *
    1196             :  *  Precondition:   Pool must not be loaded yet
    1197             :  *  Postcondition:  WhichIds from older versions can be mapped to version 'nVer'
    1198             :  *  Runtime:        1.5 * new + 10
    1199             :  *
    1200             :  *  For newer WhichRanges (nStart,nEnd) it must hold that older WhichRanges
    1201             :  *  (nOldStart,nOldEnd) are completely contained in the newer WhichRange.
    1202             :  *  It is valid to extend the WhichRange to both sides; also by inserting
    1203             :  *  WhichIds. Moving WhichIds is not permitted.
    1204             :  *  This method should only be called in or right after the ctor.
    1205             :  *
    1206             :  *  The array must be static, because its not copied and resued in the
    1207             :  *  copy-ctor of the SfxItemPool
    1208             :  *
    1209             :  *  Example usage:
    1210             :  *  Originally (version 0) the pool had the following WhichIds:
    1211             :  *
    1212             :  *     1:A, 2:B, 3:C, 4:D
    1213             :  *
    1214             :  *  A newer version (version 1) is now supposed to contain two new Ids
    1215             :  *  X and Y between B and C, looking like this:
    1216             :  *
    1217             :  *      1:A, 2:B, 3:X, 4:Y, 5:C, 6:D
    1218             :  *
    1219             :  *  We see that the Ids 3 and 4 have changed. For the new version, we
    1220             :  *  would need to set the following in the new Pool:
    1221             :  *
    1222             :  *      static sal_uInt16 nVersion1Map = { 1, 2, 5, 6 };
    1223             :  *      pPool->SetVersionMap( 1, 1, 4, &nVersion1Map );
    1224             :  *
    1225             :  *  @see SfxItemPool::IsLoadingVersionCurrent() const
    1226             :  *  @see SfxItemPool::GetNewWhich(sal_uInt16)
    1227             :  *  @see SfxItemPool::GetVersion() const
    1228             :  */
    1229      596140 : void SfxItemPool::SetVersionMap
    1230             : (
    1231             :     sal_uInt16  nVer,               // New version number
    1232             :     sal_uInt16  nOldStart,          // Old first WhichId
    1233             :     sal_uInt16  nOldEnd,            // Old last WhichId
    1234             :     const sal_uInt16* pOldWhichIdTab /* Array containing the structure of the WhichIds
    1235             :                                         of the previous version, in which the new
    1236             :                                         corresponding new WhichId is located */
    1237             : )
    1238             : {
    1239             :     // Create new map entry to insert
    1240             :     const SfxPoolVersion_ImplPtr pVerMap = SfxPoolVersion_ImplPtr( new SfxPoolVersion_Impl(
    1241      596140 :                 nVer, nOldStart, nOldEnd, pOldWhichIdTab ) );
    1242      596140 :     pImp->aVersions.push_back( pVerMap );
    1243             : 
    1244             :     DBG_ASSERT( nVer > pImp->nVersion, "Versions not sorted" );
    1245      596140 :     pImp->nVersion = nVer;
    1246             : 
    1247             :     // Adapt version range
    1248    22504300 :     for ( sal_uInt16 n = 0; n < nOldEnd-nOldStart+1; ++n )
    1249             :     {
    1250    21908160 :         sal_uInt16 nWhich = pOldWhichIdTab[n];
    1251    21908160 :         if ( nWhich < pImp->nVerStart )
    1252             :         {
    1253           0 :             if ( !nWhich )
    1254           0 :                 nWhich = 0;
    1255           0 :             pImp->nVerStart = nWhich;
    1256             :         }
    1257    21908160 :         else if ( nWhich > pImp->nVerEnd )
    1258        2336 :             pImp->nVerEnd = nWhich;
    1259      596140 :     }
    1260      596140 : }
    1261             : 
    1262             : 
    1263             : /**
    1264             :  * This method converts WhichIds from a file format to the version of the
    1265             :  * current pool.
    1266             :  * If the file format is older, the conversion tables (set by the pool developer
    1267             :  * using SetVersion()) are used. If the file format is newer the conversion tables
    1268             :  * loaded from the file format are used. In this case, not every WhichId can be
    1269             :  * mapped in which case we return 0.
    1270             :  *
    1271             :  * The calculation is only defined for WhichIds supported by the corresponding
    1272             :  * file version, which is guarded by an assertion.
    1273             :  *
    1274             :  * Precondition:   Pool must be loaded
    1275             :  * Postcondition:  Unchanged
    1276             :  * Runtime:        linear(Count of the secondary pools) +
    1277             :  *                 linear(Difference of the old and newer version)
    1278             :  *
    1279             :  * @see SfxItemPool::IsLoadingVersionCurrent() const
    1280             :  * @see SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)
    1281             :  * @see SfxItemPool::GetVersion() const
    1282             :  */
    1283           0 : sal_uInt16 SfxItemPool::GetNewWhich
    1284             : (
    1285             :     sal_uInt16  nFileWhich // The WhichId loaded from the stream
    1286             : )   const
    1287             : {
    1288             :     // Determine (secondary) Pool
    1289           0 :     if ( !IsInVersionsRange(nFileWhich) )
    1290             :     {
    1291           0 :         if ( pImp->mpSecondary )
    1292           0 :             return pImp->mpSecondary->GetNewWhich( nFileWhich );
    1293             :         SFX_ASSERT( false, nFileWhich, "unknown which in GetNewWhich()" );
    1294             :     }
    1295             : 
    1296             :     // Newer/the same/older version?
    1297           0 :     short nDiff = (short)pImp->nLoadingVersion - (short)pImp->nVersion;
    1298             : 
    1299             :     // WhichId of a newer version?
    1300           0 :     if ( nDiff > 0 )
    1301             :     {
    1302             :         // Map step by step from the top version down to the file version
    1303           0 :         for ( size_t nMap = pImp->aVersions.size(); nMap > 0; --nMap )
    1304             :         {
    1305           0 :             SfxPoolVersion_ImplPtr pVerInfo = pImp->aVersions[nMap-1];
    1306           0 :             if ( pVerInfo->_nVer > pImp->nVersion )
    1307             :             {   sal_uInt16 nOfs;
    1308           0 :                 sal_uInt16 nCount = pVerInfo->_nEnd - pVerInfo->_nStart + 1;
    1309           0 :                 for ( nOfs = 0;
    1310           0 :                       nOfs <= nCount &&
    1311           0 :                         pVerInfo->_pMap[nOfs] != nFileWhich;
    1312             :                       ++nOfs )
    1313           0 :                     continue;
    1314             : 
    1315           0 :                 if ( pVerInfo->_pMap[nOfs] == nFileWhich )
    1316           0 :                     nFileWhich = pVerInfo->_nStart + nOfs;
    1317             :                 else
    1318           0 :                     return 0;
    1319             :             }
    1320             :             else
    1321           0 :                 break;
    1322           0 :         }
    1323             :     }
    1324             : 
    1325             :     // WhichId of a newer version?
    1326           0 :     else if ( nDiff < 0 )
    1327             :     {
    1328             :         // Map step by step from the top version down to the file version
    1329           0 :         for ( size_t nMap = 0; nMap < pImp->aVersions.size(); ++nMap )
    1330             :         {
    1331           0 :             SfxPoolVersion_ImplPtr pVerInfo = pImp->aVersions[nMap];
    1332           0 :             if ( pVerInfo->_nVer > pImp->nLoadingVersion )
    1333             :             {
    1334             :                 DBG_ASSERT( nFileWhich >= pVerInfo->_nStart &&
    1335             :                             nFileWhich <= pVerInfo->_nEnd,
    1336             :                             "which-id unknown in version" );
    1337           0 :                 nFileWhich = pVerInfo->_pMap[nFileWhich - pVerInfo->_nStart];
    1338             :             }
    1339           0 :         }
    1340             :     }
    1341             : 
    1342             :     // Return original (nDiff==0) or mapped (nDiff!=0) Id
    1343           0 :     return nFileWhich;
    1344             : }
    1345             : 
    1346             : 
    1347             : 
    1348             : 
    1349           0 : bool SfxItemPool::IsInVersionsRange( sal_uInt16 nWhich ) const
    1350             : {
    1351           0 :     return nWhich >= pImp->nVerStart && nWhich <= pImp->nVerEnd;
    1352             : }
    1353             : 
    1354             : 
    1355             : /**
    1356             :  * This method determines whether the loaded Pool version corresponds to the
    1357             :  * currently loaded Pool structure.
    1358             :  *
    1359             :  * Precondition:   Pool is loaded
    1360             :  * Postcondition:  Unchanged
    1361             :  * Runtime:        linear(Count of secondary pools)
    1362             :  *
    1363             :  * @see SfxItemPool::SetVersionMap(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16*)
    1364             :  * @see SfxItemPool::GetNewWhich(sal_uInt16) const
    1365             :  * @see SfxItemPool::GetVersion() const
    1366             :  */
    1367           0 : bool SfxItemPool::IsCurrentVersionLoading() const
    1368             : {
    1369           0 :     return ( pImp->nVersion == pImp->nLoadingVersion ) &&
    1370           0 :            ( !pImp->mpSecondary || pImp->mpSecondary->IsCurrentVersionLoading() );
    1371             : }
    1372             : 
    1373             : 
    1374             : /**
    1375             :  * Saves the SfxPoolItem 'rItem' to the SvStream 'rStream':
    1376             :  * either as a surrogate ('bDirect == sal_False') or directly with
    1377             :  * 'rItem.Store()'.
    1378             :  * Non-poolable Items are always saved directly. Items without WhichId and
    1379             :  * SID-Items as well as Items that were not yet present in the file format
    1380             :  * version (return sal_False) are not saved.
    1381             :  *
    1382             :  * The Item is saved to the Stream in the following manner:
    1383             :  *   sal_uInt16  rItem.Which()
    1384             :  *   sal_uInt16  GetSlotId( rItem.Which() ) or 0 if not available
    1385             :  *   sal_uInt16  GetSurrogate( &rItem ) or SFX_ITEM_DIRECT fo '!SFX_ITEM_POOLBLE'
    1386             :  *
    1387             :  * Optionally (if 'bDirect == sal_True' or '!rItem.IsPoolable()':
    1388             :  *   sal_uInt16  rItem.GetVersion()
    1389             :  *   sal_uLong   Size
    1390             :  *   Size        rItem.Store()
    1391             :  *
    1392             :  *  @see SfxItemPool::LoadItem(SvStream&,bool) const
    1393             :  */
    1394       17768 : bool SfxItemPool::StoreItem( SvStream &rStream, const SfxPoolItem &rItem,
    1395             :                                  bool bDirect ) const
    1396             : {
    1397             :     DBG_ASSERT( !IsInvalidItem(&rItem), "cannot store invalid items" );
    1398             : 
    1399       17768 :     if ( IsSlot( rItem.Which() ) )
    1400           0 :         return false;
    1401             : 
    1402       17768 :     const SfxItemPool *pPool = this;
    1403       35536 :     while ( !pPool->IsInStoringRange(rItem.Which()) )
    1404           0 :         if ( 0 == ( pPool = pPool->pImp->mpSecondary ) )
    1405           0 :             return false;
    1406             : 
    1407             :     DBG_ASSERT( !pImp->bInSetItem || !rItem.ISA(SfxSetItem),
    1408             :                 "SetItem contains ItemSet with SetItem" );
    1409             : 
    1410       17768 :     sal_uInt16 nSlotId = pPool->GetSlotId( rItem.Which(), true );
    1411       17768 :     sal_uInt16 nItemVersion = rItem.GetVersion(pImp->mnFileFormatVersion);
    1412       17768 :     if ( USHRT_MAX == nItemVersion )
    1413           0 :         return false;
    1414             : 
    1415       17768 :     rStream.WriteUInt16( rItem.Which() ).WriteUInt16( nSlotId );
    1416       17768 :     if ( bDirect || !pPool->StoreSurrogate( rStream, &rItem ) )
    1417             :     {
    1418           0 :         rStream.WriteUInt16( nItemVersion );
    1419           0 :         rStream.WriteUInt32( 0L ); // Room for length in bytes
    1420           0 :         sal_uLong nIStart = rStream.Tell();
    1421           0 :         rItem.Store(rStream, nItemVersion);
    1422           0 :         sal_uLong nIEnd = rStream.Tell();
    1423           0 :         rStream.Seek( nIStart-4 );
    1424           0 :         rStream.WriteInt32( ( nIEnd-nIStart ) );
    1425           0 :         rStream.Seek( nIEnd );
    1426             :     }
    1427             : 
    1428       17768 :     return true;
    1429             : }
    1430             : 
    1431             : 
    1432             : /**
    1433             :  * If pRefPool==-1 => do not put!
    1434             :  */
    1435           0 : const SfxPoolItem* SfxItemPool::LoadItem( SvStream &rStream, bool bDirect,
    1436             :                                           const SfxItemPool *pRefPool )
    1437             : {
    1438           0 :     sal_uInt16 nWhich(0), nSlot(0); // nSurrogate;
    1439           0 :     rStream.ReadUInt16( nWhich ).ReadUInt16( nSlot );
    1440             : 
    1441           0 :     bool bDontPut = reinterpret_cast<SfxItemPool*>(-1) == pRefPool;
    1442           0 :     if ( bDontPut || !pRefPool )
    1443           0 :         pRefPool = this;
    1444             : 
    1445             :     // Find right secondary Pool
    1446           0 :     while ( !pRefPool->IsInVersionsRange(nWhich) )
    1447             :     {
    1448           0 :         if ( pRefPool->pImp->mpSecondary )
    1449           0 :             pRefPool = pRefPool->pImp->mpSecondary;
    1450             :         else
    1451             :         {
    1452             :             // WID not present in this version => skip
    1453           0 :             sal_uInt32 nSurro(0);
    1454           0 :             sal_uInt16 nVersion(0), nLen(0);
    1455           0 :             rStream.ReadUInt32( nSurro );
    1456           0 :             if ( SFX_ITEMS_DIRECT == nSurro )
    1457             :             {
    1458           0 :                 rStream.ReadUInt16( nVersion ).ReadUInt16( nLen );
    1459           0 :                 rStream.SeekRel( nLen );
    1460             :             }
    1461           0 :             return 0;
    1462             :         }
    1463             :     }
    1464             : 
    1465             :     // Are we loading a different version?
    1466           0 :     bool bCurVersion = pRefPool->IsCurrentVersionLoading();
    1467           0 :     if ( !bCurVersion )
    1468           0 :         nWhich = pRefPool->GetNewWhich( nWhich ); // Map WhichId to new version
    1469             : 
    1470             :     DBG_ASSERT( !nWhich || !pImp->bInSetItem ||
    1471             :                 !pRefPool->pImp->ppStaticDefaults[pRefPool->GetIndex_Impl(nWhich)]->ISA(SfxSetItem),
    1472             :                 "loading SetItem in ItemSet of SetItem" );
    1473             : 
    1474             :     // Are we loading via surrogate?
    1475           0 :     const SfxPoolItem *pItem = 0;
    1476           0 :     if ( !bDirect )
    1477             :     {
    1478             :         // WhichId known in this version?
    1479           0 :         if ( nWhich )
    1480             :             // Load surrogate and react if none present
    1481           0 :             pItem = LoadSurrogate( rStream, nWhich, nSlot, pRefPool );
    1482             :         else
    1483             :             // Else skip it
    1484           0 :             rStream.SeekRel( sizeof(sal_uInt16) );
    1485             :     }
    1486             : 
    1487             :     // Is loaded directly (not via surrogate)?
    1488           0 :     if ( bDirect || ( nWhich && !pItem ) )
    1489             :     {
    1490             :         // bDirekt or not IsPoolable() => Load Item directly
    1491           0 :         sal_uInt16 nVersion(0);
    1492           0 :         sal_uInt32 nLen(0);
    1493           0 :         rStream.ReadUInt16( nVersion ).ReadUInt32( nLen );
    1494           0 :         sal_uLong nIStart = rStream.Tell();
    1495             : 
    1496             :         // WhichId known in this version?
    1497           0 :         if ( nWhich )
    1498             :         {
    1499             :             // Load Item directly
    1500             :             SfxPoolItem *pNewItem =
    1501           0 :                     pRefPool->GetDefaultItem(nWhich).Create(rStream, nVersion);
    1502           0 :             if ( bDontPut )
    1503           0 :                 pItem = pNewItem;
    1504             :             else
    1505           0 :                 if ( pNewItem )
    1506             :                 {
    1507           0 :                     pItem = &Put(*pNewItem);
    1508           0 :                     delete pNewItem;
    1509             :                 }
    1510             :                 else
    1511           0 :                     pItem = 0;
    1512           0 :             sal_uLong nIEnd = rStream.Tell();
    1513             :             DBG_ASSERT( nIEnd <= (nIStart+nLen), "read past end of item" );
    1514           0 :             if ( (nIStart+nLen) != nIEnd )
    1515           0 :                 rStream.Seek( nIStart+nLen );
    1516             :         }
    1517             :         else
    1518             :             // SKip Item
    1519           0 :             rStream.Seek( nIStart+nLen );
    1520             :     }
    1521             : 
    1522           0 :     return pItem;
    1523             : }
    1524             : 
    1525             : 
    1526           0 : OUString readByteString(SvStream& rStream)
    1527             : {
    1528           0 :     return rStream.ReadUniOrByteString(rStream.GetStreamCharSet());
    1529             : }
    1530             : 
    1531       10704 : void writeByteString(SvStream & rStream, const OUString& rString)
    1532             : {
    1533       10704 :     rStream.WriteUniOrByteString(rString, rStream.GetStreamCharSet());
    1534       10704 : }
    1535             : 
    1536           0 : OUString readUnicodeString(SvStream & rStream, bool bUnicode)
    1537             : {
    1538             :     return rStream.ReadUniOrByteString(bUnicode ? RTL_TEXTENCODING_UCS2 :
    1539           0 :                                       rStream.GetStreamCharSet());
    1540             : }
    1541             : 
    1542           0 : void writeUnicodeString(SvStream & rStream, const OUString& rString)
    1543             : {
    1544           0 :     rStream.WriteUniOrByteString(rString, RTL_TEXTENCODING_UCS2);
    1545           0 : }
    1546             : 
    1547             : 
    1548             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10