LCOV - code coverage report
Current view: top level - svl/source/items - itemset.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 624 777 80.3 %
Date: 2015-06-13 12:38:46 Functions: 42 49 85.7 %
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             : 
      23             : #include <cstdarg>
      24             : #include <libxml/xmlwriter.h>
      25             : 
      26             : #include <sal/log.hxx>
      27             : #include <svl/itemset.hxx>
      28             : #include <svl/itempool.hxx>
      29             : #include <svl/itemiter.hxx>
      30             : #include <svl/whiter.hxx>
      31             : #include <svl/nranges.hxx>
      32             : #include "whassert.hxx"
      33             : 
      34             : #include <tools/stream.hxx>
      35             : #include <tools/solar.h>
      36             : #include <rtl/string.hxx>
      37             : 
      38             : // STATIC DATA
      39             : 
      40             : static const sal_uInt16 nInitCount = 10; // Single USHORTs => 5 pairs without '0'
      41             : #include "nranges.cxx"
      42             : #include "poolio.hxx"
      43             : 
      44             : 
      45             : #ifdef DBG_UTIL
      46             : 
      47             : 
      48             : const sal_Char *DbgCheckItemSet( const void* pVoid )
      49             : {
      50             :     const SfxItemSet *pSet = static_cast<const SfxItemSet*>(pVoid);
      51             :     SfxWhichIter aIter( *pSet );
      52             :     sal_uInt16 nCount = 0, n = 0;
      53             :     for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh; nWh = aIter.NextWhich(), ++n )
      54             :     {
      55             :         const SfxPoolItem *pItem = pSet->m_pItems[n];
      56             :         if ( pItem )
      57             :         {
      58             :             ++nCount;
      59             :             assert((IsInvalidItem(pItem) ||
      60             :                         pItem->Which() == 0 || pItem->Which() == nWh
      61             :                     ) && "SfxItemSet: invalid which-id" );
      62             :             assert((IsInvalidItem(pItem) || !pItem->Which() ||
      63             :                     !SfxItemPool::IsWhich(pItem->Which()) ||
      64             :                     pSet->GetPool()->IsItemFlag(nWh, SfxItemPoolFlags::NOT_POOLABLE) ||
      65             :                     SFX_ITEMS_NULL != pSet->GetPool()->GetSurrogate(pItem)
      66             :                    ) && "SfxItemSet: item in set which is not in pool" );
      67             :         }
      68             : 
      69             :     }
      70             :     assert(pSet->m_nCount == nCount);
      71             : 
      72             :     return 0;
      73             : }
      74             : 
      75             : #endif
      76             : 
      77             : /**
      78             :  * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to
      79             :  * the supplied SfxItemPool.
      80             :  *
      81             :  * For Sfx programmers: an SfxItemSet constructed in this way cannot
      82             :  * contain any Items with SlotIds as Which values.
      83             :  */
      84       23447 : SfxItemSet::SfxItemSet
      85             : (
      86             :     SfxItemPool&    rPool,       /* Target Pool for the SfxPoolItems which are
      87             :                                     added to this SfxItemSet */
      88             :     bool        bTotalRanges    /* Take over complete pool ranges? */
      89             : )
      90             :     : m_pPool( &rPool )
      91             :     , m_pParent(nullptr)
      92       23447 :     , m_nCount(0)
      93             : {
      94             : //  DBG_ASSERT( bTotalRanges || abs( &bTotalRanges - this ) < 1000,
      95             : //              "please use suitable ranges" );
      96             : #if defined DBG_UTIL && defined SFX_ITEMSET_NO_DEFAULT_CTOR
      97             :     if ( !bTotalRanges )
      98             :         *(int*)0 = 0; // GPF
      99             : #else
     100             :     (void) bTotalRanges; // avoid warnings
     101             : #endif
     102             : 
     103       23447 :     m_pWhichRanges = const_cast<sal_uInt16*>(m_pPool->GetFrozenIdRanges());
     104             :     assert( m_pWhichRanges && "don't create ItemSets with full range before FreezeIdRanges()" );
     105       23447 :     if (!m_pWhichRanges)
     106           0 :         m_pPool->FillItemIdRanges_Impl( m_pWhichRanges );
     107             : 
     108       23447 :     const sal_uInt16 nSize = TotalCount();
     109       23447 :     m_pItems = new const SfxPoolItem* [ nSize ];
     110       23447 :     memset(static_cast<void*>(m_pItems), 0, nSize * sizeof(SfxPoolItem*));
     111       23447 : }
     112             : 
     113     2516591 : SfxItemSet::SfxItemSet(SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich2)
     114             :     : m_pPool( &rPool )
     115             :     , m_pParent(nullptr)
     116     2516591 :     , m_nCount(0)
     117             : {
     118             :     assert(nWhich1 <= nWhich2);
     119             : 
     120     2516591 :     InitRanges_Impl(nWhich1, nWhich2);
     121     2516591 : }
     122             : 
     123     2516922 : void SfxItemSet::InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2)
     124             : {
     125     2516922 :     m_pWhichRanges = new sal_uInt16[ 3 ];
     126     2516922 :     *(m_pWhichRanges+0) = nWh1;
     127     2516922 :     *(m_pWhichRanges+1) = nWh2;
     128     2516922 :     *(m_pWhichRanges+2) = 0;
     129     2516922 :     const sal_uInt16 nRg = nWh2 - nWh1 + 1;
     130     2516922 :     m_pItems = new const SfxPoolItem* [ nRg ];
     131     2516922 :     memset(static_cast<void*>(m_pItems), 0, nRg * sizeof(SfxPoolItem*));
     132     2516922 : }
     133             : 
     134      464754 : void SfxItemSet::InitRanges_Impl(va_list pArgs, sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull)
     135             : {
     136      464754 :     sal_uInt16 nSize = InitializeRanges_Impl(m_pWhichRanges, pArgs, nWh1, nWh2, nNull);
     137      464754 :     m_pItems = new const SfxPoolItem* [ nSize ];
     138      464754 :     memset(static_cast<void*>(m_pItems), 0, sizeof(SfxPoolItem*) * nSize);
     139      464754 : }
     140             : 
     141      465085 : SfxItemSet::SfxItemSet(SfxItemPool& rPool,
     142             :                        USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ...)
     143             :     : m_pPool( &rPool )
     144             :     , m_pParent(nullptr)
     145             :     , m_pWhichRanges(nullptr)
     146      465085 :     , m_nCount(0)
     147             : {
     148             :     assert(nWh1 <= nWh2);
     149             : 
     150      465085 :     if(!nNull)
     151             :         InitRanges_Impl(
     152         331 :             sal::static_int_cast< sal_uInt16 >(nWh1),
     153         662 :             sal::static_int_cast< sal_uInt16 >(nWh2));
     154             :     else {
     155             :         va_list pArgs;
     156      464754 :         va_start( pArgs, nNull );
     157             :         InitRanges_Impl(
     158      464754 :             pArgs, sal::static_int_cast< sal_uInt16 >(nWh1),
     159      464754 :             sal::static_int_cast< sal_uInt16 >(nWh2),
     160     1394262 :             sal::static_int_cast< sal_uInt16 >(nNull));
     161      464754 :         va_end(pArgs);
     162             :     }
     163      465085 : }
     164             : 
     165     8114662 : void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
     166             : {
     167     8114662 :     sal_uInt16 nCnt = 0;
     168     8114662 :     const sal_uInt16* pPtr = pWhichPairTable;
     169    43052654 :     while( *pPtr )
     170             :     {
     171    26823330 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     172    26823330 :         pPtr += 2;
     173             :     }
     174             : 
     175     8114662 :     m_pItems = new const SfxPoolItem* [ nCnt ];
     176     8114662 :     memset(static_cast<void*>(m_pItems), 0, sizeof(SfxPoolItem*) * nCnt);
     177             : 
     178     8114662 :     std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
     179     8114662 :     m_pWhichRanges = new sal_uInt16[ cnt ];
     180     8114662 :     memcpy( m_pWhichRanges, pWhichPairTable, sizeof( sal_uInt16 ) * cnt );
     181     8114662 : }
     182             : 
     183     8157297 : SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
     184             :     : m_pPool(&rPool)
     185             :     , m_pParent(nullptr)
     186             :     , m_pItems(nullptr)
     187             :     , m_pWhichRanges(nullptr)
     188     8157297 :     , m_nCount(0)
     189             : {
     190             :     // pWhichPairTable == 0 is for the SfxAllEnumItemSet
     191     8157297 :     if ( pWhichPairTable )
     192     8114662 :         InitRanges_Impl(pWhichPairTable);
     193     8157297 : }
     194             : 
     195     5141298 : SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
     196             :     : m_pPool( rASet.m_pPool )
     197             :     , m_pParent( rASet.m_pParent )
     198     5141298 :     , m_nCount( rASet.m_nCount )
     199             : {
     200             :     // Calculate the attribute count
     201     5141298 :     sal_uInt16 nCnt = 0;
     202     5141298 :     sal_uInt16* pPtr = rASet.m_pWhichRanges;
     203    40979673 :     while( *pPtr )
     204             :     {
     205    30697077 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     206    30697077 :         pPtr += 2;
     207             :     }
     208             : 
     209     5141298 :     m_pItems = new const SfxPoolItem* [ nCnt ];
     210             : 
     211             :     // Copy attributes
     212     5141298 :     SfxItemArray ppDst = m_pItems, ppSrc = rASet.m_pItems;
     213   370425816 :     for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
     214   747129646 :         if ( 0 == *ppSrc ||                 // Current Default?
     215   381843754 :              IsInvalidItem(*ppSrc) ||       // DontCare?
     216    16559236 :              IsStaticDefaultItem(*ppSrc) )  // Defaults that are not to be pooled?
     217             :             // Just copy the pointer
     218   348769613 :             *ppDst = *ppSrc;
     219    16514905 :         else if (m_pPool->IsItemFlag( **ppSrc, SfxItemPoolFlags::POOLABLE ))
     220             :         {
     221             :             // Just copy the pointer and increase RefCount
     222    14695642 :             *ppDst = *ppSrc;
     223    14695642 :             (*ppDst)->AddRef();
     224             :         }
     225     1819263 :         else if ( !(*ppSrc)->Which() )
     226           0 :             *ppDst = (*ppSrc)->Clone();
     227             :         else
     228             :             // !IsPoolable() => assign via Pool
     229     1819263 :             *ppDst = &m_pPool->Put( **ppSrc );
     230             : 
     231             :     // Copy the WhichRanges
     232     5141298 :     std::ptrdiff_t cnt = pPtr - rASet.m_pWhichRanges+1;
     233     5141298 :     m_pWhichRanges = new sal_uInt16[ cnt ];
     234     5141298 :     memcpy( m_pWhichRanges, rASet.m_pWhichRanges, sizeof( sal_uInt16 ) * cnt);
     235     5141298 : }
     236             : 
     237    17954663 : SfxItemSet::~SfxItemSet()
     238             : {
     239    16287298 :     sal_uInt16 nCount = TotalCount();
     240    16287298 :     if( Count() )
     241             :     {
     242    10208870 :         SfxItemArray ppFnd = m_pItems;
     243  1237758586 :         for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
     244  1227549716 :             if( *ppFnd && !IsInvalidItem(*ppFnd) )
     245             :             {
     246    42608119 :                 if( !(*ppFnd)->Which() )
     247       18717 :                     delete *ppFnd;
     248             :                 else {
     249             :                     // Still multiple references present, so just alter the RefCount
     250    42589402 :                     if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
     251    37541680 :                         (*ppFnd)->ReleaseRef();
     252             :                     else
     253     5047722 :                         if ( !IsDefaultItem(*ppFnd) )
     254             :                             // Delete from Pool
     255     3562710 :                             m_pPool->Remove( **ppFnd );
     256             :                 }
     257             :             }
     258             :     }
     259             : 
     260    16287298 :     delete[] m_pItems;
     261    16287298 :     if (m_pWhichRanges != m_pPool->GetFrozenIdRanges())
     262    16263921 :         delete[] m_pWhichRanges;
     263    16287298 :     m_pWhichRanges = nullptr; // for invariant-testing
     264    17954663 : }
     265             : 
     266             : /**
     267             :  * Delete single Items or all Items (nWhich == 0)
     268             :  */
     269     7751374 : sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
     270             : {
     271     7751374 :     if( !Count() )
     272     3674815 :         return 0;
     273             : 
     274     4076559 :     sal_uInt16 nDel = 0;
     275     4076559 :     SfxItemArray ppFnd = m_pItems;
     276             : 
     277     4076559 :     if( nWhich )
     278             :     {
     279     3401975 :         const sal_uInt16* pPtr = m_pWhichRanges;
     280    10340791 :         while( *pPtr )
     281             :         {
     282             :             // Within this range?
     283     6830440 :             if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     284             :             {
     285             :                 // Actually set?
     286     3293599 :                 ppFnd += nWhich - *pPtr;
     287     3293599 :                 if( *ppFnd )
     288             :                 {
     289             :                     // Due to the assertions in the sub calls, we need to do the following
     290      205171 :                     --m_nCount;
     291      205171 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     292      205171 :                     *ppFnd = 0;
     293             : 
     294      205171 :                     if ( !IsInvalidItem(pItemToClear) )
     295             :                     {
     296      205171 :                         if ( nWhich <= SFX_WHICH_MAX )
     297             :                         {
     298             :                             const SfxPoolItem& rNew = m_pParent
     299       77436 :                                     ? m_pParent->Get( nWhich, true )
     300      260113 :                                     : m_pPool->GetDefaultItem( nWhich );
     301             : 
     302      182677 :                             Changed( *pItemToClear, rNew );
     303             :                         }
     304      205171 :                         if ( pItemToClear->Which() )
     305      205171 :                             m_pPool->Remove( *pItemToClear );
     306             :                     }
     307      205171 :                     ++nDel;
     308             :                 }
     309             : 
     310             :                 // found => break
     311     3293599 :                 break;
     312             :             }
     313     3536841 :             ppFnd += *(pPtr+1) - *pPtr + 1;
     314     3536841 :             pPtr += 2;
     315             :         }
     316             :     }
     317             :     else
     318             :     {
     319      674584 :         nDel = m_nCount;
     320             : 
     321      674584 :         sal_uInt16* pPtr = m_pWhichRanges;
     322     8706388 :         while( *pPtr )
     323             :         {
     324    81204291 :             for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     325    73847071 :                 if( *ppFnd )
     326             :                 {
     327             :                     // Due to the assertions in the sub calls, we need to do this
     328     2407618 :                     --m_nCount;
     329     2407618 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     330     2407618 :                     *ppFnd = 0;
     331             : 
     332     2407618 :                     if ( !IsInvalidItem(pItemToClear) )
     333             :                     {
     334     2407461 :                         if ( nWhich <= SFX_WHICH_MAX )
     335             :                         {
     336             :                             const SfxPoolItem& rNew = m_pParent
     337     1134150 :                                     ? m_pParent->Get( nWhich, true )
     338     2984650 :                                     : m_pPool->GetDefaultItem( nWhich );
     339             : 
     340     1850500 :                             Changed( *pItemToClear, rNew );
     341             :                         }
     342             : 
     343             :                         // #i32448#
     344             :                         // Take care of disabled items, too.
     345     2407461 :                         if (!pItemToClear->m_nWhich)
     346             :                         {
     347             :                             // item is disabled, delete it
     348           0 :                             delete pItemToClear;
     349             :                         }
     350             :                         else
     351             :                         {
     352             :                             // remove item from pool
     353     2407461 :                             m_pPool->Remove( *pItemToClear );
     354             :                         }
     355             :                     }
     356             :                 }
     357     7357220 :             pPtr += 2;
     358             :         }
     359             :     }
     360     4076559 :     return nDel;
     361             : }
     362             : 
     363      214821 : void SfxItemSet::ClearInvalidItems( bool bHardDefault )
     364             : {
     365      214821 :     sal_uInt16* pPtr = m_pWhichRanges;
     366      214821 :     SfxItemArray ppFnd = m_pItems;
     367      214821 :     if ( bHardDefault )
     368           0 :         while( *pPtr )
     369             :         {
     370           0 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     371           0 :                 if ( IsInvalidItem(*ppFnd) )
     372           0 :                      *ppFnd = &m_pPool->Put( m_pPool->GetDefaultItem(nWhich) );
     373           0 :             pPtr += 2;
     374             :         }
     375             :     else
     376     3827565 :         while( *pPtr )
     377             :         {
     378    33223399 :             for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     379    29825476 :                 if( IsInvalidItem(*ppFnd) )
     380             :                 {
     381         759 :                     *ppFnd = 0;
     382         759 :                     --m_nCount;
     383             :                 }
     384     3397923 :             pPtr += 2;
     385             :         }
     386      214821 : }
     387             : 
     388           0 : void SfxItemSet::InvalidateDefaultItems()
     389             : {
     390           0 :     sal_uInt16* pPtr = m_pWhichRanges;
     391           0 :     SfxItemArray ppFnd = m_pItems;
     392             : 
     393           0 :     while( *pPtr )
     394             :     {
     395           0 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     396           0 :             if (*ppFnd && *ppFnd != reinterpret_cast<SfxPoolItem *>(-1)
     397           0 :                 && **ppFnd == m_pPool->GetDefaultItem(nWhich))
     398             :             {
     399           0 :                 m_pPool->Remove( **ppFnd );
     400           0 :                 *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
     401             :             }
     402           0 :         pPtr += 2;
     403             :     }
     404           0 : }
     405             : 
     406           0 : void SfxItemSet::InvalidateAllItems()
     407             : {
     408             :     assert( !m_nCount && "There are still Items set" );
     409           0 :     m_nCount = TotalCount();
     410           0 :     memset(static_cast<void*>(m_pItems), -1, m_nCount * sizeof(SfxPoolItem*));
     411           0 : }
     412             : 
     413   176419523 : SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
     414             :                                         bool bSrchInParent,
     415             :                                         const SfxPoolItem **ppItem ) const
     416             : {
     417             :     // Find the range in which the Which is located
     418   176419523 :     const SfxItemSet* pAktSet = this;
     419   176419523 :     SfxItemState eRet = SfxItemState::UNKNOWN;
     420   142026535 :     do
     421             :     {
     422   200899285 :         SfxItemArray ppFnd = pAktSet->m_pItems;
     423   200899285 :         const sal_uInt16* pPtr = pAktSet->m_pWhichRanges;
     424   200899285 :         if (pPtr)
     425             :         {
     426   580258036 :             while ( *pPtr )
     427             :             {
     428   364251400 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     429             :                 {
     430             :                     // Within this range
     431   185791934 :                     ppFnd += nWhich - *pPtr;
     432   185791934 :                     if ( !*ppFnd )
     433             :                     {
     434   155412085 :                         eRet = SfxItemState::DEFAULT;
     435   155412085 :                         if( !bSrchInParent )
     436    28492901 :                             return eRet; // Not present
     437   126919184 :                         break; // Keep searching in the parents!
     438             :                     }
     439             : 
     440    30379849 :                     if ( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd )
     441             :                         // Different ones are present
     442         477 :                         return SfxItemState::DONTCARE;
     443             : 
     444    30379372 :                     if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) )
     445       24515 :                         return SfxItemState::DISABLED;
     446             : 
     447    30354857 :                     if (ppItem)
     448             :                     {
     449    17463516 :                         *ppItem = *ppFnd;
     450             :                     }
     451    30354857 :                     return SfxItemState::SET;
     452             :                 }
     453   178459466 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     454   178459466 :                 pPtr += 2;
     455             :             }
     456             :         }
     457   142026535 :     } while (bSrchInParent && nullptr != (pAktSet = pAktSet->m_pParent));
     458   117546773 :     return eRet;
     459             : }
     460             : 
     461     3686027 : bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
     462             : {
     463     3686027 :     bool bRet = SfxItemState::SET == GetItemState(nWhich, true, ppItem);
     464     3686027 :     if (!bRet && ppItem)
     465       35976 :         *ppItem = NULL;
     466     3686027 :     return bRet;
     467             : }
     468             : 
     469    37450958 : const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
     470             : {
     471    37450958 :     if ( !nWhich )
     472         112 :         return 0; //FIXME: Only because of Outliner bug
     473             : 
     474    37450846 :     SfxItemArray ppFnd = m_pItems;
     475    37450846 :     const sal_uInt16* pPtr = m_pWhichRanges;
     476   116313927 :     while( *pPtr )
     477             :     {
     478    74718988 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     479             :         {
     480             :             // Within this range
     481    33306753 :             ppFnd += nWhich - *pPtr;
     482    33306753 :             if( *ppFnd ) // Already one present
     483             :             {
     484             :                 // Same Item already present?
     485     8082644 :                 if ( *ppFnd == &rItem )
     486     5074561 :                     return 0;
     487             : 
     488             :                 // Will 'dontcare' or 'disabled' be overwritten with some real value?
     489     3008083 :                 if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
     490             :                 {
     491           9 :                     *ppFnd = &m_pPool->Put( rItem, nWhich );
     492           9 :                     return *ppFnd;
     493             :                 }
     494             : 
     495             :                 // Turns into disabled?
     496     3008074 :                 if( !rItem.Which() )
     497             :                 {
     498        1013 :                     *ppFnd = rItem.Clone(m_pPool);
     499        1013 :                     return 0;
     500             :                 }
     501             :                 else
     502             :                 {
     503             :                     // Same value already present?
     504     3007061 :                     if ( rItem == **ppFnd )
     505     1974469 :                         return 0;
     506             : 
     507             :                     // Add the new one, remove the old one
     508     1032592 :                     const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
     509     1032592 :                     const SfxPoolItem* pOld = *ppFnd;
     510     1032592 :                     *ppFnd = &rNew;
     511     1032592 :                     if(nWhich <= SFX_WHICH_MAX)
     512     1021958 :                         Changed( *pOld, rNew );
     513     1032592 :                     m_pPool->Remove( *pOld );
     514             :                 }
     515             :             }
     516             :             else
     517             :             {
     518    25224109 :                 ++m_nCount;
     519    25224109 :                 if( !rItem.Which() )
     520       18710 :                     *ppFnd = rItem.Clone(m_pPool);
     521             :                 else {
     522    25205399 :                     const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
     523    25205399 :                     *ppFnd = &rNew;
     524    25205399 :                     if (nWhich <= SFX_WHICH_MAX )
     525             :                     {
     526             :                         const SfxPoolItem& rOld = m_pParent
     527     3182887 :                             ? m_pParent->Get( nWhich, true )
     528    27512709 :                             : m_pPool->GetDefaultItem( nWhich );
     529    24329822 :                         Changed( rOld, rNew );
     530             :                     }
     531             :                 }
     532             :             }
     533             :             SFX_ASSERT( !m_pPool->IsItemFlag(nWhich, SfxItemPoolFlags::POOLABLE) ||
     534             :                         rItem.ISA(SfxSetItem) || **ppFnd == rItem,
     535             :                         nWhich, "putted Item unequal" );
     536    26256701 :             return *ppFnd;
     537             :         }
     538    41412235 :         ppFnd += *(pPtr+1) - *pPtr + 1;
     539    41412235 :         pPtr += 2;
     540             :     }
     541     4144093 :     return 0;
     542             : }
     543             : 
     544     2049769 : bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
     545             : {
     546     2049769 :     bool bRet = false;
     547     2049769 :     if( rSet.Count() )
     548             :     {
     549     1852328 :         SfxItemArray ppFnd = rSet.m_pItems;
     550     1852328 :         const sal_uInt16* pPtr = rSet.m_pWhichRanges;
     551    12931693 :         while ( *pPtr )
     552             :         {
     553   333971994 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     554   324744957 :                 if( *ppFnd )
     555             :                 {
     556    12095250 :                     if ( IsInvalidItem( *ppFnd ) )
     557             :                     {
     558          48 :                         if ( bInvalidAsDefault )
     559           0 :                             bRet |= 0 != ClearItem( nWhich );
     560             :                             // FIXME: Caused a SEGFAULT on non Windows-platforms:
     561             :                             // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     562             :                         else
     563          48 :                             InvalidateItem( nWhich );
     564             :                     }
     565             :                     else
     566    12095202 :                         bRet |= 0 != Put( **ppFnd, nWhich );
     567             :                 }
     568     9227037 :             pPtr += 2;
     569             :         }
     570             :     }
     571     2049769 :     return bRet;
     572             : }
     573             : 
     574             : /**
     575             :  * This method takes the Items from the 'rSet' and adds to '*this'.
     576             :  * Which ranges in '*this' that are non-existent in 'rSet' will not
     577             :  * be altered. The Which range of '*this' is also not changed.
     578             :  *
     579             :  * Items set in 'rSet' are also set in '*this'.
     580             :  * Default (0 pointer) and Invalid (-1 pointer) Items are processed
     581             :  * according to their parameter 'eDontCareAs' and 'eDefaultAs':
     582             :  *
     583             :  * SfxItemState::SET:       Hard set to the default of the Pool
     584             :  * SfxItemState::DEFAULT:   Deleted (0 pointer)
     585             :  * SfxItemState::DONTCARE:  Invalid (-1 pointer)
     586             :  *
     587             :  * NB: All other values for 'eDontCareAs' and 'eDefaultAs' are invalid
     588             :  */
     589        1921 : void SfxItemSet::PutExtended
     590             : (
     591             :     const SfxItemSet&   rSet,           // Source of the Items to be put
     592             :     SfxItemState        eDontCareAs,    // What will happen to the DontCare Items
     593             :     SfxItemState        eDefaultAs      // What will happen to the Default Items
     594             : )
     595             : {
     596             :     // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
     597        1921 :     SfxItemArray ppFnd = rSet.m_pItems;
     598        1921 :     const sal_uInt16* pPtr = rSet.m_pWhichRanges;
     599        5779 :     while ( *pPtr )
     600             :     {
     601      109453 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     602      107516 :             if( *ppFnd )
     603             :             {
     604        1951 :                 if ( IsInvalidItem( *ppFnd ) )
     605             :                 {
     606             :                     // Item ist DontCare:
     607           0 :                     switch ( eDontCareAs )
     608             :                     {
     609             :                         case SfxItemState::SET:
     610           0 :                             Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     611           0 :                             break;
     612             : 
     613             :                         case SfxItemState::DEFAULT:
     614           0 :                             ClearItem( nWhich );
     615           0 :                             break;
     616             : 
     617             :                         case SfxItemState::DONTCARE:
     618           0 :                             InvalidateItem( nWhich );
     619           0 :                             break;
     620             : 
     621             :                         default:
     622             :                             assert(!"invalid Argument for eDontCareAs");
     623             :                     }
     624             :                 }
     625             :                 else
     626             :                     // Item is set:
     627        1951 :                     Put( **ppFnd, nWhich );
     628             :             }
     629             :             else
     630             :             {
     631             :                 // Item is default:
     632      105565 :                 switch ( eDefaultAs )
     633             :                 {
     634             :                     case SfxItemState::SET:
     635      104789 :                         Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     636      104789 :                         break;
     637             : 
     638             :                     case SfxItemState::DEFAULT:
     639         776 :                         ClearItem( nWhich );
     640         776 :                         break;
     641             : 
     642             :                     case SfxItemState::DONTCARE:
     643           0 :                         InvalidateItem( nWhich );
     644           0 :                         break;
     645             : 
     646             :                     default:
     647             :                         assert(!"invalid Argument for eDefaultAs");
     648             :                 }
     649             :             }
     650        1937 :         pPtr += 2;
     651             :     }
     652        1921 : }
     653             : 
     654             : /**
     655             :  * Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of
     656             :  * items which are new ranges too.
     657             :  */
     658       37808 : void SfxItemSet::MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo )
     659             : {
     660             :     // special case: exactly one sal_uInt16 which is already included?
     661       37808 :     SfxItemState eItemState = GetItemState(nFrom, false);
     662       37808 :     if ( nFrom == nTo && ( eItemState == SfxItemState::DEFAULT || eItemState == SfxItemState::SET ) )
     663       37808 :         return;
     664             : 
     665             :     // merge new range
     666       37808 :     SfxUShortRanges aRanges( m_pWhichRanges );
     667       37808 :     aRanges += SfxUShortRanges( nFrom, nTo );
     668       37808 :     SetRanges( aRanges );
     669             : }
     670             : 
     671             : /**
     672             :  * Modifies the ranges of settable items. Keeps state of items which
     673             :  * are new ranges too.
     674             :  */
     675       37808 : void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
     676             : {
     677             :     // Identical Ranges?
     678       37808 :     if (m_pWhichRanges == pNewRanges)
     679           0 :         return;
     680       37808 :     const sal_uInt16* pOld = m_pWhichRanges;
     681       37808 :     const sal_uInt16* pNew = pNewRanges;
     682      207944 :     while ( *pOld == *pNew )
     683             :     {
     684      132328 :         if ( !*pOld && !*pNew )
     685           0 :             return;
     686      132328 :         ++pOld, ++pNew;
     687             :     }
     688             : 
     689             :     // create new item-array (by iterating through all new ranges)
     690       37808 :     sal_uLong        nSize = Capacity_Impl(pNewRanges);
     691       37808 :     SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ];
     692       37808 :     sal_uInt16 nNewCount = 0;
     693       37808 :     if (m_nCount == 0)
     694       37808 :         memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
     695             :     else
     696             :     {
     697           0 :         sal_uInt16 n = 0;
     698           0 :         for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
     699             :         {
     700             :             // iterate through all ids in the range
     701           0 :             for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
     702             :             {
     703             :                 // direct move of pointer (not via pool)
     704           0 :                 SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
     705           0 :                 if ( SfxItemState::SET == eState )
     706             :                 {
     707             :                     // increment new item count and possibly increment ref count
     708           0 :                     ++nNewCount;
     709           0 :                     aNewItems[n]->AddRef();
     710             :                 }
     711           0 :                 else if ( SfxItemState::DISABLED == eState )
     712             :                 {
     713             :                     // put "disabled" item
     714           0 :                     ++nNewCount;
     715           0 :                     aNewItems[n] = new SfxVoidItem(0);
     716             :                 }
     717           0 :                 else if ( SfxItemState::DONTCARE == eState )
     718             :                 {
     719           0 :                     ++nNewCount;
     720           0 :                     aNewItems[n] = reinterpret_cast<SfxPoolItem*>(-1);
     721             :                 }
     722             :                 else
     723             :                 {
     724             :                     // default
     725           0 :                     aNewItems[n] = 0;
     726             :                 }
     727             :             }
     728             :         }
     729             :         // free old items
     730           0 :         sal_uInt16 nOldTotalCount = TotalCount();
     731           0 :         for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
     732             :         {
     733           0 :             const SfxPoolItem *pItem = m_pItems[nItem];
     734           0 :             if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
     735           0 :                 m_pPool->Remove(*pItem);
     736             :         }
     737             :     }
     738             : 
     739             :     // replace old items-array and ranges
     740       37808 :     delete[] m_pItems;
     741       37808 :     m_pItems = aNewItems;
     742       37808 :     m_nCount = nNewCount;
     743             : 
     744       37808 :     if( pNewRanges == GetPool()->GetFrozenIdRanges() )
     745             :     {
     746           0 :         delete[] m_pWhichRanges;
     747           0 :         m_pWhichRanges = const_cast<sal_uInt16*>(pNewRanges);
     748             :     }
     749             :     else
     750             :     {
     751       37808 :         sal_uInt16 nCount = Count_Impl(pNewRanges) + 1;
     752       37808 :         if (m_pWhichRanges != m_pPool->GetFrozenIdRanges())
     753       37808 :             delete[] m_pWhichRanges;
     754       37808 :         m_pWhichRanges = new sal_uInt16[ nCount ];
     755       37808 :         memcpy( m_pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
     756             :     }
     757             : }
     758             : 
     759             : /**
     760             :  * The SfxItemSet takes over exactly those SfxPoolItems that are
     761             :  * set in rSet and are in their own Which range. All others are removed.
     762             :  * The SfxItemPool is retained, such that SfxPoolItems that have been
     763             :  * taken over, are moved from the rSet's SfxItemPool to the SfxItemPool
     764             :  * of *this.
     765             :  *
     766             :  * SfxPoolItems in rSet, for which holds 'IsInvalidItem() == true' are
     767             :  * taken over as invalid items.
     768             :  *
     769             :  * @return bool true
     770             :  *              SfxPoolItems have been taken over
     771             :  *
     772             :  *              false
     773             :  *              No SfxPoolItems have been taken over, because
     774             :  *              e.g. the Which ranges of SfxItemSets are not intersecting
     775             :  *              or the intersection does not contain SfxPoolItems that are
     776             :  *              set in rSet
     777             :  */
     778     1423034 : bool SfxItemSet::Set
     779             : (
     780             :     const SfxItemSet&   rSet,   /*  The SfxItemSet, whose SfxPoolItems are
     781             :                                     to been taken over */
     782             : 
     783             :     bool                bDeep   /*  true (default)
     784             : 
     785             :                                     The SfxPoolItems from the parents that may
     786             :                                     be present in rSet, are also taken over into
     787             :                                     this SfxPoolItemSet
     788             : 
     789             :                                     false
     790             :                                     The SfxPoolItems from the parents of
     791             :                                     rSet are not taken into account */
     792             : )
     793             : {
     794     1423034 :     bool bRet = false;
     795     1423034 :     if (m_nCount)
     796      262263 :         ClearItem();
     797     1423034 :     if ( bDeep )
     798             :     {
     799     1414661 :         SfxWhichIter aIter(*this);
     800     1414661 :         sal_uInt16 nWhich = aIter.FirstWhich();
     801    69881826 :         while ( nWhich )
     802             :         {
     803             :             const SfxPoolItem* pItem;
     804    67052504 :             if( SfxItemState::SET == rSet.GetItemState( nWhich, true, &pItem ) )
     805    11335987 :                 bRet |= 0 != Put( *pItem, pItem->Which() );
     806    67052504 :             nWhich = aIter.NextWhich();
     807     1414661 :         }
     808             :     }
     809             :     else
     810        8373 :         bRet = Put(rSet, false);
     811             : 
     812     1423034 :     return bRet;
     813             : }
     814             : 
     815             : /**
     816             :  * This method eases accessing single Items in the SfxItemSet.
     817             :  * Type checking is done via assertion, which makes client code
     818             :  * much more readable.
     819             :  *
     820             :  * The PRODUCT version returns 0, if the Item found is not of the
     821             :  * specified class.
     822             :  *
     823             :  * @returns 0 if the ItemSet does not contain an Item with the Id 'nWhich'
     824             :  */
     825      660069 : const SfxPoolItem* SfxItemSet::GetItem
     826             : (
     827             :     sal_uInt16          nId,            // SlotId or the Item's WhichId
     828             :     bool                bSrchInParent,  // sal_True: also search in Parent ItemSets
     829             :     TypeId              aItemType       // != 0 =>  RTTI check using assertion
     830             : )   const
     831             : {
     832             :     // Convert to WhichId
     833      660069 :     sal_uInt16 nWhich = GetPool()->GetWhich(nId);
     834             : 
     835             :     // Is the Item set or 'bDeep == true' available?
     836      660069 :     const SfxPoolItem *pItem = 0;
     837      660069 :     SfxItemState eState = GetItemState( nWhich, bSrchInParent, &pItem );
     838      660069 :     if ( bSrchInParent && SfxItemState::DEFAULT == eState &&
     839             :          nWhich <= SFX_WHICH_MAX )
     840             :     {
     841      412909 :         pItem = &m_pPool->GetDefaultItem(nWhich);
     842             :     }
     843             : 
     844      660069 :     if ( pItem )
     845             :     {
     846             :         // Does the type match?
     847      570301 :         if ( !aItemType || pItem->IsA(aItemType) )
     848      570301 :             return pItem;
     849             : 
     850             :         // Else report error
     851             :         assert(!"invalid argument type");
     852             :     }
     853             : 
     854             :     // No Item of wrong type found
     855       89768 :     return 0;
     856             : }
     857             : 
     858   270173723 : const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
     859             : {
     860             :     // Search the Range in which the Which is located in:
     861   270173723 :     const SfxItemSet* pAktSet = this;
     862   487285052 :     do
     863             :     {
     864   505172135 :         if( pAktSet->Count() )
     865             :         {
     866   278611111 :             SfxItemArray ppFnd = pAktSet->m_pItems;
     867   278611111 :             const sal_uInt16* pPtr = pAktSet->m_pWhichRanges;
     868   817437385 :             while( *pPtr )
     869             :             {
     870   538268741 :                 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     871             :                 {
     872             :                     // In this Range
     873   278053578 :                     ppFnd += nWhich - *pPtr;
     874   278053578 :                     if( *ppFnd )
     875             :                     {
     876    17887083 :                         if( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd ) {
     877             :                             //FIXME: The following code is duplicated further down
     878             :                             SFX_ASSERT(m_pPool, nWhich, "no Pool, but status is ambiguous");
     879             :                             //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
     880             :                             //!return aDefault;
     881         510 :                             return m_pPool->GetDefaultItem( nWhich );
     882             :                         }
     883             : #ifdef DBG_UTIL
     884             :                         const SfxPoolItem *pItem = *ppFnd;
     885             :                         if ( pItem->ISA(SfxVoidItem) || !pItem->Which() )
     886             :                             SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
     887             : #endif
     888    17886573 :                         return **ppFnd;
     889             :                     }
     890   260166495 :                     break; // Continue with Parent
     891             :                 }
     892   260215163 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     893   260215163 :                 pPtr += 2;
     894             :             }
     895             :         }
     896             : //TODO: Search until end of Range: What are we supposed to do now? To the Parent or Default??
     897             : //      if( !*pPtr )            // Until the end of the search Range?
     898             : //      break;
     899   487285052 :     } while (bSrchInParent && nullptr != (pAktSet = pAktSet->m_pParent));
     900             : 
     901             :     // Get the Default from the Pool and return
     902             :     SFX_ASSERT(m_pPool, nWhich, "no Pool, but status is ambiguous");
     903   252286640 :     const SfxPoolItem *pItem = &m_pPool->GetDefaultItem( nWhich );
     904   252286640 :     return *pItem;
     905             : }
     906             : 
     907             : /**
     908             :  * Notification callback
     909             :  */
     910    24991153 : void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
     911             : {
     912    24991153 : }
     913             : 
     914    18699946 : sal_uInt16 SfxItemSet::TotalCount() const
     915             : {
     916    18699946 :     sal_uInt16 nRet = 0;
     917    18699946 :     sal_uInt16* pPtr = m_pWhichRanges;
     918   112788035 :     while( *pPtr )
     919             :     {
     920    75388143 :         nRet += ( *(pPtr+1) - *pPtr ) + 1;
     921    75388143 :         pPtr += 2;
     922             :     }
     923    18699946 :     return nRet;
     924             : }
     925             : 
     926             : /**
     927             :  * Only retain the Items that are also present in rSet
     928             :  * (nevermind their value).
     929             :  */
     930       43374 : void SfxItemSet::Intersect( const SfxItemSet& rSet )
     931             : {
     932             :     assert(m_pPool && "Not implemented without Pool");
     933       43374 :     if( !Count() ) // None set?
     934       11803 :         return;
     935             : 
     936             :     // Delete all Items not contained in rSet
     937       31571 :     if( !rSet.Count() )
     938             :     {
     939           0 :         ClearItem(); // Delete everything
     940           0 :         return;
     941             :     }
     942             : 
     943             :     // Test whether the Which Ranges are different
     944       31571 :     bool bEqual = true;
     945       31571 :     sal_uInt16* pWh1 = m_pWhichRanges;
     946       31571 :     sal_uInt16* pWh2 = rSet.m_pWhichRanges;
     947       31571 :     sal_uInt16 nSize = 0;
     948             : 
     949      222337 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
     950             :     {
     951      190766 :         if( *pWh1 != *pWh2 )
     952             :         {
     953           0 :             bEqual = false;
     954           0 :             break;
     955             :         }
     956      190766 :         if( n & 1 )
     957       95383 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
     958             :     }
     959       31571 :     bEqual = *pWh1 == *pWh2; // Also check for 0
     960             : 
     961             :     // If the Ranges are identical, we can easily process it
     962       31571 :     if( bEqual )
     963             :     {
     964       31571 :         SfxItemArray ppFnd1 = m_pItems;
     965       31571 :         SfxItemArray ppFnd2 = rSet.m_pItems;
     966             : 
     967     2073555 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
     968     2041984 :             if( *ppFnd1 && !*ppFnd2 )
     969             :             {
     970             :                 // Delete from Pool
     971       39510 :                 if( !IsInvalidItem( *ppFnd1 ) )
     972             :                 {
     973       39510 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
     974       39510 :                     if(nWhich <= SFX_WHICH_MAX)
     975             :                     {
     976             :                         const SfxPoolItem& rNew = m_pParent
     977       39510 :                             ? m_pParent->Get( nWhich, true )
     978       79020 :                             : m_pPool->GetDefaultItem( nWhich );
     979             : 
     980       39510 :                         Changed( **ppFnd1, rNew );
     981             :                     }
     982       39510 :                     m_pPool->Remove( **ppFnd1 );
     983             :                 }
     984       39510 :                 *ppFnd1 = 0;
     985       39510 :                 --m_nCount;
     986             :             }
     987             :     }
     988             :     else
     989             :     {
     990           0 :         SfxItemIter aIter( *this );
     991           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
     992             :         while( true )
     993             :         {
     994           0 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
     995           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
     996           0 :                                 : pItem->Which();
     997           0 :             if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
     998           0 :                 ClearItem( nWhich );        // Delete
     999           0 :             if( aIter.IsAtEnd() )
    1000           0 :                 break;
    1001           0 :             pItem = aIter.NextItem();
    1002           0 :         }
    1003             :     }
    1004             : }
    1005             : 
    1006      993002 : void SfxItemSet::Differentiate( const SfxItemSet& rSet )
    1007             : {
    1008      993002 :     if( !Count() || !rSet.Count() )// None set?
    1009     1256762 :         return;
    1010             : 
    1011             :    // Test whether the Which Ranges are different
    1012      729242 :     bool bEqual = true;
    1013      729242 :     sal_uInt16* pWh1 = m_pWhichRanges;
    1014      729242 :     sal_uInt16* pWh2 = rSet.m_pWhichRanges;
    1015      729242 :     sal_uInt16 nSize = 0;
    1016             : 
    1017     1569210 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1018             :     {
    1019     1497012 :         if( *pWh1 != *pWh2 )
    1020             :         {
    1021      657044 :             bEqual = false;
    1022      657044 :             break;
    1023             :         }
    1024      839968 :         if( n & 1 )
    1025      419984 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1026             :     }
    1027      729242 :     bEqual = *pWh1 == *pWh2; // Also test for 0
    1028             : 
    1029             :     // If the Ranges are identical, we can easily process it
    1030      729242 :     if( bEqual )
    1031             :     {
    1032       72198 :         SfxItemArray ppFnd1 = m_pItems;
    1033       72198 :         SfxItemArray ppFnd2 = rSet.m_pItems;
    1034             : 
    1035     7324295 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1036     7252097 :             if( *ppFnd1 && *ppFnd2 )
    1037             :             {
    1038             :                 // Delete from Pool
    1039       59564 :                 if( !IsInvalidItem( *ppFnd1 ) )
    1040             :                 {
    1041       59564 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
    1042       59564 :                     if(nWhich <= SFX_WHICH_MAX)
    1043             :                     {
    1044             :                         const SfxPoolItem& rNew = m_pParent
    1045           0 :                             ? m_pParent->Get( nWhich, true )
    1046       59564 :                             : m_pPool->GetDefaultItem( nWhich );
    1047             : 
    1048       59564 :                         Changed( **ppFnd1, rNew );
    1049             :                     }
    1050       59564 :                     m_pPool->Remove( **ppFnd1 );
    1051             :                 }
    1052       59564 :                 *ppFnd1 = 0;
    1053       59564 :                 --m_nCount;
    1054             :             }
    1055             :     }
    1056             :     else
    1057             :     {
    1058      657044 :         SfxItemIter aIter( *this );
    1059      657044 :         const SfxPoolItem* pItem = aIter.GetCurItem();
    1060             :         while( true )
    1061             :         {
    1062      690520 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
    1063           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
    1064      690520 :                                 : pItem->Which();
    1065      690520 :             if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
    1066       37757 :                 ClearItem( nWhich ); // Delete
    1067      690520 :             if( aIter.IsAtEnd() )
    1068      657044 :                 break;
    1069       33476 :             pItem = aIter.NextItem();
    1070      657044 :         }
    1071             : 
    1072             :     }
    1073             : }
    1074             : 
    1075             : /**
    1076             :  * Decision table for MergeValue(s)
    1077             :  *
    1078             :  * Principles:
    1079             :  * 1. If the Which value in the 1st set is "unknown", there's never any action
    1080             :  * 2. If the Which value in the 2nd set is "unknown", it's made the "default"
    1081             :  * 3. For comparisons the values of the "default" Items are take into account
    1082             :  *
    1083             :  * 1st Item    2nd Item    Values  bIgnoreDefs       Remove      Assign       Add
    1084             :  *
    1085             :  * set         set         ==      sal_False           -           -           -
    1086             :  * default     set         ==      sal_False           -           -           -
    1087             :  * dontcare    set         ==      sal_False           -           -           -
    1088             :  * unknown     set         ==      sal_False           -           -           -
    1089             :  * set         default     ==      sal_False           -           -           -
    1090             :  * default     default     ==      sal_False           -           -           -
    1091             :  * dontcare    default     ==      sal_False           -           -           -
    1092             :  * unknown     default     ==      sal_False           -           -           -
    1093             :  * set         dontcare    ==      sal_False        1st Item       -1          -
    1094             :  * default     dontcare    ==      sal_False           -           -1          -
    1095             :  * dontcare    dontcare    ==      sal_False           -           -           -
    1096             :  * unknown     dontcare    ==      sal_False           -           -           -
    1097             :  * set         unknown     ==      sal_False        1st Item       -1          -
    1098             :  * default     unknown     ==      sal_False           -           -           -
    1099             :  * dontcare    unknown     ==      sal_False           -           -           -
    1100             :  * unknown     unknown     ==      sal_False           -           -           -
    1101             :  *
    1102             :  * set         set         !=      sal_False        1st Item       -1          -
    1103             :  * default     set         !=      sal_False           -           -1          -
    1104             :  * dontcare    set         !=      sal_False           -           -           -
    1105             :  * unknown     set         !=      sal_False           -           -           -
    1106             :  * set         default     !=      sal_False        1st Item       -1          -
    1107             :  * default     default     !=      sal_False           -           -           -
    1108             :  * dontcare    default     !=      sal_False           -           -           -
    1109             :  * unknown     default     !=      sal_False           -           -           -
    1110             :  * set         dontcare    !=      sal_False        1st Item       -1          -
    1111             :  * default     dontcare    !=      sal_False           -           -1          -
    1112             :  * dontcare    dontcare    !=      sal_False           -           -           -
    1113             :  * unknown     dontcare    !=      sal_False           -           -           -
    1114             :  * set         unknown     !=      sal_False        1st Item       -1          -
    1115             :  * default     unknown     !=      sal_False           -           -           -
    1116             :  * dontcare    unknown     !=      sal_False           -           -           -
    1117             :  * unknown     unknown     !=      sal_False           -           -           -
    1118             :  *
    1119             :  * set         set         ==      sal_True            -           -           -
    1120             :  * default     set         ==      sal_True            -       2nd Item     2nd Item
    1121             :  * dontcare    set         ==      sal_True            -           -           -
    1122             :  * unknown     set         ==      sal_True            -           -           -
    1123             :  * set         default     ==      sal_True            -           -           -
    1124             :  * default     default     ==      sal_True            -           -           -
    1125             :  * dontcare    default     ==      sal_True            -           -           -
    1126             :  * unknown     default     ==      sal_True            -           -           -
    1127             :  * set         dontcare    ==      sal_True            -           -           -
    1128             :  * default     dontcare    ==      sal_True            -           -1          -
    1129             :  * dontcare    dontcare    ==      sal_True            -           -           -
    1130             :  * unknown     dontcare    ==      sal_True            -           -           -
    1131             :  * set         unknown     ==      sal_True            -           -           -
    1132             :  * default     unknown     ==      sal_True            -           -           -
    1133             :  * dontcare    unknown     ==      sal_True            -           -           -
    1134             :  * unknown     unknown     ==      sal_True            -           -           -
    1135             :  *
    1136             :  * set         set         !=      sal_True         1st Item       -1          -
    1137             :  * default     set         !=      sal_True            -        2nd Item    2nd Item
    1138             :  * dontcare    set         !=      sal_True            -           -           -
    1139             :  * unknown     set         !=      sal_True            -           -           -
    1140             :  * set         default     !=      sal_True            -           -           -
    1141             :  * default     default     !=      sal_True            -           -           -
    1142             :  * dontcare    default     !=      sal_True            -           -           -
    1143             :  * unknown     default     !=      sal_True            -           -           -
    1144             :  * set         dontcare    !=      sal_True         1st Item       -1          -
    1145             :  * default     dontcare    !=      sal_True            -           -1          -
    1146             :  * dontcare    dontcare    !=      sal_True            -           -           -
    1147             :  * unknown     dontcare    !=      sal_True            -           -           -
    1148             :  * set         unknown     !=      sal_True            -           -           -
    1149             :  * default     unknown     !=      sal_True            -           -           -
    1150             :  * dontcare    unknown     !=      sal_True            -           -           -
    1151             :  * unknown     unknown     !=      sal_True            -           -           -
    1152             :  */
    1153      423914 : static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
    1154             :                             const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
    1155             :                             bool bIgnoreDefaults )
    1156             : {
    1157             :     assert(ppFnd1 != 0 && "Merging to 0-Item");
    1158             : 
    1159             :     // 1st Item is Default?
    1160      423914 :     if ( !*ppFnd1 )
    1161             :     {
    1162      360165 :         if ( IsInvalidItem(pFnd2) )
    1163             :             // Decision table: default, dontcare, doesn't matter, doesn't matter
    1164          48 :             *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1165             : 
    1166      360139 :         else if ( pFnd2 && !bIgnoreDefaults &&
    1167          22 :                   _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
    1168             :             // Decision table: default, set, !=, sal_False
    1169          22 :             *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1170             : 
    1171      360095 :         else if ( pFnd2 && bIgnoreDefaults )
    1172             :             // Decision table: default, set, doesn't matter, sal_True
    1173        4664 :             *ppFnd1 = &_pPool->Put( *pFnd2 );
    1174             : 
    1175      360165 :         if ( *ppFnd1 )
    1176        4734 :             ++rCount;
    1177             :     }
    1178             : 
    1179             :     // 1st Item set?
    1180       63749 :     else if ( !IsInvalidItem(*ppFnd1) )
    1181             :     {
    1182       49203 :         if ( !pFnd2 )
    1183             :         {
    1184             :             // 2nd Item is Default
    1185        1514 :             if ( !bIgnoreDefaults &&
    1186         757 :                  **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
    1187             :             {
    1188             :                 // Decision table: set, default, !=, sal_False
    1189         755 :                 _pPool->Remove( **ppFnd1 );
    1190         755 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1191             :             }
    1192             :         }
    1193       48446 :         else if ( IsInvalidItem(pFnd2) )
    1194             :         {
    1195             :             // 2nd Item is dontcare
    1196          96 :             if ( !bIgnoreDefaults ||
    1197           0 :                  **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
    1198             :             {
    1199             :                 // Decision table: set, dontcare, doesn't matter, sal_False
    1200             :                 // or:             set, dontcare, !=, sal_True
    1201          96 :                 _pPool->Remove( **ppFnd1 );
    1202          96 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1203             :             }
    1204             :         }
    1205             :         else
    1206             :         {
    1207             :             // 2nd Item is set
    1208       48350 :             if ( **ppFnd1 != *pFnd2 )
    1209             :             {
    1210             :                 // Decision table: set, set, !=, doesn't matter
    1211         432 :                 _pPool->Remove( **ppFnd1 );
    1212         432 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1213             :             }
    1214             :         }
    1215             :     }
    1216      423914 : }
    1217             : 
    1218        8186 : void SfxItemSet::MergeValues( const SfxItemSet& rSet, bool bIgnoreDefaults )
    1219             : {
    1220             :     // WARNING! When making changes/fixing bugs, always update the table above!!
    1221             :     assert( GetPool() == rSet.GetPool() && "MergeValues with different Pools" );
    1222             : 
    1223             :     // Test if the which Ranges are different
    1224        8186 :     bool bEqual = true;
    1225        8186 :     sal_uInt16* pWh1 = m_pWhichRanges;
    1226        8186 :     sal_uInt16* pWh2 = rSet.m_pWhichRanges;
    1227        8186 :     sal_uInt16 nSize = 0;
    1228             : 
    1229       37022 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1230             :     {
    1231       28836 :         if( *pWh1 != *pWh2 )
    1232             :         {
    1233           0 :             bEqual = false;
    1234           0 :             break;
    1235             :         }
    1236       28836 :         if( n & 1 )
    1237       14418 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1238             :     }
    1239        8186 :     bEqual = *pWh1 == *pWh2; // Also check for 0
    1240             : 
    1241             :     // If the Ranges match, they are easier to process!
    1242        8186 :     if( bEqual )
    1243             :     {
    1244        8186 :         SfxItemArray ppFnd1 = m_pItems;
    1245        8186 :         SfxItemArray ppFnd2 = rSet.m_pItems;
    1246             : 
    1247      427436 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1248      419250 :             MergeItem_Impl(m_pPool, m_nCount, ppFnd1, *ppFnd2, bIgnoreDefaults);
    1249             :     }
    1250             :     else
    1251             :     {
    1252           0 :         SfxWhichIter aIter( rSet );
    1253             :         sal_uInt16 nWhich;
    1254           0 :         while( 0 != ( nWhich = aIter.NextWhich() ) )
    1255             :         {
    1256           0 :             const SfxPoolItem* pItem = 0;
    1257           0 :             rSet.GetItemState( nWhich, true, &pItem );
    1258           0 :             if( !pItem )
    1259             :             {
    1260             :                 // Not set, so default
    1261           0 :                 if ( !bIgnoreDefaults )
    1262           0 :                     MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ), bIgnoreDefaults );
    1263             :             }
    1264           0 :             else if( IsInvalidItem( pItem ) )
    1265             :                 // dont care
    1266           0 :                 InvalidateItem( nWhich );
    1267             :             else
    1268           0 :                 MergeValue( *pItem, bIgnoreDefaults );
    1269           0 :         }
    1270             :     }
    1271        8186 : }
    1272             : 
    1273        4664 : void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
    1274             : {
    1275        4664 :     SfxItemArray ppFnd = m_pItems;
    1276        4664 :     const sal_uInt16* pPtr = m_pWhichRanges;
    1277        4664 :     const sal_uInt16 nWhich = rAttr.Which();
    1278       11088 :     while( *pPtr )
    1279             :     {
    1280             :         // In this Range??
    1281        6424 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1282             :         {
    1283        4664 :             ppFnd += nWhich - *pPtr;
    1284        4664 :             MergeItem_Impl(m_pPool, m_nCount, ppFnd, &rAttr, bIgnoreDefaults);
    1285        4664 :             break;
    1286             :         }
    1287        1760 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1288        1760 :         pPtr += 2;
    1289             :     }
    1290        4664 : }
    1291             : 
    1292        6820 : void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
    1293             : {
    1294        6820 :     SfxItemArray ppFnd = m_pItems;
    1295        6820 :     const sal_uInt16* pPtr = m_pWhichRanges;
    1296       29430 :     while( *pPtr )
    1297             :     {
    1298       17742 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1299             :         {
    1300             :             // In this Range?
    1301        1952 :             ppFnd += nWhich - *pPtr;
    1302             : 
    1303        1952 :             if( *ppFnd ) // Set for me
    1304             :             {
    1305        1013 :                 if( reinterpret_cast<SfxPoolItem*>(-1) != *ppFnd ) // Not yet dontcare!
    1306             :                 {
    1307         503 :                     m_pPool->Remove( **ppFnd );
    1308         503 :                     *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
    1309             :                 }
    1310             :             }
    1311             :             else
    1312             :             {
    1313         939 :                 *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
    1314         939 :                 ++m_nCount;
    1315             :             }
    1316        1952 :             break;
    1317             :         }
    1318       15790 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1319       15790 :         pPtr += 2;
    1320             :     }
    1321        6820 : }
    1322             : 
    1323      220580 : sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
    1324             : {
    1325      220580 :     sal_uInt16 n = 0;
    1326      220580 :     sal_uInt16* pPtr = m_pWhichRanges;
    1327      696393 :     while( *pPtr )
    1328             :     {
    1329      475813 :         n = ( *(pPtr+1) - *pPtr ) + 1;
    1330      475813 :         if( nPos < n )
    1331      220580 :             return *(pPtr)+nPos;
    1332      255233 :         nPos = nPos - n;
    1333      255233 :         pPtr += 2;
    1334             :     }
    1335             :     assert(false);
    1336           0 :     return 0;
    1337             : }
    1338             : 
    1339             : /**
    1340             :  * Saves the SfxItemSet instance to the supplied Stream.
    1341             :  * The surrogates as well as the ones with 'bDirect == true' are saved
    1342             :  * to the stream in the following way:
    1343             :  *
    1344             :  *  sal_uInt16  ... Count of the set Items
    1345             :  *  Count*  m_pPool->StoreItem()
    1346             :  *
    1347             :  *  @see SfxItemPool::StoreItem() const
    1348             :  *  @see SfxItemSet::Load(SvStream&,bool,const SfxItemPool*)
    1349             :  */
    1350        6402 : SvStream &SfxItemSet::Store
    1351             : (
    1352             :     SvStream&   rStream,        // Target stream for normal Items
    1353             :     bool        bDirect         /* true: Save Items directly
    1354             :                                    false: Surrogates */
    1355             : )   const
    1356             : {
    1357             :     assert(m_pPool);
    1358             : 
    1359             :     // Remember position of the count (to be able to correct it, if need be)
    1360        6402 :     sal_uLong nCountPos = rStream.Tell();
    1361        6402 :     rStream.WriteUInt16( m_nCount );
    1362             : 
    1363             :     // If there's nothing to save, don't construct an ItemIter
    1364        6402 :     if (m_nCount)
    1365             :     {
    1366             :         // Keep record of how many Items are really saved
    1367         368 :         sal_uInt16 nWrittenCount = 0; // Count of Items streamed in 'rStream'
    1368             : 
    1369             :         // Iterate over all set Items
    1370         368 :         SfxItemIter aIter(*this);
    1371       10332 :         for ( const SfxPoolItem *pItem = aIter.FirstItem();
    1372             :               pItem;
    1373             :               pItem = aIter.NextItem() )
    1374             :         {
    1375             :             // Let Items (if need be as a Surrogate) be saved via Pool
    1376             :             SAL_WARN_IF(IsInvalidItem(pItem), "svl.items", "can't store invalid items");
    1377       19928 :             if ( !IsInvalidItem(pItem) &&
    1378        9964 :                  m_pPool->StoreItem( rStream, *pItem, bDirect ) )
    1379             :                 // Item was streamed in 'rStream'
    1380        9964 :                 ++nWrittenCount;
    1381             :         }
    1382             : 
    1383             :         // Fewer written than read (e.g. old format)
    1384         368 :         if (nWrittenCount != m_nCount)
    1385             :         {
    1386             :             // Store real count in the stream
    1387           0 :             sal_uLong nPos = rStream.Tell();
    1388           0 :             rStream.Seek( nCountPos );
    1389           0 :             rStream.WriteUInt16( nWrittenCount );
    1390           0 :             rStream.Seek( nPos );
    1391         368 :         }
    1392             :     }
    1393             : 
    1394        6402 :     return rStream;
    1395             : }
    1396             : 
    1397             : /**
    1398             :  * This method loads an SfxItemSet from a stream.
    1399             :  * If the SfxItemPool was loaded without RefCounts the loaded Item
    1400             :  * references are counted, else we assume the they were accounted for
    1401             :  * when loadig the SfxItemPool.
    1402             :  *
    1403             :  * @see SfxItemSet::Store(Stream&,bool) const
    1404             :  */
    1405           0 : SvStream &SfxItemSet::Load
    1406             : (
    1407             :     SvStream&           rStream,    //  Stream we're loading from
    1408             : 
    1409             :     bool                bDirect,    /*  true
    1410             :                                         Items are directly read form the stream
    1411             :                                         and not via Surrogates
    1412             : 
    1413             :                                         false (default)
    1414             :                                         Items are read via Surrogates */
    1415             : 
    1416             :     const SfxItemPool*  pRefPool    /*  Pool that can resolve the Surrogates
    1417             :                                         (e.g. when inserting documents) */
    1418             : )
    1419             : {
    1420             :     assert(m_pPool);
    1421             : 
    1422             :     // No RefPool => Resolve Surrogates with ItemSet's Pool
    1423           0 :     if ( !pRefPool )
    1424           0 :         pRefPool = m_pPool;
    1425             : 
    1426             :     // Load Item count and as many Items
    1427           0 :     sal_uInt16 nCount = 0;
    1428           0 :     rStream.ReadUInt16( nCount );
    1429             : 
    1430           0 :     const size_t nMinRecordSize = sizeof(sal_uInt16) * 2;
    1431           0 :     const size_t nMaxRecords = rStream.remainingSize() / nMinRecordSize;
    1432           0 :     if (nCount > nMaxRecords)
    1433             :     {
    1434             :         SAL_WARN("svl", "Parsing error: " << nMaxRecords <<
    1435             :                  " max possible entries, but " << nCount << " claimed, truncating");
    1436           0 :         nCount = nMaxRecords;
    1437             :     }
    1438             : 
    1439           0 :     for ( sal_uInt16 i = 0; i < nCount; ++i )
    1440             :     {
    1441             :         // Load Surrogate/Item and resolve Surrogate
    1442             :         const SfxPoolItem *pItem =
    1443           0 :                 m_pPool->LoadItem( rStream, bDirect, pRefPool );
    1444             : 
    1445             :         // Did we load an Item or resolve a Surrogate?
    1446           0 :         if ( pItem )
    1447             :         {
    1448             :             // Find position for Item pointer in the set
    1449           0 :             sal_uInt16 nWhich = pItem->Which();
    1450           0 :             SfxItemArray ppFnd = m_pItems;
    1451           0 :             const sal_uInt16* pPtr = m_pWhichRanges;
    1452           0 :             while ( *pPtr )
    1453             :             {
    1454             :                 // In this Range??
    1455           0 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1456             :                 {
    1457             :                     // Remember Item pointer in the set
    1458           0 :                     ppFnd += nWhich - *pPtr;
    1459             :                     SFX_ASSERT( !*ppFnd, nWhich, "Item is present twice");
    1460           0 :                     *ppFnd = pItem;
    1461           0 :                     ++m_nCount;
    1462           0 :                     break;
    1463             :                 }
    1464             : 
    1465             :                 // In the range array and Item array to the next Which range
    1466           0 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
    1467           0 :                 pPtr += 2;
    1468             :             }
    1469             :         }
    1470             :     }
    1471             : 
    1472           0 :     return rStream;
    1473             : }
    1474             : 
    1475     1104257 : bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
    1476             : {
    1477             :     // Values we can get quickly need to be the same
    1478     3311085 :     if ( m_pParent != rCmp.m_pParent ||
    1479     1980705 :          m_pPool != rCmp.m_pPool ||
    1480      876448 :          Count() != rCmp.Count() )
    1481      562119 :         return false;
    1482             : 
    1483             :     // Counting Ranges takes longer; they also need to be the same, however
    1484      542138 :     sal_uInt16 nCount1 = TotalCount();
    1485      542138 :     sal_uInt16 nCount2 = rCmp.TotalCount();
    1486      542138 :     if ( nCount1 != nCount2 )
    1487        2202 :         return false;
    1488             : 
    1489             :     // Are the Ranges themselves unequal?
    1490     1147336 :     for (sal_uInt16 nRange = 0; m_pWhichRanges[nRange]; nRange += 2)
    1491             :     {
    1492     1214800 :         if (m_pWhichRanges[nRange] != rCmp.m_pWhichRanges[nRange] ||
    1493      607400 :             m_pWhichRanges[nRange+1] != rCmp.m_pWhichRanges[nRange+1])
    1494             :         {
    1495             :             // We must use the slow method then
    1496           0 :             SfxWhichIter aIter( *this );
    1497           0 :             for ( sal_uInt16 nWh = aIter.FirstWhich();
    1498             :                   nWh;
    1499             :                   nWh = aIter.NextWhich() )
    1500             :             {
    1501             :                 // If the pointer of the poolable Items are unequal, the Items must match
    1502           0 :                 const SfxPoolItem *pItem1 = 0, *pItem2 = 0;
    1503           0 :                 if ( GetItemState( nWh, false, &pItem1 ) !=
    1504           0 :                         rCmp.GetItemState( nWh, false, &pItem2 ) ||
    1505           0 :                      ( pItem1 != pItem2 &&
    1506           0 :                         ( !pItem1 || IsInvalidItem(pItem1) ||
    1507           0 :                           (m_pPool->IsItemFlag(*pItem1, SfxItemPoolFlags::POOLABLE) &&
    1508           0 :                             *pItem1 != *pItem2 ) ) ) )
    1509           0 :                     return false;
    1510             :             }
    1511             : 
    1512           0 :             return true;
    1513             :         }
    1514             :     }
    1515             : 
    1516             :     // Are all pointers the same?
    1517      539936 :     if (0 == memcmp( m_pItems, rCmp.m_pItems, nCount1 * sizeof(m_pItems[0]) ))
    1518      524082 :         return true;
    1519             : 
    1520             :     // We need to compare each one separately then
    1521       15854 :     const SfxPoolItem **ppItem1 = m_pItems;
    1522       15854 :     const SfxPoolItem **ppItem2 = rCmp.m_pItems;
    1523      243918 :     for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
    1524             :     {
    1525             :         // If the pointers of the poolable Items are not the same, the Items
    1526             :         // must match
    1527      282952 :         if ( *ppItem1 != *ppItem2 &&
    1528       76195 :              ( ( !*ppItem1 || !*ppItem2 ) ||
    1529       74709 :                ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
    1530       37183 :                (m_pPool->IsItemFlag(**ppItem1, SfxItemPoolFlags::POOLABLE)) ||
    1531       12280 :                  **ppItem1 != **ppItem2 ) )
    1532       14531 :             return false;
    1533             : 
    1534      228064 :         ++ppItem1;
    1535      228064 :         ++ppItem2;
    1536             :     }
    1537             : 
    1538        1323 :     return true;
    1539             : }
    1540             : 
    1541      730624 : SfxItemSet *SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1542             : {
    1543      730624 :     if (pToPool && pToPool != m_pPool)
    1544             :     {
    1545       13024 :         SfxItemSet *pNewSet = new SfxItemSet(*pToPool, m_pWhichRanges);
    1546       13024 :         if ( bItems )
    1547             :         {
    1548         327 :             SfxWhichIter aIter(*pNewSet);
    1549         327 :             sal_uInt16 nWhich = aIter.FirstWhich();
    1550        6324 :             while ( nWhich )
    1551             :             {
    1552             :                 const SfxPoolItem* pItem;
    1553        5670 :                 if ( SfxItemState::SET == GetItemState( nWhich, false, &pItem ) )
    1554           9 :                     pNewSet->Put( *pItem, pItem->Which() );
    1555        5670 :                 nWhich = aIter.NextWhich();
    1556         327 :             }
    1557             :         }
    1558       13024 :         return pNewSet;
    1559             :     }
    1560             :     else
    1561             :         return bItems
    1562      706608 :                 ? new SfxItemSet(*this)
    1563     1424208 :                 : new SfxItemSet(*m_pPool, m_pWhichRanges);
    1564             : }
    1565             : 
    1566     3586550 : void SfxItemSet::PutDirect(const SfxPoolItem &rItem)
    1567             : {
    1568     3586550 :     SfxItemArray ppFnd = m_pItems;
    1569     3586550 :     const sal_uInt16* pPtr = m_pWhichRanges;
    1570     3586550 :     const sal_uInt16 nWhich = rItem.Which();
    1571             : #ifdef DBG_UTIL
    1572             :     IsPoolDefaultItem(&rItem) || m_pPool->GetSurrogate(&rItem);
    1573             :         // Only cause assertion in the callees
    1574             : #endif
    1575     7962028 :     while( *pPtr )
    1576             :     {
    1577     4375478 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1578             :         {
    1579             :             // In this Range?
    1580     3586550 :             ppFnd += nWhich - *pPtr;
    1581     3586550 :             const SfxPoolItem* pOld = *ppFnd;
    1582     3586550 :             if( pOld ) // One already present
    1583             :             {
    1584         408 :                 if( rItem == **ppFnd )
    1585           0 :                     return; // Already present!
    1586         408 :                 m_pPool->Remove( *pOld );
    1587             :             }
    1588             :             else
    1589     3586142 :                 ++m_nCount;
    1590             : 
    1591             :             // Add the new one
    1592     3586550 :             if( IsPoolDefaultItem(&rItem) )
    1593      100898 :                 *ppFnd = &m_pPool->Put( rItem );
    1594             :             else
    1595             :             {
    1596     3485652 :                 *ppFnd = &rItem;
    1597     3485652 :                 if( !IsStaticDefaultItem( &rItem ) )
    1598     2043283 :                     rItem.AddRef();
    1599             :             }
    1600             : 
    1601     3586550 :             return;
    1602             :         }
    1603      788928 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1604      788928 :         pPtr += 2;
    1605             :     }
    1606             : }
    1607             : 
    1608           0 : sal_Int32 SfxItemSet::getHash() const
    1609             : {
    1610           0 :     return stringify().hashCode();
    1611             : }
    1612             : 
    1613           0 : OString SfxItemSet::stringify() const
    1614             : {
    1615           0 :     SvMemoryStream aStream;
    1616           0 :     SfxItemSet aSet(*this);
    1617           0 :     aSet.InvalidateDefaultItems();
    1618           0 :     aSet.Store(aStream, true);
    1619           0 :     aStream.Flush();
    1620             :     return OString(
    1621           0 :         static_cast<char const *>(aStream.GetData()), aStream.GetEndOfData());
    1622             : }
    1623             : 
    1624           0 : void SfxItemSet::dumpAsXml(xmlTextWriterPtr pWriter) const
    1625             : {
    1626           0 :     xmlTextWriterStartElement(pWriter, BAD_CAST("sfxItemSet"));
    1627           0 :     SfxItemIter aIter(*this);
    1628           0 :     for (const SfxPoolItem* pItem = aIter.FirstItem(); pItem; pItem = aIter.NextItem())
    1629           0 :          pItem->dumpAsXml(pWriter);
    1630           0 :     xmlTextWriterEndElement(pWriter);
    1631           0 : }
    1632             : 
    1633             : 
    1634             : // ----------------------------------------------- class SfxAllItemSet
    1635             : 
    1636       42635 : SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
    1637             : :   SfxItemSet(rPool, nullptr),
    1638             :     aDefault(0),
    1639       42635 :     nFree(nInitCount)
    1640             : {
    1641             :     // Initially no Items
    1642       42635 :     m_pItems = nullptr;
    1643             : 
    1644             :     // Allocate nInitCount pairs at USHORTs for Ranges
    1645       42635 :     m_pWhichRanges = new sal_uInt16[ nInitCount + 1 ];
    1646       42635 :     memset( m_pWhichRanges, 0, (nInitCount + 1) * sizeof(sal_uInt16) );
    1647       42635 : }
    1648             : 
    1649         727 : SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy)
    1650             : :   SfxItemSet(rCopy),
    1651             :     aDefault(0),
    1652         727 :     nFree(0)
    1653             : {
    1654         727 : }
    1655             : 
    1656             : /**
    1657             :  * Explicitly define this ctor to avoid auto-generation by the compiler.
    1658             :  * The compiler does not take the ctor with the 'const SfxItemSet&'!
    1659             :  */
    1660        4247 : SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy)
    1661             : :   SfxItemSet(rCopy),
    1662             :     aDefault(0),
    1663        4247 :     nFree(0)
    1664             : {
    1665        4247 : }
    1666             : 
    1667             : /**
    1668             :  * This internal function creates a new WhichRanges array, which is copied
    1669             :  * from the 'nOldSize'-USHORTs long 'pUS'. It has new USHORTs at the end instead
    1670             :  * of 'nIncr'.
    1671             :  * The terminating sal_uInt16 with the '0' is neither accounted for in 'nOldSize'
    1672             :  * nor in 'nIncr', but always explicitly added.
    1673             :  *
    1674             :  * @returns the new WhichRanges array (the old 'pUS' is freed)
    1675             :  */
    1676       13208 : static sal_uInt16 *AddRanges_Impl(
    1677             :     sal_uInt16 *pUS, std::ptrdiff_t nOldSize, sal_uInt16 nIncr)
    1678             : {
    1679             :     // Create new WhichRanges array
    1680       13208 :     sal_uInt16 *pNew = new sal_uInt16[ nOldSize + nIncr + 1 ];
    1681             : 
    1682             :     // Take over the old Ranges
    1683       13208 :     memcpy( pNew, pUS, nOldSize * sizeof(sal_uInt16) );
    1684             : 
    1685             :     // Initialize the new one to 0
    1686       13208 :     memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(sal_uInt16) );
    1687             : 
    1688             :     // Free the old array
    1689       13208 :     delete[] pUS;
    1690             : 
    1691       13208 :     return pNew;
    1692             : }
    1693             : 
    1694             : /**
    1695             :  * This internal function creates a new ItemArray, which is copied from 'pItems',
    1696             :  * but has room for a new ItemPointer at 'nPos'.
    1697             :  *
    1698             :  * @returns the new ItemArray (the old 'pItems' is freed)
    1699             :  */
    1700      122667 : static SfxItemArray AddItem_Impl(SfxItemArray pItems, sal_uInt16 nOldSize, sal_uInt16 nPos)
    1701             : {
    1702             :     // Create new ItemArray
    1703      122667 :     SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1];
    1704             : 
    1705             :     // Was there one before?
    1706      122667 :     if ( pItems )
    1707             :     {
    1708             :         // Copy all Items before nPos
    1709       95813 :         if ( nPos )
    1710       95813 :             memcpy( static_cast<void*>(pNew), pItems, nPos * sizeof(SfxPoolItem *) );
    1711             : 
    1712             :         // Copy all Items after nPos
    1713       95813 :         if ( nPos < nOldSize )
    1714        2356 :             memcpy( static_cast<void*>(pNew + nPos + 1), pItems + nPos,
    1715        3534 :                     (nOldSize-nPos) * sizeof(SfxPoolItem *) );
    1716             :     }
    1717             : 
    1718             :     // Initialize new Item
    1719      122667 :     *(pNew + nPos) = 0;
    1720             : 
    1721             :     // Free old ItemArray
    1722      122667 :     delete[] pItems;
    1723             : 
    1724      122667 :     return pNew;
    1725             : }
    1726             : 
    1727             : /**
    1728             :  * Putting with automatic extension of the WhichId with the ID of the Item.
    1729             :  */
    1730      160416 : const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
    1731             : {
    1732      160416 :     sal_uInt16 nPos = 0; // Position for 'rItem' in 'm_pItems'
    1733      160416 :     const sal_uInt16 nItemCount = TotalCount();
    1734             : 
    1735             :     // Let's see first whether there's a suitable Range already
    1736      160416 :     sal_uInt16 *pPtr = m_pWhichRanges;
    1737      816206 :     while ( *pPtr )
    1738             :     {
    1739             :         // WhichId is within this Range?
    1740      533123 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1741             :         {
    1742             :             // Insert
    1743       37749 :             nPos += nWhich - *pPtr;
    1744       37749 :             break;
    1745             :         }
    1746             : 
    1747             :         // Carry over the position of the Item in m_pItems
    1748      495374 :         nPos += *(pPtr+1) - *pPtr + 1;
    1749             : 
    1750             :         // To the next Range
    1751      495374 :         pPtr += 2;
    1752             :     }
    1753             : 
    1754             :     // WhichId not yet present?
    1755      160416 :     if ( !*pPtr )
    1756             :     {
    1757             :         // Let's see if we can attach it somewhere
    1758      122667 :         pPtr = m_pWhichRanges;
    1759      122667 :         nPos = 0;
    1760      594388 :         while ( *pPtr )
    1761             :         {
    1762             :             // WhichId is right before this Range?
    1763      350320 :             if ( (nWhich+1) == *pPtr )
    1764             :             {
    1765             :                 // Range grows downwards
    1766         579 :                 (*pPtr)--;
    1767             : 
    1768             :                 // Make room before first Item of this Range
    1769         579 :                 m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
    1770         579 :                 break;
    1771             :             }
    1772             : 
    1773             :             // WhichId is right after this Range?
    1774      349741 :             else if ( (nWhich-1) == *(pPtr+1) )
    1775             :             {
    1776             :                 // Range grows upwards?
    1777         687 :                 (*(pPtr+1))++;
    1778             : 
    1779             :                 // Make room after last Item of this Range
    1780         687 :                 nPos += nWhich - *pPtr;
    1781         687 :                 m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
    1782         687 :                 break;
    1783             :             }
    1784             : 
    1785             :             // Carry over position of the Item in m_pItems
    1786      349054 :             nPos += *(pPtr+1) - *pPtr + 1;
    1787             : 
    1788             :             // To the next Range
    1789      349054 :             pPtr += 2;
    1790             :         }
    1791             :     }
    1792             : 
    1793             :     // No extensible Range found?
    1794      160416 :     if ( !*pPtr )
    1795             :     {
    1796             :         // No room left in m_pWhichRanges? => Expand!
    1797      121401 :         std::ptrdiff_t nSize = pPtr - m_pWhichRanges;
    1798      121401 :         if( !nFree )
    1799             :         {
    1800       13208 :             m_pWhichRanges = AddRanges_Impl(m_pWhichRanges, nSize, nInitCount);
    1801       13208 :             nFree += nInitCount;
    1802             :         }
    1803             : 
    1804             :         // Attach new WhichRange
    1805      121401 :         pPtr = m_pWhichRanges + nSize;
    1806      121401 :         *pPtr++ = nWhich;
    1807      121401 :         *pPtr = nWhich;
    1808      121401 :         nFree -= 2;
    1809             : 
    1810             :         // Expand ItemArray
    1811      121401 :         nPos = nItemCount;
    1812      121401 :         m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
    1813             :     }
    1814             : 
    1815             :     // Add new Item to Pool
    1816      160416 :     const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
    1817             : 
    1818             :     // Remember old Item
    1819      160416 :     bool bIncrementCount = false;
    1820      160416 :     const SfxPoolItem* pOld = *( m_pItems + nPos );
    1821      160416 :     if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare"
    1822           0 :         pOld = NULL;
    1823      160416 :     if ( !pOld )
    1824             :     {
    1825      122701 :         bIncrementCount = true;
    1826             :         pOld = (m_pParent)
    1827           0 :             ? &m_pParent->Get( nWhich, true )
    1828             :             : ((nWhich <= SFX_WHICH_MAX)
    1829           1 :                     ? &m_pPool->GetDefaultItem(nWhich)
    1830      122702 :                     : nullptr);
    1831             :     }
    1832             : 
    1833             :     // Add new Item to ItemSet
    1834      160416 :     *(m_pItems + nPos) = &rNew;
    1835             : 
    1836             :     // Send Changed Notification
    1837      160416 :     if ( pOld )
    1838             :     {
    1839       37716 :         Changed( *pOld, rNew );
    1840       37716 :         if ( !IsDefaultItem(pOld) )
    1841       37715 :             m_pPool->Remove( *pOld );
    1842             :     }
    1843             : 
    1844      160416 :     if ( bIncrementCount )
    1845      122701 :         ++m_nCount;
    1846             : 
    1847      160416 :     return &rNew;
    1848             : }
    1849             : 
    1850             : /**
    1851             :  * Disable Item
    1852             :  * Using a VoidItem with Which value 0
    1853             :  */
    1854      351078 : void SfxItemSet::DisableItem(sal_uInt16 nWhich)
    1855             : {
    1856      351078 :     Put( SfxVoidItem(0), nWhich );
    1857      351078 : }
    1858             : 
    1859           0 : SfxItemSet *SfxAllItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1860             : {
    1861           0 :     if (pToPool && pToPool != m_pPool)
    1862             :     {
    1863           0 :         SfxAllItemSet *pNewSet = new SfxAllItemSet( *pToPool );
    1864           0 :         if ( bItems )
    1865           0 :             pNewSet->Set( *this );
    1866           0 :         return pNewSet;
    1867             :     }
    1868             :     else
    1869           0 :         return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*m_pPool);
    1870             : }
    1871             : 
    1872             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11