summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svl/itemiter.hxx32
-rw-r--r--include/svl/itemset.hxx10
-rw-r--r--sc/source/core/data/patattr.cxx6
-rw-r--r--solenv/gdb/libreoffice/svl.py44
-rw-r--r--svl/qa/unit/items/test_itempool.cxx54
-rw-r--r--svl/source/items/itemiter.cxx62
-rw-r--r--svl/source/items/itemset.cxx1000
-rw-r--r--svx/source/dialog/srchdlg.cxx2
-rw-r--r--sw/source/core/crsr/findattr.cxx8
-rw-r--r--sw/source/core/undo/undobj1.cxx3
-rw-r--r--sw/source/uibase/app/docstyle.cxx3
11 files changed, 484 insertions, 740 deletions
diff --git a/include/svl/itemiter.hxx b/include/svl/itemiter.hxx
index 30b6bd13d00d..b68730f245d6 100644
--- a/include/svl/itemiter.hxx
+++ b/include/svl/itemiter.hxx
@@ -21,6 +21,7 @@
#include <svl/svldllapi.h>
#include <svl/itemset.hxx>
+#include <vector>
class SfxPoolItem;
class SfxItemSet;
@@ -28,32 +29,23 @@ class SfxItemPool;
class SVL_DLLPUBLIC SfxItemIter
{
- const SfxItemSet& m_rSet;
- sal_uInt16 m_nStart;
- sal_uInt16 m_nEnd;
- sal_uInt16 m_nCurrent;
+ const SfxItemSet& m_rSet;
+ std::vector<sal_uInt16> m_keys;
+ std::vector<sal_uInt16>::const_iterator m_iter;
public:
SfxItemIter( const SfxItemSet& rSet );
~SfxItemIter();
/// get item, or null if no items
- const SfxPoolItem* FirstItem()
- {
- m_nCurrent = m_nStart;
- return m_rSet.m_nCount ? *(m_rSet.m_pItems + m_nCurrent) : nullptr;
- }
- const SfxPoolItem* GetCurItem()
- {
- return m_rSet.m_nCount ? *(m_rSet.m_pItems + m_nCurrent) : nullptr;
- }
- const SfxPoolItem* NextItem();
-
- bool IsAtEnd() const { return m_nCurrent == m_nEnd; }
-
- sal_uInt16 GetCurPos() const { return m_nCurrent; }
- sal_uInt16 GetFirstPos() const { return m_nStart; }
- sal_uInt16 GetLastPos() const { return m_nEnd; }
+ SfxPoolItem const * FirstItem();
+ SfxPoolItem const * GetCurItem();
+ SfxPoolItem const * NextItem();
+
+ bool IsAtEnd() const;
+ sal_uInt16 GetCurWhich() const { return *m_iter; }
+ sal_uInt16 GetFirstWhich() const { return *m_keys.begin(); }
+ sal_uInt16 GetLastWhich() const { return *m_keys.rbegin(); }
};
#endif
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index f327f92792eb..502c0ebc2c99 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -23,12 +23,13 @@
#include <cstdarg>
#include <svl/poolitem.hxx>
+#include <map>
class SfxItemPool;
class SfxPoolItem;
class SvStream;
-typedef SfxPoolItem const** SfxItemArray;
+typedef std::map<sal_uInt16, SfxPoolItem const *> SfxItemMap;
class SVL_DLLPUBLIC SfxItemSet
{
@@ -36,9 +37,8 @@ class SVL_DLLPUBLIC SfxItemSet
SfxItemPool* m_pPool; ///< pool that stores the items
const SfxItemSet* m_pParent; ///< derivation
- SfxItemArray m_pItems; ///< array of items
+ SfxItemMap m_aItems; ///< array of items
sal_uInt16* m_pWhichRanges; ///< array of Which Ranges
- sal_uInt16 m_nCount; ///< number of items
friend class SfxItemPoolCache;
friend class SfxAllItemSet;
@@ -50,7 +50,7 @@ private:
SVL_DLLPRIVATE void InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2);
public:
- SfxItemArray GetItems_Impl() const { return m_pItems; }
+ SfxItemMap const & GetItems_Impl() const { return m_aItems; }
private:
const SfxItemSet& operator=(const SfxItemSet &) = delete;
@@ -73,7 +73,7 @@ public:
virtual SfxItemSet * Clone(bool bItems = true, SfxItemPool *pToPool = nullptr) const;
// Get number of items
- sal_uInt16 Count() const { return m_nCount; }
+ sal_uInt16 Count() const { return m_aItems.size(); }
sal_uInt16 TotalCount() const;
const SfxPoolItem& Get( sal_uInt16 nWhich, bool bSrchInParent = true ) const;
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index 133b9809eb33..fd8c8f7f1dd4 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -126,10 +126,10 @@ inline bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 )
if ( rSet1.Count() != rSet2.Count() )
return false;
- SfxItemArray pItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet
- SfxItemArray pItems2 = rSet2.GetItems_Impl();
+ SfxItemMap const & rItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet
+ SfxItemMap const & rItems2 = rSet2.GetItems_Impl();
- return ( 0 == memcmp( pItems1, pItems2, (ATTR_PATTERN_END - ATTR_PATTERN_START + 1) * sizeof(pItems1[0]) ) );
+ return rItems1 == rItems2;
}
bool ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const
diff --git a/solenv/gdb/libreoffice/svl.py b/solenv/gdb/libreoffice/svl.py
index 05049652c434..f7d5dbcc5e90 100644
--- a/solenv/gdb/libreoffice/svl.py
+++ b/solenv/gdb/libreoffice/svl.py
@@ -34,48 +34,8 @@ class ItemSetPrinter(object):
return whiches
def children(self):
- whichranges = self.which_ranges()
- size = 0
- whichids = []
- for (whichfrom, whichto) in whichranges:
- size += whichto - whichfrom + 1
- whichids += [which for which in range(whichfrom, whichto+1)]
- return self._iterator(self.value['m_pItems'], size, whichids)
-
- class _iterator(six.Iterator):
-
- def __init__(self, data, count, whichids):
- self.data = data
- self.whichids = whichids
- self.count = count
- self.pos = 0
- self._check_invariant()
-
- def __iter__(self):
- return self
-
- def __next__(self):
- if self.pos == self.count:
- raise StopIteration()
-
- which = self.whichids[self.pos]
- elem = self.data[self.pos]
- self.pos = self.pos + 1
-
- self._check_invariant()
- if (elem == -1):
- elem = "(Invalid)"
- elif (elem != 0):
- # let's try how well that works...
- elem = elem.cast(elem.dynamic_type).dereference()
- return (str(which), elem)
-
- def _check_invariant(self):
- assert self.count >= 0
- assert self.data
- assert self.pos >= 0
- assert self.pos <= self.count
- assert len(self.whichids) == self.count
+ children = [ ( 'items', self.value['m_aItems'] ) ]
+ return children.__iter__()
printer = None
diff --git a/svl/qa/unit/items/test_itempool.cxx b/svl/qa/unit/items/test_itempool.cxx
index 714c170b445b..38cbda3214da 100644
--- a/svl/qa/unit/items/test_itempool.cxx
+++ b/svl/qa/unit/items/test_itempool.cxx
@@ -8,6 +8,8 @@
*/
#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/itemiter.hxx>
#include <poolio.hxx>
#include <cppunit/TestAssert.h>
@@ -21,13 +23,11 @@ class PoolItemTest : public CppUnit::TestFixture
PoolItemTest() {}
void testPool();
+ void testItemSet();
- // Adds code needed to register the test suite
CPPUNIT_TEST_SUITE(PoolItemTest);
-
CPPUNIT_TEST(testPool);
-
- // End of test suite definition
+ CPPUNIT_TEST(testItemSet);
CPPUNIT_TEST_SUITE_END();
};
@@ -99,6 +99,52 @@ void PoolItemTest::testPool()
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pImpl->maPoolItems[3]->maFree.size());
}
+void PoolItemTest::testItemSet()
+{
+ SfxItemInfo aItems[] =
+ { { 1, false },
+ { 2, false },
+ { 3, false },
+ { 4, false },
+ { 5, false },
+ { 6, false },
+ { 7, false }
+ };
+
+ SfxItemPool *pPool = new SfxItemPool("testpool", 1, 7, aItems);
+ std::vector<SfxPoolItem*> aDefaults {
+ new SfxVoidItem(1),
+ new SfxVoidItem(2),
+ new SfxVoidItem(3),
+ new SfxVoidItem(4),
+ new SfxVoidItem(5),
+ new SfxVoidItem(6),
+ new SfxVoidItem(7)
+ };
+ pPool->SetDefaults(&aDefaults);
+
+ SfxItemSet aItemSet(*pPool, 1, 3, 5, 7, 0);
+ aItemSet.Put(SfxVoidItem(1));
+ aItemSet.Put(SfxVoidItem(2));
+ aItemSet.Put(SfxVoidItem(3));
+ aItemSet.Put(SfxVoidItem(5));
+ aItemSet.Put(SfxVoidItem(6));
+ aItemSet.Put(SfxVoidItem(7));
+
+ SfxItemIter aIter(aItemSet);
+
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)1, aIter.GetFirstWhich());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)7, aIter.GetLastWhich());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)1, aIter.FirstItem()->Which());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)2, aIter.NextItem()->Which());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)3, aIter.NextItem()->Which());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)5, aIter.NextItem()->Which());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)6, aIter.NextItem()->Which());
+ CPPUNIT_ASSERT_EQUAL((sal_uInt16)7, aIter.NextItem()->Which());
+ CPPUNIT_ASSERT_EQUAL(static_cast<const SfxPoolItem*>(nullptr), aIter.NextItem());
+ CPPUNIT_ASSERT_EQUAL(true, aIter.IsAtEnd());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(PoolItemTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx
index a42a90bc2358..e1e8baade8be 100644
--- a/svl/source/items/itemiter.cxx
+++ b/svl/source/items/itemiter.cxx
@@ -25,44 +25,50 @@
SfxItemIter::SfxItemIter( const SfxItemSet& rItemSet )
: m_rSet( rItemSet )
{
- if (!m_rSet.m_nCount)
- {
- m_nStart = 1;
- m_nEnd = 0;
+ // store the set of keys because client code likes modifying the map
+ // while iterating over it
+ m_keys.resize(rItemSet.m_aItems.size());
+ size_t idx = 0;
+ for (auto const & rPair : rItemSet.m_aItems) {
+ m_keys[idx++] = rPair.first;
}
- else
- {
- SfxItemArray ppFnd = m_rSet.m_pItems;
+ m_iter = m_keys.begin();
+}
- // Find the first Item that is set
- for (m_nStart = 0; !*(ppFnd + m_nStart ); ++m_nStart)
- ; // empty loop
- if (1 < m_rSet.Count())
- for (m_nEnd = m_rSet.TotalCount(); !*(ppFnd + --m_nEnd); )
- ; // empty loop
- else
- m_nEnd = m_nStart;
- }
+SfxItemIter::~SfxItemIter()
+{
+}
- m_nCurrent = m_nStart;
+SfxPoolItem const * SfxItemIter::FirstItem()
+{
+ m_iter = m_keys.begin();
+ return GetCurItem();
}
-SfxItemIter::~SfxItemIter()
+SfxPoolItem const * SfxItemIter::GetCurItem()
{
+ if (m_keys.empty())
+ return nullptr;
+ auto it = m_rSet.m_aItems.find(*m_iter);
+ if (it == m_rSet.m_aItems.end())
+ return nullptr;
+ return it->second;
}
-const SfxPoolItem* SfxItemIter::NextItem()
+SfxPoolItem const * SfxItemIter::NextItem()
{
- SfxItemArray ppFnd = m_rSet.m_pItems;
+ if (m_iter == m_keys.end())
+ return nullptr;
+ ++m_iter;
+ if (m_iter == m_keys.end())
+ return nullptr;
+ return GetCurItem();
+}
- if (m_nCurrent < m_nEnd)
- {
- do {
- m_nCurrent++;
- } while (m_nCurrent < m_nEnd && !*(ppFnd + m_nCurrent ));
- return *(ppFnd+m_nCurrent);
- }
- return nullptr;
+bool SfxItemIter::IsAtEnd() const
+{
+ return m_iter == m_keys.end() || std::next(m_iter) == m_keys.end();
}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 9e44a8ba1889..5de52ce8c8dc 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -101,25 +101,6 @@ sal_uInt16 Count_Impl( const sal_uInt16 *pRanges )
return nCount;
}
-/**
- * Determines the total number of sal_uInt16s described in a 0-terminated
- * array of pairs of sal_uInt16s, each representing an range of sal_uInt16s.
- */
-sal_uInt16 Capacity_Impl( const sal_uInt16 *pRanges )
-{
- sal_uInt16 nCount = 0;
-
- if ( pRanges )
- {
- while ( *pRanges )
- {
- nCount += pRanges[1] - pRanges[0] + 1;
- pRanges += 2;
- }
- }
- return nCount;
-}
-
}
/**
@@ -132,21 +113,16 @@ sal_uInt16 Capacity_Impl( const sal_uInt16 *pRanges )
SfxItemSet::SfxItemSet(SfxItemPool& rPool)
: m_pPool( &rPool )
, m_pParent(nullptr)
- , m_nCount(0)
{
m_pWhichRanges = const_cast<sal_uInt16*>(m_pPool->GetFrozenIdRanges());
assert( m_pWhichRanges && "don't create ItemSets with full range before FreezeIdRanges()" );
if (!m_pWhichRanges)
m_pPool->FillItemIdRanges_Impl( m_pWhichRanges );
-
- const sal_uInt16 nSize = TotalCount();
- m_pItems = new const SfxPoolItem*[nSize]{};
}
SfxItemSet::SfxItemSet(SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich2)
: m_pPool( &rPool )
, m_pParent(nullptr)
- , m_nCount(0)
{
assert(nWhich1 <= nWhich2);
@@ -156,21 +132,17 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich
void SfxItemSet::InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2)
{
m_pWhichRanges = new sal_uInt16[3]{nWh1, nWh2, 0};
- const sal_uInt16 nRg = nWh2 - nWh1 + 1;
- m_pItems = new const SfxPoolItem*[nRg]{};
}
void SfxItemSet::InitRanges_Impl(va_list pArgs, sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull)
{
- sal_uInt16 nSize = InitializeRanges_Impl(m_pWhichRanges, pArgs, nWh1, nWh2, nNull);
- m_pItems = new const SfxPoolItem*[nSize]{};
+ InitializeRanges_Impl(m_pWhichRanges, pArgs, nWh1, nWh2, nNull);
}
SfxItemSet::SfxItemSet(SfxItemPool& rPool, int nWh1, int nWh2, int nNull, ...)
: m_pPool( &rPool )
, m_pParent(nullptr)
, m_pWhichRanges(nullptr)
- , m_nCount(0)
{
assert(nWh1 <= nWh2);
@@ -199,8 +171,6 @@ void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
pPtr += 2;
}
- m_pItems = new const SfxPoolItem*[nCnt]{};
-
std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
m_pWhichRanges = new sal_uInt16[ cnt ];
memcpy( m_pWhichRanges, pWhichPairTable, sizeof( sal_uInt16 ) * cnt );
@@ -209,9 +179,7 @@ void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
: m_pPool(&rPool)
, m_pParent(nullptr)
- , m_pItems(nullptr)
, m_pWhichRanges(nullptr)
- , m_nCount(0)
{
// pWhichPairTable == 0 is for the SfxAllEnumItemSet
if ( pWhichPairTable )
@@ -221,7 +189,6 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
: m_pPool( rASet.m_pPool )
, m_pParent( rASet.m_pParent )
- , m_nCount( rASet.m_nCount )
{
// Calculate the attribute count
sal_uInt16 nCnt = 0;
@@ -232,58 +199,51 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
pPtr += 2;
}
- m_pItems = new const SfxPoolItem* [ nCnt ];
-
// Copy attributes
- SfxItemArray ppDst = m_pItems, ppSrc = rASet.m_pItems;
- for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
- if ( nullptr == *ppSrc || // Current Default?
- IsInvalidItem(*ppSrc) || // DontCare?
- IsStaticDefaultItem(*ppSrc) ) // Defaults that are not to be pooled?
+ SfxItemMap ppDst = m_aItems, ppSrc = rASet.m_aItems;
+ for (auto & rSrcPair : rASet.m_aItems)
+ {
+ if ( IsInvalidItem(rSrcPair.second) || // DontCare?
+ IsStaticDefaultItem(rSrcPair.second) ) // Defaults that are not to be pooled?
// Just copy the pointer
- *ppDst = *ppSrc;
- else if (m_pPool->IsItemPoolable( **ppSrc ))
+ m_aItems.insert(rSrcPair);
+ else if (m_pPool->IsItemPoolable( *rSrcPair.second ))
{
// Just copy the pointer and increase RefCount
- *ppDst = *ppSrc;
- (*ppDst)->AddRef();
+ m_aItems.insert(rSrcPair);
+ rSrcPair.second->AddRef();
}
- else if ( !(*ppSrc)->Which() )
- *ppDst = (*ppSrc)->Clone();
+ else if ( !rSrcPair.second->Which() )
+ m_aItems[rSrcPair.first] = rSrcPair.second->Clone();
else
// !IsPoolable() => assign via Pool
- *ppDst = &m_pPool->Put( **ppSrc );
+ m_aItems[rSrcPair.first] = &m_pPool->Put( *rSrcPair.second );
+ }
// Copy the WhichRanges
- std::ptrdiff_t cnt = pPtr - rASet.m_pWhichRanges+1;
+ std::ptrdiff_t cnt = pPtr - rASet.m_pWhichRanges + 1;
m_pWhichRanges = new sal_uInt16[ cnt ];
memcpy( m_pWhichRanges, rASet.m_pWhichRanges, sizeof( sal_uInt16 ) * cnt);
}
SfxItemSet::~SfxItemSet()
{
- sal_uInt16 nCount = TotalCount();
- if( Count() )
- {
- SfxItemArray ppFnd = m_pItems;
- for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
- if( *ppFnd && !IsInvalidItem(*ppFnd) )
- {
- if( !(*ppFnd)->Which() )
- delete *ppFnd;
- else {
- // Still multiple references present, so just alter the RefCount
- if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
- (*ppFnd)->ReleaseRef();
- else
- if ( !IsDefaultItem(*ppFnd) )
- // Delete from Pool
- m_pPool->Remove( **ppFnd );
- }
+ for (auto & rPair : m_aItems)
+ if( !IsInvalidItem(rPair.second) )
+ {
+ if( !rPair.second->Which() )
+ delete rPair.second;
+ else {
+ // Still multiple references present, so just alter the RefCount
+ if ( 1 < rPair.second->GetRefCount() && !IsDefaultItem(rPair.second) )
+ rPair.second->ReleaseRef();
+ else
+ if ( !IsDefaultItem(rPair.second) )
+ // Delete from Pool
+ m_pPool->Remove( *rPair.second );
}
- }
+ }
- delete[] m_pItems;
if (m_pWhichRanges != m_pPool->GetFrozenIdRanges())
delete[] m_pWhichRanges;
m_pWhichRanges = nullptr; // for invariant-testing
@@ -298,89 +258,67 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
return 0;
sal_uInt16 nDel = 0;
- SfxItemArray ppFnd = m_pItems;
if( nWhich )
{
- const sal_uInt16* pPtr = m_pWhichRanges;
- while( *pPtr )
+ auto it = m_aItems.find(nWhich);
+ if (it != m_aItems.end())
{
- // Within this range?
- if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ const SfxPoolItem *pItemToClear = it->second;
+ m_aItems.erase(it);
+ // Due to the assertions in the sub calls, we need to do the following
+
+ if ( !IsInvalidItem(pItemToClear) )
{
- // Actually set?
- ppFnd += nWhich - *pPtr;
- if( *ppFnd )
+ if (SfxItemPool::IsWhich(nWhich))
{
- // Due to the assertions in the sub calls, we need to do the following
- --m_nCount;
- const SfxPoolItem *pItemToClear = *ppFnd;
- *ppFnd = nullptr;
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
- if ( !IsInvalidItem(pItemToClear) )
- {
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rNew = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
-
- Changed( *pItemToClear, rNew );
- }
- if ( pItemToClear->Which() )
- m_pPool->Remove( *pItemToClear );
- }
- ++nDel;
+ Changed( *pItemToClear, rNew );
}
-
- // found => break
- break;
+ if ( pItemToClear->Which() )
+ m_pPool->Remove( *pItemToClear );
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
- pPtr += 2;
+ ++nDel;
}
}
else
{
- nDel = m_nCount;
+ nDel = m_aItems.size();
- sal_uInt16* pPtr = m_pWhichRanges;
- while( *pPtr )
+ SfxItemMap aTmp;
+ aTmp.swap(m_aItems);
+ for (auto & rPair : aTmp)
{
- for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
- if( *ppFnd )
- {
- // Due to the assertions in the sub calls, we need to do this
- --m_nCount;
- const SfxPoolItem *pItemToClear = *ppFnd;
- *ppFnd = nullptr;
+ // Due to the assertions in the sub calls, we need to do this
+ const SfxPoolItem *pItemToClear = rPair.second;
- if ( !IsInvalidItem(pItemToClear) )
- {
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rNew = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
-
- Changed( *pItemToClear, rNew );
- }
-
- // #i32448#
- // Take care of disabled items, too.
- if (!pItemToClear->m_nWhich)
- {
- // item is disabled, delete it
- delete pItemToClear;
- }
- else
- {
- // remove item from pool
- m_pPool->Remove( *pItemToClear );
- }
- }
- }
- pPtr += 2;
+ if ( !IsInvalidItem(pItemToClear) )
+ {
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+
+ Changed( *pItemToClear, rNew );
+ }
+
+ // #i32448#
+ // Take care of disabled items, too.
+ if (!pItemToClear->m_nWhich)
+ {
+ // item is disabled, delete it
+ delete pItemToClear;
+ }
+ else
+ {
+ // remove item from pool
+ m_pPool->Remove( *pItemToClear );
+ }
+ }
}
}
return nDel;
@@ -388,25 +326,30 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
void SfxItemSet::ClearInvalidItems()
{
- sal_uInt16* pPtr = m_pWhichRanges;
- SfxItemArray ppFnd = m_pItems;
- while( *pPtr )
+ for (auto it = m_aItems.begin(); it != m_aItems.end(); )
{
- for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
- if( IsInvalidItem(*ppFnd) )
- {
- *ppFnd = nullptr;
- --m_nCount;
- }
- pPtr += 2;
+ if( IsInvalidItem(it->second) )
+ {
+ it = m_aItems.erase(it);
+ }
+ else
+ ++it;
}
}
void SfxItemSet::InvalidateAllItems()
{
- assert( !m_nCount && "There are still Items set" );
- m_nCount = TotalCount();
- memset(static_cast<void*>(m_pItems), -1, m_nCount * sizeof(SfxPoolItem*));
+ assert( m_aItems.empty() && "There are still Items set" );
+ m_aItems.clear();
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ while ( *pPtr )
+ {
+ for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich )
+ {
+ m_aItems[nWhich] = reinterpret_cast<const SfxPoolItem *>(-1);
+ }
+ pPtr += 2;
+ }
}
SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
@@ -418,39 +361,44 @@ SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
SfxItemState eRet = SfxItemState::UNKNOWN;
do
{
- SfxItemArray ppFnd = pAktSet->m_pItems;
const sal_uInt16* pPtr = pAktSet->m_pWhichRanges;
+ bool bFound = false;
if (pPtr)
{
while ( *pPtr )
{
if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- // Within this range
- ppFnd += nWhich - *pPtr;
- if ( !*ppFnd )
- {
- eRet = SfxItemState::DEFAULT;
- if( !bSrchInParent )
- return eRet; // Not present
- break; // Keep searching in the parents!
- }
-
- if ( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd )
- // Different ones are present
- return SfxItemState::DONTCARE;
+ bFound = true;
+ break;
+ }
+ pPtr += 2;
+ }
+ }
+ if (bFound)
+ {
+ auto it = pAktSet->m_aItems.find(nWhich);
+ if ( it == pAktSet->m_aItems.end())
+ {
+ eRet = SfxItemState::DEFAULT;
+ if( !bSrchInParent )
+ return eRet; // Not present
+ // Keep searching in the parents!
+ }
+ else
+ {
+ if ( reinterpret_cast<SfxPoolItem*>(-1) == it->second )
+ // Different ones are present
+ return SfxItemState::DONTCARE;
- if ( dynamic_cast<const SfxVoidItem *>(*ppFnd) != nullptr )
- return SfxItemState::DISABLED;
+ if ( dynamic_cast<const SfxVoidItem *>(it->second) != nullptr )
+ return SfxItemState::DISABLED;
- if (ppItem)
- {
- *ppItem = *ppFnd;
- }
- return SfxItemState::SET;
+ if (ppItem)
+ {
+ *ppItem = it->second;
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
- pPtr += 2;
+ return SfxItemState::SET;
}
}
} while (bSrchInParent && nullptr != (pAktSet = pAktSet->m_pParent));
@@ -470,82 +418,83 @@ const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich
if ( !nWhich )
return nullptr; //FIXME: Only because of Outliner bug
- SfxItemArray ppFnd = m_pItems;
+ bool bFound = false;
const sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- // Within this range
- ppFnd += nWhich - *pPtr;
- if( *ppFnd ) // Already one present
- {
- // Same Item already present?
- if ( *ppFnd == &rItem )
- return nullptr;
+ bFound = true;
+ break;
+ }
+ pPtr += 2;
+ }
+ if (!bFound)
+ return nullptr;
- // Will 'dontcare' or 'disabled' be overwritten with some real value?
- if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
- {
- auto const old = *ppFnd;
- *ppFnd = &m_pPool->Put( rItem, nWhich );
- if (!IsInvalidItem(old)) {
- assert(old->Which() == 0);
- delete old;
- }
- return *ppFnd;
- }
+ auto it = m_aItems.find(nWhich);
+ if (it != m_aItems.end()) // Already one present
+ {
+ // Same Item already present?
+ if ( it->second == &rItem )
+ return nullptr;
- // Turns into disabled?
- if( !rItem.Which() )
- {
- if (IsInvalidItem(*ppFnd) || (*ppFnd)->Which() != 0) {
- *ppFnd = rItem.Clone(m_pPool);
- }
- return nullptr;
- }
- else
- {
- // Same value already present?
- if ( rItem == **ppFnd )
- return nullptr;
-
- // Add the new one, remove the old one
- const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
- const SfxPoolItem* pOld = *ppFnd;
- *ppFnd = &rNew;
- if (SfxItemPool::IsWhich(nWhich))
- Changed( *pOld, rNew );
- m_pPool->Remove( *pOld );
- }
+ // Will 'dontcare' or 'disabled' be overwritten with some real value?
+ if ( rItem.Which() && ( IsInvalidItem(it->second) || !it->second->Which() ) )
+ {
+ auto const old = it->second;
+ it->second = &m_pPool->Put( rItem, nWhich );
+ if (!IsInvalidItem(old)) {
+ assert(old->Which() == 0);
+ delete old;
}
- else
+ return it->second;
+ }
+
+ // Turns into disabled?
+ if( !rItem.Which() )
+ {
+ if (IsInvalidItem(it->second) || it->second->Which() != 0) {
+ it->second = rItem.Clone(m_pPool);
+ }
+ return nullptr;
+ }
+ else
+ {
+ // Same value already present?
+ if ( rItem == *it->second )
+ return nullptr;
+
+ // Add the new one, remove the old one
+ const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
+ const SfxPoolItem* pOld = it->second;
+ it->second = &rNew;
+ if (SfxItemPool::IsWhich(nWhich))
+ Changed( *pOld, rNew );
+ m_pPool->Remove( *pOld );
+ }
+ }
+ else
+ {
+ if( !rItem.Which() )
+ it = m_aItems.insert({ nWhich, rItem.Clone(m_pPool)}).first;
+ else {
+ const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
+ it = m_aItems.insert({nWhich, &rNew}).first;
+ if (SfxItemPool::IsWhich(nWhich))
{
- ++m_nCount;
- if( !rItem.Which() )
- *ppFnd = rItem.Clone(m_pPool);
- else {
- const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
- *ppFnd = &rNew;
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rOld = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
- Changed( rOld, rNew );
- }
- }
+ const SfxPoolItem& rOld = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+ Changed( rOld, rNew );
}
- SAL_WARN_IF(m_pPool->IsItemPoolable(nWhich) &&
- dynamic_cast<const SfxSetItem*>( &rItem ) == nullptr &&
- **ppFnd != rItem,
- "svl.items", "putted Item unequal, with ID/pos " << nWhich );
- return *ppFnd;
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
- pPtr += 2;
}
- return nullptr;
+ SAL_WARN_IF(m_pPool->IsItemPoolable(nWhich) &&
+ dynamic_cast<const SfxSetItem*>( &rItem ) == nullptr &&
+ *it->second != rItem,
+ "svl.items", "putted Item unequal, with ID/pos " << nWhich );
+ return it->second;
}
bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
@@ -553,26 +502,19 @@ bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
bool bRet = false;
if( rSet.Count() )
{
- SfxItemArray ppFnd = rSet.m_pItems;
- const sal_uInt16* pPtr = rSet.m_pWhichRanges;
- while ( *pPtr )
+ for (auto const & rPair : rSet.m_aItems)
{
- for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
- if( *ppFnd )
- {
- if ( IsInvalidItem( *ppFnd ) )
- {
- if ( bInvalidAsDefault )
- bRet |= 0 != ClearItem( nWhich );
- // FIXME: Caused a SEGFAULT on non Windows-platforms:
- // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
- else
- InvalidateItem( nWhich );
- }
- else
- bRet |= nullptr != Put( **ppFnd, nWhich );
- }
- pPtr += 2;
+ if ( IsInvalidItem( rPair.second ) )
+ {
+ if ( bInvalidAsDefault )
+ bRet |= 0 != ClearItem( rPair.first );
+ // FIXME: Caused a SEGFAULT on non Windows-platforms:
+ // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
+ else
+ InvalidateItem( rPair.first );
+ }
+ else
+ bRet |= nullptr != Put( *rPair.second, rPair.first );
}
}
return bRet;
@@ -601,14 +543,15 @@ void SfxItemSet::PutExtended
)
{
// don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
- SfxItemArray ppFnd = rSet.m_pItems;
const sal_uInt16* pPtr = rSet.m_pWhichRanges;
while ( *pPtr )
{
- for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
- if( *ppFnd )
+ for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich )
+ {
+ auto it = rSet.m_aItems.find(nWhich);
+ if( it != rSet.m_aItems.end() )
{
- if ( IsInvalidItem( *ppFnd ) )
+ if ( IsInvalidItem( it->second ) )
{
// Item ist DontCare:
switch ( eDontCareAs )
@@ -631,7 +574,7 @@ void SfxItemSet::PutExtended
}
else
// Item is set:
- Put( **ppFnd, nWhich );
+ Put( *it->second, nWhich );
}
else
{
@@ -654,6 +597,7 @@ void SfxItemSet::PutExtended
assert(!"invalid Argument for eDefaultAs");
}
}
+ }
pPtr += 2;
}
}
@@ -749,12 +693,8 @@ void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
}
// create new item-array (by iterating through all new ranges)
- sal_uLong nSize = Capacity_Impl(pNewRanges);
- SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ];
- sal_uInt16 nNewCount = 0;
- if (m_nCount == 0)
- memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
- else
+ SfxItemMap aNewItems;
+ if (!m_aItems.empty())
{
sal_uInt16 n = 0;
for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
@@ -763,45 +703,40 @@ void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
{
// direct move of pointer (not via pool)
- SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
- if ( SfxItemState::SET == eState )
+ auto it = m_aItems.find(nWID);
+ if ( it == m_aItems.end())
{
- // increment new item count and possibly increment ref count
- ++nNewCount;
- aNewItems[n]->AddRef();
+ // default
}
- else if ( SfxItemState::DISABLED == eState )
+ else if ( reinterpret_cast<SfxPoolItem*>(-1) == it->second )
{
- // put "disabled" item
- ++nNewCount;
- aNewItems[n] = new SfxVoidItem(0);
+ // don't care
+ aNewItems[nWID] = reinterpret_cast<SfxPoolItem*>(-1);
}
- else if ( SfxItemState::DONTCARE == eState )
+ else if ( dynamic_cast<const SfxVoidItem *>(it->second) != nullptr )
{
- ++nNewCount;
- aNewItems[n] = reinterpret_cast<SfxPoolItem*>(-1);
+ // put "disabled" item
+ aNewItems[nWID] = new SfxVoidItem(0);
}
else
{
- // default
- aNewItems[n] = nullptr;
+ aNewItems[nWID] = it->second;
+ // increment new item count and possibly increment ref count
+ aNewItems[nWID]->AddRef();
}
}
}
// free old items
- sal_uInt16 nOldTotalCount = TotalCount();
- for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
+ for ( auto & rPair : m_aItems )
{
- const SfxPoolItem *pItem = m_pItems[nItem];
- if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
+ const SfxPoolItem *pItem = rPair.second;
+ if ( !IsInvalidItem(pItem) && pItem->Which() )
m_pPool->Remove(*pItem);
}
}
// replace old items-array and ranges
- delete[] m_pItems;
- m_pItems = aNewItems;
- m_nCount = nNewCount;
+ m_aItems.swap(aNewItems);
if( pNewRanges == GetPool()->GetFrozenIdRanges() )
{
@@ -854,7 +789,7 @@ bool SfxItemSet::Set
)
{
bool bRet = false;
- if (m_nCount)
+ if (!m_aItems.empty())
ClearItem();
if ( bDeep )
{
@@ -898,39 +833,24 @@ const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
{
if( pAktSet->Count() )
{
- SfxItemArray ppFnd = pAktSet->m_pItems;
- const sal_uInt16* pPtr = pAktSet->m_pWhichRanges;
- while( *pPtr )
+ auto it = pAktSet->m_aItems.find(nWhich);
+ if( it != pAktSet->m_aItems.end() )
{
- if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
- {
- // In this Range
- ppFnd += nWhich - *pPtr;
- if( *ppFnd )
- {
- if( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd ) {
- //FIXME: The following code is duplicated further down
- SAL_WARN_IF(!m_pPool, "svl.items", "no Pool, but status is ambiguous, with ID/pos " << nWhich);
- //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
- //!return aDefault;
- return m_pPool->GetDefaultItem( nWhich );
- }
+ if( reinterpret_cast<SfxPoolItem*>(-1) == it->second ) {
+ //FIXME: The following code is duplicated further down
+ SAL_WARN_IF(!m_pPool, "svl.items", "no Pool, but status is ambiguous, with ID/pos " << nWhich);
+ //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
+ //!return aDefault;
+ return m_pPool->GetDefaultItem( nWhich );
+ }
#ifdef DBG_UTIL
- const SfxPoolItem *pItem = *ppFnd;
- if ( dynamic_cast<const SfxVoidItem *>(pItem) != nullptr || !pItem->Which() )
- SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+ const SfxPoolItem *pItem = it->second;
+ if ( dynamic_cast<const SfxVoidItem *>(pItem) != nullptr || !pItem->Which() )
+ SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
#endif
- return **ppFnd;
- }
- break; // Continue with Parent
- }
- ppFnd += *(pPtr+1) - *pPtr + 1;
- pPtr += 2;
+ return *it->second;
}
}
-//TODO: Search until end of Range: What are we supposed to do now? To the Parent or Default??
-// if( !*pPtr ) // Until the end of the search Range?
-// break;
} while (bSrchInParent && nullptr != (pAktSet = pAktSet->m_pParent));
// Get the Default from the Pool and return
@@ -952,7 +872,7 @@ sal_uInt16 SfxItemSet::TotalCount() const
sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
- nRet += ( *(pPtr+1) - *pPtr ) + 1;
+ nRet += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
return nRet;
@@ -960,7 +880,7 @@ sal_uInt16 SfxItemSet::TotalCount() const
/**
* Only retain the Items that are also present in rSet
- * (nevermind their value).
+ * (never mind their value).
*/
void SfxItemSet::Intersect( const SfxItemSet& rSet )
{
@@ -975,64 +895,17 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet )
return;
}
- // Test whether the Which Ranges are different
- sal_uInt16* pWh1 = m_pWhichRanges;
- sal_uInt16* pWh2 = rSet.m_pWhichRanges;
- sal_uInt16 nSize = 0;
-
- for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
- {
- if( *pWh1 != *pWh2 )
- {
- break;
- }
- if( n & 1 )
- nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
- }
- bool bEqual = *pWh1 == *pWh2; // Also check for 0
-
- // If the Ranges are identical, we can easily process it
- if( bEqual )
- {
- SfxItemArray ppFnd1 = m_pItems;
- SfxItemArray ppFnd2 = rSet.m_pItems;
-
- for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
- if( *ppFnd1 && !*ppFnd2 )
- {
- // Delete from Pool
- if( !IsInvalidItem( *ppFnd1 ) )
- {
- sal_uInt16 nWhich = (*ppFnd1)->Which();
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rNew = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
-
- Changed( **ppFnd1, rNew );
- }
- m_pPool->Remove( **ppFnd1 );
- }
- *ppFnd1 = nullptr;
- --m_nCount;
- }
+ // get the set of keys since we are going to be modifying
+ // the map while we iterate over it
+ std::vector<sal_uInt16> keys(m_aItems.size());
+ size_t idx = 0;
+ for (auto const & rPair : m_aItems) {
+ keys[idx++] = rPair.first;
}
- else
+ for (sal_uInt16 nWhich : keys)
{
- SfxItemIter aIter( *this );
- const SfxPoolItem* pItem = aIter.GetCurItem();
- while( true )
- {
- sal_uInt16 nWhich = IsInvalidItem( pItem )
- ? GetWhichByPos( aIter.GetCurPos() )
- : pItem->Which();
- if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
- ClearItem( nWhich ); // Delete
- if( aIter.IsAtEnd() )
- break;
- pItem = aIter.NextItem();
- }
+ if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
+ ClearItem( nWhich ); // Delete
}
}
@@ -1041,65 +914,17 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
if( !Count() || !rSet.Count() )// None set?
return;
- // Test whether the Which Ranges are different
- sal_uInt16* pWh1 = m_pWhichRanges;
- sal_uInt16* pWh2 = rSet.m_pWhichRanges;
- sal_uInt16 nSize = 0;
-
- for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
- {
- if( *pWh1 != *pWh2 )
- {
- break;
- }
- if( n & 1 )
- nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
- }
- bool bEqual = *pWh1 == *pWh2; // Also test for 0
-
- // If the Ranges are identical, we can easily process it
- if( bEqual )
- {
- SfxItemArray ppFnd1 = m_pItems;
- SfxItemArray ppFnd2 = rSet.m_pItems;
-
- for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
- if( *ppFnd1 && *ppFnd2 )
- {
- // Delete from Pool
- if( !IsInvalidItem( *ppFnd1 ) )
- {
- sal_uInt16 nWhich = (*ppFnd1)->Which();
- if (SfxItemPool::IsWhich(nWhich))
- {
- const SfxPoolItem& rNew = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
-
- Changed( **ppFnd1, rNew );
- }
- m_pPool->Remove( **ppFnd1 );
- }
- *ppFnd1 = nullptr;
- --m_nCount;
- }
+ // get the set of keys since we are going to be modifying
+ // the map while we iterate over it
+ std::vector<sal_uInt16> keys(m_aItems.size());
+ size_t idx = 0;
+ for (auto const & rPair : m_aItems) {
+ keys[idx++] = rPair.first;
}
- else
+ for (sal_uInt16 nWhich : keys)
{
- SfxItemIter aIter( *this );
- const SfxPoolItem* pItem = aIter.GetCurItem();
- while( true )
- {
- sal_uInt16 nWhich = IsInvalidItem( pItem )
- ? GetWhichByPos( aIter.GetCurPos() )
- : pItem->Which();
- if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
- ClearItem( nWhich ); // Delete
- if( aIter.IsAtEnd() )
- break;
- pItem = aIter.NextItem();
- }
-
+ if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
+ ClearItem( nWhich ); // Delete
}
}
@@ -1181,66 +1006,63 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
* dontcare unknown != sal_True - - -
* unknown unknown != sal_True - - -
*/
-static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
- const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
+static void MergeItem_Impl( SfxItemPool *_pPool,
+ SfxItemMap& rItems, sal_uInt16 nWhich, const SfxPoolItem *pFnd2,
bool bIgnoreDefaults )
{
- assert(ppFnd1 != nullptr && "Merging to 0-Item");
+ auto ppFnd1 = rItems.find(nWhich);
// 1st Item is Default?
- if ( !*ppFnd1 )
+ if ( ppFnd1 == rItems.end() )
{
if ( IsInvalidItem(pFnd2) )
// Decision table: default, dontcare, doesn't matter, doesn't matter
- *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
+ rItems[nWhich] = reinterpret_cast<SfxPoolItem*>(-1);
else if ( pFnd2 && !bIgnoreDefaults &&
_pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
// Decision table: default, set, !=, sal_False
- *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
+ rItems[nWhich] = reinterpret_cast<SfxPoolItem*>(-1);
else if ( pFnd2 && bIgnoreDefaults )
// Decision table: default, set, doesn't matter, sal_True
- *ppFnd1 = &_pPool->Put( *pFnd2 );
-
- if ( *ppFnd1 )
- ++rCount;
+ rItems[nWhich] = &_pPool->Put( *pFnd2 );
}
// 1st Item set?
- else if ( !IsInvalidItem(*ppFnd1) )
+ else if ( !IsInvalidItem(ppFnd1->second) )
{
if ( !pFnd2 )
{
// 2nd Item is Default
if ( !bIgnoreDefaults &&
- **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
+ *ppFnd1->second != _pPool->GetDefaultItem(ppFnd1->second->Which()) )
{
// Decision table: set, default, !=, sal_False
- _pPool->Remove( **ppFnd1 );
- *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( *ppFnd1->second );
+ ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
}
}
else if ( IsInvalidItem(pFnd2) )
{
// 2nd Item is dontcare
if ( !bIgnoreDefaults ||
- **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
+ *ppFnd1->second != _pPool->GetDefaultItem( ppFnd1->second->Which()) )
{
// Decision table: set, dontcare, doesn't matter, sal_False
// or: set, dontcare, !=, sal_True
- _pPool->Remove( **ppFnd1 );
- *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( *ppFnd1->second );
+ ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
}
}
else
{
// 2nd Item is set
- if ( **ppFnd1 != *pFnd2 )
+ if ( *ppFnd1->second != *pFnd2 )
{
// Decision table: set, set, !=, doesn't matter
- _pPool->Remove( **ppFnd1 );
- *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( *ppFnd1->second );
+ ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
}
}
}
@@ -1265,96 +1087,82 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet )
if( n & 1 )
nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
}
- bool bEqual = *pWh1 == *pWh2; // Also check for 0
- // If the Ranges match, they are easier to process!
- if( bEqual )
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich;
+ while( 0 != ( nWhich = aIter.NextWhich() ) )
{
- SfxItemArray ppFnd1 = m_pItems;
- SfxItemArray ppFnd2 = rSet.m_pItems;
-
- for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
- MergeItem_Impl(m_pPool, m_nCount, ppFnd1, *ppFnd2, false/*bIgnoreDefaults*/);
- }
- else
- {
- SfxWhichIter aIter( rSet );
- sal_uInt16 nWhich;
- while( 0 != ( nWhich = aIter.NextWhich() ) )
+ const SfxPoolItem* pItem = nullptr;
+ (void)rSet.GetItemState( nWhich, true, &pItem );
+ if( !pItem )
{
- const SfxPoolItem* pItem = nullptr;
- (void)rSet.GetItemState( nWhich, true, &pItem );
- if( !pItem )
- {
- // Not set, so default
- MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ) );
- }
- else if( IsInvalidItem( pItem ) )
- // don't care
- InvalidateItem( nWhich );
- else
- MergeValue( *pItem );
+ // Not set, so default
+ MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ) );
}
+ else if( IsInvalidItem( pItem ) )
+ // don't care
+ InvalidateItem( nWhich );
+ else
+ MergeValue( *pItem );
}
}
void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
{
- SfxItemArray ppFnd = m_pItems;
const sal_uInt16* pPtr = m_pWhichRanges;
const sal_uInt16 nWhich = rAttr.Which();
+ bool bFound = false;
while( *pPtr )
{
// In this Range??
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- ppFnd += nWhich - *pPtr;
- MergeItem_Impl(m_pPool, m_nCount, ppFnd, &rAttr, bIgnoreDefaults);
+ bFound = true;
break;
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ if (bFound)
+ MergeItem_Impl(m_pPool, m_aItems, nWhich, &rAttr, bIgnoreDefaults);
}
void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
{
- SfxItemArray ppFnd = m_pItems;
+ bool bFound = false;
const sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- // In this Range?
- ppFnd += nWhich - *pPtr;
-
- if( *ppFnd ) // Set for me
- {
- if( reinterpret_cast<SfxPoolItem*>(-1) != *ppFnd ) // Not yet dontcare!
- {
- m_pPool->Remove( **ppFnd );
- *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
- }
- }
- else
- {
- *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
- ++m_nCount;
- }
+ bFound = true;
break;
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ if (!bFound)
+ return;
+
+ auto it = m_aItems.find(nWhich);
+ if (it != m_aItems.end())
+ {
+ if( reinterpret_cast<SfxPoolItem*>(-1) != it->second ) // Not yet dontcare!
+ {
+ m_pPool->Remove( *it->second );
+ it->second = reinterpret_cast<SfxPoolItem*>(-1);
+ }
+ }
+ else
+ {
+ m_aItems[nWhich] = reinterpret_cast<SfxPoolItem*>(-1);
+ }
}
sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
{
- sal_uInt16 n = 0;
sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
- n = ( *(pPtr+1) - *pPtr ) + 1;
+ sal_uInt16 n = *(pPtr+1) - *pPtr + 1;
if( nPos < n )
return *(pPtr)+nPos;
nPos = nPos - n;
@@ -1386,10 +1194,10 @@ void SfxItemSet::Store
// Remember position of the count (to be able to correct it, if need be)
sal_uLong nCountPos = rStream.Tell();
- rStream.WriteUInt16( m_nCount );
+ rStream.WriteUInt16( m_aItems.size() );
// If there's nothing to save, don't construct an ItemIter
- if (m_nCount)
+ if (!m_aItems.empty())
{
// Keep record of how many Items are really saved
sal_uInt16 nWrittenCount = 0; // Count of Items streamed in 'rStream'
@@ -1409,7 +1217,7 @@ void SfxItemSet::Store
}
// Fewer written than read (e.g. old format)
- if (nWrittenCount != m_nCount)
+ if (nWrittenCount != m_aItems.size())
{
// Store real count in the stream
sal_uLong nPos = rStream.Tell();
@@ -1462,25 +1270,23 @@ void SfxItemSet::Load
{
// Find position for Item pointer in the set
sal_uInt16 nWhich = pItem->Which();
- SfxItemArray ppFnd = m_pItems;
const sal_uInt16* pPtr = m_pWhichRanges;
+ bool bFound = false;
while ( *pPtr )
{
// In this Range??
if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- // Remember Item pointer in the set
- ppFnd += nWhich - *pPtr;
- SAL_WARN_IF( *ppFnd, "svl.items", "Item is present twice, with ID/pos " << nWhich);
- *ppFnd = pItem;
- ++m_nCount;
+ bFound = true;
break;
}
-
- // In the range array and Item array to the next Which range
- ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ if (bFound)
+ {
+ SAL_WARN_IF( m_aItems.find(nWhich) != m_aItems.end(), "svl.items", "Item is present twice, with ID/pos " << nWhich);
+ m_aItems[nWhich] = pItem;
+ }
}
}
}
@@ -1527,27 +1333,29 @@ bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
}
// Are all pointers the same?
- if (0 == memcmp( m_pItems, rCmp.m_pItems, nCount1 * sizeof(m_pItems[0]) ))
+ if ( m_aItems == rCmp.m_aItems )
return true;
// We need to compare each one separately then
- const SfxPoolItem **ppItem1 = m_pItems;
- const SfxPoolItem **ppItem2 = rCmp.m_pItems;
- for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
+ auto it1 = m_aItems.begin();
+ auto it2 = rCmp.m_aItems.begin();
+ for (;; ++it1, ++it2)
{
- // If the pointers of the poolable Items are not the same, the Items
- // must match
- if ( *ppItem1 != *ppItem2 &&
- ( ( !*ppItem1 || !*ppItem2 ) ||
- ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
- (m_pPool->IsItemPoolable(**ppItem1)) ||
- **ppItem1 != **ppItem2 ) )
+ if (it1 == m_aItems.end() && it2 == rCmp.m_aItems.end())
+ break;
+ if (it1 == m_aItems.end() || it2 == rCmp.m_aItems.end())
+ return false;
+ if (it1->first != it2->first)
+ return false;
+ if (it1->second == it2->second)
+ continue;
+ if (IsInvalidItem(it1->second) || IsInvalidItem(it2->second))
+ return false;
+ if (m_pPool->IsItemPoolable(*it1->second))
+ return false;
+ if (*it1->second != *it2->second)
return false;
-
- ++ppItem1;
- ++ppItem2;
}
-
return true;
}
@@ -1578,44 +1386,43 @@ SfxItemSet *SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
void SfxItemSet::PutDirect(const SfxPoolItem &rItem)
{
- SfxItemArray ppFnd = m_pItems;
const sal_uInt16* pPtr = m_pWhichRanges;
const sal_uInt16 nWhich = rItem.Which();
#ifdef DBG_UTIL
IsPoolDefaultItem(&rItem) || m_pPool->GetSurrogate(&rItem);
// Only cause assertion in the callees
#endif
+
+ bool bFound = false;
while( *pPtr )
{
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- // In this Range?
- ppFnd += nWhich - *pPtr;
- const SfxPoolItem* pOld = *ppFnd;
- if( pOld ) // One already present
- {
- if( rItem == **ppFnd )
- return; // Already present!
- m_pPool->Remove( *pOld );
- }
- else
- ++m_nCount;
-
- // Add the new one
- if( IsPoolDefaultItem(&rItem) )
- *ppFnd = &m_pPool->Put( rItem );
- else
- {
- *ppFnd = &rItem;
- if( !IsStaticDefaultItem( &rItem ) )
- rItem.AddRef();
- }
-
- return;
+ bFound = true;
+ break;
}
- ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ if (!bFound)
+ return;
+
+ auto it = m_aItems.find(nWhich);
+ if (it != m_aItems.end()) // One already present
+ {
+ if( rItem == *it->second )
+ return; // Already present!
+ m_pPool->Remove( *it->second );
+ }
+
+ // Add the new one
+ if( IsPoolDefaultItem(&rItem) )
+ m_aItems[nWhich] = &m_pPool->Put( rItem );
+ else
+ {
+ m_aItems[nWhich] = &rItem;
+ if( !IsStaticDefaultItem( &rItem ) )
+ rItem.AddRef();
+ }
}
sal_Int32 SfxItemSet::getHash() const
@@ -1648,9 +1455,6 @@ SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
: SfxItemSet(rPool, nullptr),
nFree(nInitCount)
{
- // Initially no Items
- m_pItems = nullptr;
-
// Allocate nInitCount pairs at USHORTs for Ranges
m_pWhichRanges = new sal_uInt16[nInitCount + 1]{};
}
@@ -1699,61 +1503,17 @@ static sal_uInt16 *AddRanges_Impl(
}
/**
- * This internal function creates a new ItemArray, which is copied from 'pItems',
- * but has room for a new ItemPointer at 'nPos'.
- *
- * @returns the new ItemArray (the old 'pItems' is freed)
- */
-static SfxItemArray AddItem_Impl(SfxItemArray pItems, sal_uInt16 nOldSize, sal_uInt16 nPos)
-{
- // Create new ItemArray
- SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1];
-
- // Was there one before?
- if ( pItems )
- {
- // Copy all Items before nPos
- if ( nPos )
- memcpy( static_cast<void*>(pNew), pItems, nPos * sizeof(SfxPoolItem *) );
-
- // Copy all Items after nPos
- if ( nPos < nOldSize )
- memcpy( static_cast<void*>(pNew + nPos + 1), pItems + nPos,
- (nOldSize-nPos) * sizeof(SfxPoolItem *) );
- }
-
- // Initialize new Item
- *(pNew + nPos) = nullptr;
-
- // Free old ItemArray
- delete[] pItems;
-
- return pNew;
-}
-
-/**
* Putting with automatic extension of the WhichId with the ID of the Item.
*/
const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
{
- sal_uInt16 nPos = 0; // Position for 'rItem' in 'm_pItems'
- const sal_uInt16 nItemCount = TotalCount();
-
// Let's see first whether there's a suitable Range already
sal_uInt16 *pPtr = m_pWhichRanges;
while ( *pPtr )
{
// WhichId is within this Range?
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
- {
- // Insert
- nPos += nWhich - *pPtr;
break;
- }
-
- // Carry over the position of the Item in m_pItems
- nPos += *(pPtr+1) - *pPtr + 1;
-
// To the next Range
pPtr += 2;
}
@@ -1763,35 +1523,24 @@ const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhi
{
// Let's see if we can attach it somewhere
pPtr = m_pWhichRanges;
- nPos = 0;
while ( *pPtr )
{
// WhichId is right before this Range?
if ( (nWhich+1) == *pPtr )
{
- // Range grows downwards
+ // Grow range downwards
(*pPtr)--;
-
- // Make room before first Item of this Range
- m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
break;
}
// WhichId is right after this Range?
else if ( (nWhich-1) == *(pPtr+1) )
{
- // Range grows upwards?
+ // Grow range upwards
(*(pPtr+1))++;
-
- // Make room after last Item of this Range
- nPos += nWhich - *pPtr;
- m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
break;
}
- // Carry over position of the Item in m_pItems
- nPos += *(pPtr+1) - *pPtr + 1;
-
// To the next Range
pPtr += 2;
}
@@ -1813,32 +1562,28 @@ const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhi
*pPtr++ = nWhich;
*pPtr = nWhich;
nFree -= 2;
-
- // Expand ItemArray
- nPos = nItemCount;
- m_pItems = AddItem_Impl(m_pItems, nItemCount, nPos);
}
// Add new Item to Pool
const SfxPoolItem& rNew = m_pPool->Put( rItem, nWhich );
// Remember old Item
- bool bIncrementCount = false;
- const SfxPoolItem* pOld = *( m_pItems + nPos );
+ auto it = m_aItems.find(nWhich);
+ const SfxPoolItem* pOld = nullptr;
+ if (it != m_aItems.end())
+ pOld = it->second;
if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare"
pOld = nullptr;
if ( !pOld )
{
- bIncrementCount = true;
- pOld = (m_pParent)
- ? &m_pParent->Get( nWhich )
- : (SfxItemPool::IsWhich(nWhich)
- ? &m_pPool->GetDefaultItem(nWhich)
- : nullptr);
+ if (m_pParent)
+ pOld = &m_pParent->Get( nWhich );
+ else if (SfxItemPool::IsWhich(nWhich))
+ pOld = &m_pPool->GetDefaultItem(nWhich);
}
// Add new Item to ItemSet
- *(m_pItems + nPos) = &rNew;
+ m_aItems[nWhich] = &rNew;
// Send Changed Notification
if ( pOld )
@@ -1848,9 +1593,6 @@ const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhi
m_pPool->Remove( *pOld );
}
- if ( bIncrementCount )
- ++m_nCount;
-
return &rNew;
}
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index a7f025d1c11d..630b111edf02 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -194,7 +194,7 @@ void SearchAttrItemList::Put( const SfxItemSet& rSet )
// only test that it is available?
if( IsInvalidItem( pItem ) )
{
- nWhich = rSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = aIter.GetCurWhich();
aItem.pItem = const_cast<SfxPoolItem*>(pItem);
}
else
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 73b577712c86..5e347f9fbac7 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -235,8 +235,8 @@ SwAttrCheckArr::SwAttrCheckArr( const SfxItemSet& rSet, bool bFwd,
// determine area of Fnd/Stack array (Min/Max)
SfxItemIter aIter( aCmpSet );
- nArrStart = aCmpSet.GetWhichByPos( aIter.GetFirstPos() );
- nArrLen = aCmpSet.GetWhichByPos( aIter.GetLastPos() ) - nArrStart+1;
+ nArrStart = aIter.GetFirstWhich();
+ nArrLen = aIter.GetLastWhich() - nArrStart + 1;
char* pFndChar = new char[ nArrLen * sizeof(SwSrchChrAttr) ];
char* pStackChar = new char[ nArrLen * sizeof(SwSrchChrAttr) ];
@@ -287,7 +287,7 @@ void SwAttrCheckArr::SetNewSet( const SwTextNode& rTextNd, const SwPaM& rPam )
{
if( IsInvalidItem( pItem ) )
{
- nWhich = aCmpSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = aIter.GetCurWhich();
if( RES_TXTATR_END <= nWhich )
break; // end of text attributes
@@ -861,7 +861,7 @@ static bool lcl_Search( const SwContentNode& rCNd, const SfxItemSet& rCmpSet, bo
{
if( IsInvalidItem( pItem ))
{
- nWhich = rCmpSet.GetWhichByPos( aIter.GetCurPos() );
+ nWhich = aIter.GetCurWhich();
if( SfxItemState::SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem )
|| CmpAttr( *pNdItem, rNdSet.GetPool()->GetDefaultItem( nWhich ) ))
return false;
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index ab7d5ff9612a..73556ba96eb6 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -532,8 +532,7 @@ void SwUndoSetFlyFormat::UndoImpl(::sw::UndoRedoContext & rContext)
while( pItem )
{
if( IsInvalidItem( pItem ))
- pFrameFormat->ResetFormatAttr( pItemSet->GetWhichByPos(
- aIter.GetCurPos() ));
+ pFrameFormat->ResetFormatAttr( aIter.GetCurWhich() );
else
pFrameFormat->SetFormatAttr( *pItem );
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index a4257fa71fb3..7a8a5f848822 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -1677,8 +1677,7 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet,
{
// use method <SwDoc::ResetAttrAtFormat(..)> in order to
// create an Undo object for the attribute reset.
- rDoc.ResetAttrAtFormat( rSet.GetWhichByPos(aIter.GetCurPos()),
- *pFormat );
+ rDoc.ResetAttrAtFormat( aIter.GetCurWhich(), *pFormat );
}
if( aIter.IsAtEnd() )