From a940ad1aa00c24cfafc1c108a2f0bdce6b5d7c53 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Mon, 9 Jun 2014 21:31:43 +0100 Subject: [PATCH] Re-factor and extend the work ... Change-Id: I06abdfffb1e57fe5ed9f4e5e1c1fe17e4f9870eb --- svl/source/inc/poolio.hxx | 183 ++++++++++++++------- svl/source/items/itempool.cxx | 364 ++++++++++++++++++++++-------------------- svl/source/items/poolio.cxx | 10 +- 3 files changed, 326 insertions(+), 231 deletions(-) diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx index a9073b5..83399bf 100644 --- a/svl/source/inc/poolio.hxx +++ b/svl/source/inc/poolio.hxx @@ -48,26 +48,15 @@ struct SfxPoolVersion_Impl {} }; -typedef std::vector SfxPoolItemArrayBase_Impl; -typedef boost::unordered_set< SfxPoolItem * > SfxPoolItemHashBase_Impl; - typedef boost::shared_ptr< SfxPoolVersion_Impl > SfxPoolVersion_ImplPtr; typedef std::deque< SfxPoolVersion_ImplPtr > SfxPoolVersionArr_Impl; -struct SfxPoolItemArray_Impl: public SfxPoolItemArrayBase_Impl -{ - size_t nFirstFree; - SfxPoolItemHashBase_Impl maHash; // hack for now ... - - SfxPoolItemArray_Impl () - : nFirstFree( 0 ) - {} -}; +class SfxPoolItemStore_Impl; struct SfxItemPool_Impl { SfxBroadcaster aBC; - std::vector maPoolItems; + std::vector maPoolItems; std::vector maSfxItemPoolUsers; /// ObjectUser section OUString aName; SfxPoolItem** ppPoolDefaults; @@ -90,52 +79,21 @@ struct SfxItemPool_Impl bool bStreaming; // in Load() bzw. Store() bool mbPersistentRefCounts; - SfxItemPool_Impl( SfxItemPool* pMaster, const OUString& rName, sal_uInt16 nStart, sal_uInt16 nEnd ) - : maPoolItems(nEnd - nStart + 1, static_cast(NULL)) - , aName(rName) - , ppPoolDefaults(new SfxPoolItem* [nEnd - nStart + 1]) - , ppStaticDefaults(0) - , mpMaster(pMaster) - , mpSecondary(NULL) - , mpPoolRanges(NULL) - , mnStart(nStart) - , mnEnd(nEnd) - , mnFileFormatVersion(0) - , nLoadingVersion(0) - , nInitRefCount(0) - , nVerStart(0) - , nVerEnd(0) - , nStoringStart(0) - , nStoringEnd(0) - , nMajorVer(0) - , nMinorVer(0) - , bInSetItem(false) - , bStreaming(false) - { - DBG_ASSERT(mnStart, "Start-Which-Id must be greater 0" ); - memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1)); - } + SfxItemPool_Impl( SfxItemPool* pMaster, const OUString& rName, sal_uInt16 nStart, sal_uInt16 nEnd ); + ~SfxItemPool_Impl(); - ~SfxItemPool_Impl() + void DeleteItems(); + void readTheItems(SvStream & rStream, sal_uInt32 nCount, sal_uInt16 nVersion, + SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** pArr); + + static sal_uLong AddRef( const SfxPoolItem& rItem, sal_uLong n = 1 ) { - DeleteItems(); + return SfxItemPool::AddRef( rItem, n ); } - - void DeleteItems() + static sal_uLong ReleaseRef( const SfxPoolItem& rItem, sal_uLong n = 1) { - std::vector::iterator itr = maPoolItems.begin(), itrEnd = maPoolItems.end(); - for (; itr != itrEnd; ++itr) - delete *itr; - maPoolItems.clear(); - - delete[] mpPoolRanges; - mpPoolRanges = NULL; - delete[] ppPoolDefaults; - ppPoolDefaults = NULL; + return SfxItemPool::ReleaseRef( rItem, n ); } - - void readTheItems(SvStream & rStream, sal_uInt32 nCount, sal_uInt16 nVersion, - SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** pArr); }; // ----------------------------------------------------------------------- @@ -219,4 +177,121 @@ struct SfxItemPool_Impl #define SFX_STYLES_REC_HEADER sal_uInt16(0x0010) #define SFX_STYLES_REC_STYLES sal_uInt16(0x0020) +/// Abstract base class for types of things we store in the pool +class SfxPoolItemStore_Impl +{ +protected: + void doReleaseItem( SfxPoolItem *&rpItem ) + { + SfxItemPool_Impl::ReleaseRef( *rpItem, 1 ); + + //! MI: Hack, solange wir das Problem mit dem Outliner haben + //! siehe anderes MI-REF + if ( 0 == rpItem->GetRefCount() && rpItem->Which() < 4000 ) + DELETEZ( rpItem ); + } + + SfxPoolItem *cloneItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) const + { + SfxPoolItem* pNewItem = rItem.Clone( pImp->mpMaster ); + pNewItem->SetWhich( nWhich ); + +#ifdef DBG_UTIL + SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" ) + if ( !rItem.ISA(SfxSetItem) ) + { + SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) || + rItem == *pNewItem, + nWhich, "unequal items in Put(): no operator==?" ); + SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) || + *pNewItem == rItem, + nWhich, "unequal items in Put(): no operator==?" ); + } +#endif + SfxItemPool_Impl::AddRef( *pNewItem, pImp->nInitRefCount ); + + return pNewItem; + } + +public: + SfxPoolItemStore_Impl() {} + virtual ~SfxPoolItemStore_Impl() {} + virtual void Delete() = 0; // FIXME merge with destructor ? + virtual bool RemoveItem( const SfxPoolItem *pItem ) = 0; + virtual const SfxPoolItem *PutItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) = 0; + // lame iterator API + virtual sal_uInt32 GetCount() const = 0; + virtual SfxPoolItem *GetItem( sal_uInt32 nOffset ) const = 0; +}; + +/** + * For storing re-usable (poolable) items inside the pool. + * + * typical usage is a linear scan looking for a duplicate. + */ +class SfxPoolItemArray_Impl : public SfxPoolItemStore_Impl +{ + typedef std::vector Array_Impl; + + Array_Impl maArray; + size_t nFirstFree; + +public: + SfxPoolItemArray_Impl () : nFirstFree( 0 ) {} + virtual ~SfxPoolItemArray_Impl() {} + + virtual void Delete() SAL_OVERRIDE; + virtual bool RemoveItem( const SfxPoolItem *pItem ) SAL_OVERRIDE; + virtual const SfxPoolItem *PutItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) SAL_OVERRIDE; + + virtual sal_uInt32 GetCount() const SAL_OVERRIDE + { + return maArray.size(); + } + + virtual SfxPoolItem *GetItem( sal_uInt32 nOffset ) const SAL_OVERRIDE + { + if ( nOffset < maArray.size() ) + return maArray[ nOffset ]; + else + return NULL; + } +}; + +/** + * For storing non-re-usable (!poolable) items + * + * typical usage is rapid insertion and removal of a large number + * of duplicate entries, with no need for comparison. + */ +class SfxPoolItemHash_Impl : public SfxPoolItemStore_Impl +{ + typedef boost::unordered_set< SfxPoolItem * > Hash_Impl; + Hash_Impl maHash; +public: + SfxPoolItemHash_Impl() {} + virtual ~SfxPoolItemHash_Impl() {} + + virtual void Delete() SAL_OVERRIDE; + virtual bool RemoveItem( const SfxPoolItem *pItem ) SAL_OVERRIDE; + virtual const SfxPoolItem *PutItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) SAL_OVERRIDE; + + virtual sal_uInt32 GetCount() const SAL_OVERRIDE + { + return maHash.size(); + } + virtual SfxPoolItem *GetItem( sal_uInt32 nOffset ) const SAL_OVERRIDE + { + if ( nOffset < maHash.size() ) + { + Hash_Impl::iterator it = maHash.begin(); + // FIXME: this is a really lame iteration API. + std::advance( it, nOffset ); + return *it; + } + else + return NULL; + } +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index 8d5c618..b91a0b5 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -279,7 +279,50 @@ SfxItemPool::SfxItemPool SetSecondaryPool( rPool.pImp->mpSecondary->Clone() ); } -// ----------------------------------------------------------------------- + +SfxItemPool_Impl::SfxItemPool_Impl( SfxItemPool* pMaster, const OUString& rName, sal_uInt16 nStart, sal_uInt16 nEnd ) + : maPoolItems(nEnd - nStart + 1, static_cast(NULL)) + , aName(rName) + , ppPoolDefaults(new SfxPoolItem* [nEnd - nStart + 1]) + , ppStaticDefaults(0) + , mpMaster(pMaster) + , mpSecondary(NULL) + , mpPoolRanges(NULL) + , mnStart(nStart) + , mnEnd(nEnd) + , mnFileFormatVersion(0) + , nLoadingVersion(0) + , nInitRefCount(0) + , nVerStart(0) + , nVerEnd(0) + , nStoringStart(0) + , nStoringEnd(0) + , nMajorVer(0) + , nMinorVer(0) + , bInSetItem(false) + , bStreaming(false) +{ + DBG_ASSERT(mnStart, "Start-Which-Id must be greater 0" ); + memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1)); +} + +SfxItemPool_Impl::~SfxItemPool_Impl() +{ + DeleteItems(); +} + +void SfxItemPool_Impl::DeleteItems() +{ + std::vector::iterator itr = maPoolItems.begin(), itrEnd = maPoolItems.end(); + for (; itr != itrEnd; ++itr) + delete *itr; + maPoolItems.clear(); + + delete[] mpPoolRanges; + mpPoolRanges = NULL; + delete[] ppPoolDefaults; + ppPoolDefaults = NULL; +} void SfxItemPool::SetDefaults( SfxPoolItem **pDefaults ) { @@ -558,7 +601,7 @@ void SfxItemPool::Delete() //MA 16. Apr. 97: Zweimal durchlaufen, in der ersten Runde fuer die SetItems. //Der Klarheit halber wird das jetzt in zwei besser lesbare Schleifen aufgeteilt. - std::vector::iterator itrItemArr = pImp->maPoolItems.begin(); + std::vector::iterator itrItemArr = pImp->maPoolItems.begin(); SfxPoolItem** ppDefaultItem = pImp->ppPoolDefaults; SfxPoolItem** ppStaticDefaultItem = pImp->ppStaticDefaults; sal_uInt16 nArrCnt; @@ -578,15 +621,7 @@ void SfxItemPool::Delete() { if ( *itrItemArr ) { - SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin(); - for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr ) - if (*ppHtArr) - { -#ifdef DBG_UTIL - ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() ); -#endif - delete *ppHtArr; - } + (*itrItemArr)->Delete(); DELETEZ( *itrItemArr ); } if ( *ppDefaultItem ) @@ -603,22 +638,14 @@ void SfxItemPool::Delete() itrItemArr = pImp->maPoolItems.begin(); ppDefaultItem = pImp->ppPoolDefaults; - //Jetzt die 'einfachen' Items + // Jetzt die 'einfachen' Items for ( nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++itrItemArr, ++ppDefaultItem ) { if ( *itrItemArr ) { - SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin(); - for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr ) - if (*ppHtArr) - { -#ifdef DBG_UTIL - ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() ); -#endif - delete *ppHtArr; - } + (*itrItemArr)->Delete(); DELETEZ( *itrItemArr ); } if ( *ppDefaultItem ) @@ -633,7 +660,34 @@ void SfxItemPool::Delete() pImp->DeleteItems(); } -// ---------------------------------------------------------------------- +void SfxPoolItemArray_Impl::Delete() +{ + for ( Array_Impl::iterator it = maArray.begin(); it != maArray.end(); ++it ) + { + if (*it) + { +#ifdef DBG_UTIL + ReleaseRef( **it, (*it)->GetRefCount() ); +#endif + delete *it; + } + } + maArray.clear(); + nFirstFree = 0; +} + +void SfxPoolItemHash_Impl::Delete() +{ + Hash_Impl::iterator it; + for (it = maHash.begin(); it != maHash.end(); ++it) + { +#ifdef DBG_UTIL + ReleaseRef( **it, (*it)->GetRefCount() ); +#endif + delete *it; + } + maHash.clear(); +} void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem) { @@ -722,93 +776,91 @@ const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich SFX_ASSERT( rItem.IsA(GetDefaultItem(nWhich).Type()), nWhich, "SFxItemPool: wrong item type in Put" ); - SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex]; + SfxPoolItemStore_Impl* pItemArr = pImp->maPoolItems[nIndex]; if (!pItemArr) { - pImp->maPoolItems[nIndex] = new SfxPoolItemArray_Impl; - pItemArr = pImp->maPoolItems[nIndex]; + bool bIsPoolable = IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ); + if (bIsPoolable) + pItemArr = new SfxPoolItemArray_Impl(); + else + pItemArr = new SfxPoolItemHash_Impl(); + pImp->maPoolItems[nIndex] = pItemArr; } - SfxPoolItemArrayBase_Impl::iterator ppFree; + // check life still makes some sense. + assert ( ( IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) && + dynamic_cast< SfxPoolItemArray_Impl *>( pItemArr ) ) || + ( !IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) && + dynamic_cast< SfxPoolItemHash_Impl *>( pItemArr ) ) ); + + const SfxPoolItem *pItem = pItemArr->PutItem( pImp, rItem, nWhich ); + assert ( pItem != NULL ); + return *pItem; +} + +const SfxPoolItem *SfxPoolItemArray_Impl::PutItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) +{ + Array_Impl::iterator itr, ppFree; bool ppFreeIsSet = false; - bool bIsPoolable = IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ); - if ( bIsPoolable ) + + // 1. if it's already in a pool, first just search by pointer + if ( IsPooledItem( &rItem ) ) { - // wenn es ueberhaupt gepoolt ist, koennte es schon drin sein - if ( IsPooledItem(&rItem) ) + itr = std::find( maArray.begin(), maArray.end(), &rItem ); + if (itr != maArray.end()) { - // 1. Schleife: teste ob der Pointer vorhanden ist. - SfxPoolItemArrayBase_Impl::iterator itr = - std::find(pItemArr->begin(), pItemArr->end(), &rItem); - if (itr != pItemArr->end()) - { - AddRef(**itr); - return **itr; - } + SfxItemPool_Impl::AddRef(**itr); + return *itr; } + } - // 2. Schleife: dann muessen eben die Attribute verglichen werden - SfxPoolItemArrayBase_Impl::iterator itr = pItemArr->begin(); - for (; itr != pItemArr->end(); ++itr) + // 2. search now by comparing attributes one by one for a match + itr = maArray.begin(); + for (; itr != maArray.end(); ++itr) + { + if (*itr) { - if (*itr) + if (**itr == rItem) { - if (**itr == rItem) - { - AddRef(**itr); - return **itr; - } + SfxItemPool_Impl::AddRef(**itr); + return *itr; } - else + } + else + { + if (!ppFreeIsSet) { - if (!ppFreeIsSet) - { - ppFree = itr; - ppFreeIsSet = true; - } + ppFree = itr; + ppFreeIsSet = true; } } } - // nicht vorhanden, also im PtrArray eintragen - SfxPoolItem* pNewItem = rItem.Clone(pImp->mpMaster); - pNewItem->SetWhich(nWhich); + SfxPoolItem* pNewItem = cloneItem( pImp, rItem, nWhich ); -#ifdef DBG_UTIL - SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" ) - if ( !rItem.ISA(SfxSetItem) ) + if ( ppFreeIsSet == false ) + maArray.push_back( pNewItem ); + else { - SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) || - rItem == *pNewItem, - nWhich, "unequal items in Put(): no operator==?" ); - SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) || - *pNewItem == rItem, - nWhich, "unequal items in Put(): no operator==?" ); + assert ( *ppFree == NULL ); + *ppFree = pNewItem; } -#endif - AddRef( *pNewItem, pImp->nInitRefCount ); - if ( bIsPoolable ) - { - if ( ppFreeIsSet == false ) - pItemArr->push_back( pNewItem ); - else - { - DBG_ASSERT( *ppFree == 0, "using surrogate in use" ); - *ppFree = pNewItem; - } - } - else // not poolable - whack it into the hash - { - assert( pItemArr->size() == 0); - // check we're not leaking refs ... - assert( pItemArr->maHash.find( pNewItem ) == pItemArr->maHash.end() ); - pItemArr->maHash.insert( pNewItem ); - } - return *pNewItem; + return pNewItem; } -// ----------------------------------------------------------------------- +const SfxPoolItem *SfxPoolItemHash_Impl::PutItem( SfxItemPool_Impl *pImp, const SfxPoolItem &rItem, sal_uInt16 nWhich ) +{ + // non-poolable no point in looking up, we always duplicate just insert. + SfxPoolItem* pNewItem = cloneItem( pImp, rItem, nWhich ); + + // check we're not leaking refs ... + assert( maHash.find( pNewItem ) == maHash.end() ); + + maHash.insert( pNewItem ); + + return pNewItem; +} void SfxItemPool::Remove( const SfxPoolItem& rItem ) { @@ -821,7 +873,7 @@ void SfxItemPool::Remove( const SfxPoolItem& rItem ) SFX_ASSERT( !IsPoolDefaultItem(&rItem), rItem.Which(), "wo kommt denn hier ein Pool-Default her" ); - // richtigen Secondary-Pool finden + // find the right Secondary Pool const sal_uInt16 nWhich = rItem.Which(); bool bSID = nWhich > SFX_WHICH_MAX; if ( !bSID && !IsInRange(nWhich) ) @@ -834,7 +886,7 @@ void SfxItemPool::Remove( const SfxPoolItem& rItem ) OSL_FAIL( "unknown Which-Id - cannot remove item" ); } - // SID oder nicht poolable (neue Definition)? + // SID is not poolable by the new definition. sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich); if ( bSID || IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) ) { @@ -849,76 +901,63 @@ void SfxItemPool::Remove( const SfxPoolItem& rItem ) return; } - SFX_ASSERT( rItem.GetRefCount(), rItem.Which(), "RefCount == 0, Remove unmoeglich" ); + assert( rItem.GetRefCount() > 0 ); - // statische Defaults sind eben einfach da + // don't try to remove / unref static defaults, they're always there. if ( rItem.GetKind() == SFX_ITEMS_STATICDEFAULT && &rItem == *( pImp->ppStaticDefaults + GetIndex_Impl(nWhich) ) ) return; - // Item im eigenen Pool suchen - SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex]; - SFX_ASSERT( pItemArr, rItem.Which(), "removing Item not in Pool" ); - - if ( pItemArr->maHash.size() == 0 ) - { - SfxPoolItemArrayBase_Impl::iterator ppHtArrBeg = pItemArr->begin(), ppHtArrEnd = pItemArr->end(); - for (SfxPoolItemArrayBase_Impl::iterator ppHtArr = ppHtArrBeg; ppHtArr != ppHtArrEnd; ++ppHtArr) - { - SfxPoolItem*& p = *ppHtArr; - if (p == &rItem) - { - if ( p->GetRefCount() ) //! - ReleaseRef( *p ); - else - { - SFX_ASSERT( 0, rItem.Which(), "removing Item without ref" ); - } + // Look for this item in the pool. + SfxPoolItemStore_Impl* pItemArr = pImp->maPoolItems[nIndex]; + assert ( pItemArr != NULL ); - // ggf. kleinstmoegliche freie Position merken - size_t nPos = std::distance(ppHtArrBeg, ppHtArr); - if ( pItemArr->nFirstFree > nPos ) - pItemArr->nFirstFree = nPos; + bool bRemoved = false; + if ( pItemArr ) + bRemoved = pItemArr->RemoveItem( &rItem ); + assert ( bRemoved ); (void) bRemoved; +} - //! MI: Hack, solange wir das Problem mit dem Outliner haben - //! siehe anderes MI-REF - if ( 0 == p->GetRefCount() && nWhich < 4000 ) - DELETEZ(p); - return; - } - } - } - else // the hash ! +bool SfxPoolItemArray_Impl::RemoveItem( const SfxPoolItem *pItem ) +{ + Array_Impl::iterator ppBegin = maArray.begin(), + ppEnd = maArray.end(); + for ( Array_Impl::iterator it = ppBegin; it != ppEnd; ++it ) { - SfxPoolItemHashBase_Impl::iterator it; - it = pItemArr->maHash.find( const_cast< SfxPoolItem *>( &rItem ) ); - if ( it != pItemArr->maHash.end() ) + SfxPoolItem*& p = *it; + if (p == pItem) { - SfxPoolItem* p = *it; - pItemArr->maHash.erase( it ); - assert (pItemArr->maHash.find( p ) == pItemArr->maHash.end() ); - - // Ugly cut/paste ... - if ( p->GetRefCount() ) //! - ReleaseRef( *p ); - else - { - SFX_ASSERT( false, rItem.Which(), "removing Item without ref" ); - } + doReleaseItem( p ); - //! MI: Hack, solange wir das Problem mit dem Outliner haben - //! siehe anderes MI-REF - if ( 0 == p->GetRefCount() && nWhich < 4000 ) - delete p; - return; + // store the position of the first hole + size_t nPos = std::distance( ppBegin, it ); + if ( nFirstFree > nPos ) + nFirstFree = nPos; + return true; } } - // nicht vorhanden - SFX_ASSERT( 0, rItem.Which(), "removing Item not in Pool" ); + return false; } -// ----------------------------------------------------------------------- +bool SfxPoolItemHash_Impl::RemoveItem( const SfxPoolItem *pItem ) +{ + Hash_Impl::iterator it; + it = maHash.find( const_cast< SfxPoolItem *>( pItem ) ); + + if ( it != maHash.end() ) + { + SfxPoolItem* p = *it; + maHash.erase( it ); + assert (maHash.find( p ) == maHash.end() ); + + doReleaseItem( p ); + + return true; + } + else + return false; +} const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const { @@ -1005,29 +1044,17 @@ const SfxPoolItem *SfxItemPool::GetItem2(sal_uInt16 nWhich, sal_uInt32 nOfst) co return 0; } - // dflt-Attribut? + // do we have a default attribute ? if ( nOfst == SFX_ITEMS_DEFAULT ) return *(pImp->ppStaticDefaults + GetIndex_Impl(nWhich)); - SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)]; + SfxPoolItemStore_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)]; if ( pItemArr ) - { - if ( nOfst < pItemArr->maHash.size() ) - { - SfxPoolItemHashBase_Impl::iterator it = pItemArr->maHash.begin(); - std::advance( it, nOfst ); // not the best iteration API in the world ... - return *it; - } - - if( nOfst < pItemArr->size() ) - return (*pItemArr)[nOfst]; // FIXME: URGH - what a hash ... - } - - return 0; + return pItemArr->GetItem( nOfst ); + else + return NULL; } -// ----------------------------------------------------------------------- - sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const { DBG_CHKTHIS(SfxItemPool, 0); @@ -1040,22 +1067,13 @@ sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const return 0; } - SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)]; + SfxPoolItemStore_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)]; if ( pItemArr ) - { - if ( pItemArr->maHash.size() ) - { - assert( pItemArr->size() == 0 ); - return pItemArr->maHash.size(); - } - else - return pItemArr->size(); - } - return 0; + return pItemArr->GetCount(); + else + return 0; } -// ----------------------------------------------------------------------- - sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const { if ( !IsSlot(nSlotId) ) diff --git a/svl/source/items/poolio.cxx b/svl/source/items/poolio.cxx index e4e0113..d0f8b69 100644 --- a/svl/source/items/poolio.cxx +++ b/svl/source/items/poolio.cxx @@ -170,7 +170,7 @@ SvStream &SfxItemPool::Store(SvStream &rStream) const { pImp->bInSetItem = ft != 0; - std::vector::iterator itrArr = pImp->maPoolItems.begin(); + std::vector::iterator itrArr = pImp->maPoolItems.begin(); SfxPoolItem **ppDefItem = pImp->ppStaticDefaults; const sal_uInt16 nSize = GetSize_Impl(); for ( size_t i = 0; i < nSize && !rStream.GetError(); ++i, ++itrArr, ++ppDefItem ) @@ -191,7 +191,7 @@ SvStream &SfxItemPool::Store(SvStream &rStream) const aWhichIdsRec.NewContent(nSlotId, 0); rStream << (*ppDefItem)->Which(); rStream << nItemVersion; - const sal_uInt32 nCount = ::std::min( (*itrArr)->size(), SAL_MAX_UINT32 ); + const sal_uInt32 nCount = ::std::min( (*itrArr)->GetCount(), SAL_MAX_UINT32 ); DBG_ASSERT(nCount, "ItemArr is empty"); rStream << nCount; @@ -200,7 +200,7 @@ SvStream &SfxItemPool::Store(SvStream &rStream) const for ( size_t j = 0; j < nCount; ++j ) { // Item selbst besorgen - const SfxPoolItem *pItem = (*itrArr)->operator[](j); + const SfxPoolItem *pItem = (*itrArr)->GetItem( j ); if ( pItem && pItem->GetRefCount() ) //! siehe anderes MI-REF { aItemsRec.NewContent((sal_uInt16)j, 'X' ); @@ -317,8 +317,10 @@ void SfxItemPool::LoadCompleted() // ist "uberhaupt ein Item mit dem Which-Wert da? if ( *itrItemArr ) { +#warning FIXME [!] ... here ... we need more work ... [!] ... // "uber alle Items mit dieser Which-Id iterieren - SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin(); + SfxPoolItemStoreBase_Impl::iterator ppHtArr = (*itrItemArr)->begin(); + size_t nCoutn = itrItemArr->GetCount(); for( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr ) if (*ppHtArr) { -- 1.8.4.5