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.cxx55
-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, 740 insertions, 485 deletions
diff --git a/include/svl/itemiter.hxx b/include/svl/itemiter.hxx
index b68730f245d6..30b6bd13d00d 100644
--- a/include/svl/itemiter.hxx
+++ b/include/svl/itemiter.hxx
@@ -21,7 +21,6 @@
#include <svl/svldllapi.h>
#include <svl/itemset.hxx>
-#include <vector>
class SfxPoolItem;
class SfxItemSet;
@@ -29,23 +28,32 @@ class SfxItemPool;
class SVL_DLLPUBLIC SfxItemIter
{
- const SfxItemSet& m_rSet;
- std::vector<sal_uInt16> m_keys;
- std::vector<sal_uInt16>::const_iterator m_iter;
+ const SfxItemSet& m_rSet;
+ sal_uInt16 m_nStart;
+ sal_uInt16 m_nEnd;
+ sal_uInt16 m_nCurrent;
public:
SfxItemIter( const SfxItemSet& rSet );
~SfxItemIter();
/// get item, or null if no items
- 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(); }
+ 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; }
};
#endif
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 8c1ebd5b8109..dccebd2b23b3 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -23,13 +23,12 @@
#include <cstdarg>
#include <svl/poolitem.hxx>
-#include <map>
class SfxItemPool;
class SfxPoolItem;
class SvStream;
-typedef std::map<sal_uInt16, SfxPoolItem const *> SfxItemMap;
+typedef SfxPoolItem const** SfxItemArray;
class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
{
@@ -37,8 +36,9 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
SfxItemPool* m_pPool; ///< pool that stores the items
const SfxItemSet* m_pParent; ///< derivation
- SfxItemMap m_aItems; ///< array of items
+ SfxItemArray m_pItems; ///< 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:
- SfxItemMap const & GetItems_Impl() const { return m_aItems; }
+ SfxItemArray GetItems_Impl() const { return m_pItems; }
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_aItems.size(); }
+ sal_uInt16 Count() const { return m_nCount; }
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 fd8c8f7f1dd4..133b9809eb33 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;
- SfxItemMap const & rItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet
- SfxItemMap const & rItems2 = rSet2.GetItems_Impl();
+ SfxItemArray pItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet
+ SfxItemArray pItems2 = rSet2.GetItems_Impl();
- return rItems1 == rItems2;
+ return ( 0 == memcmp( pItems1, pItems2, (ATTR_PATTERN_END - ATTR_PATTERN_START + 1) * sizeof(pItems1[0]) ) );
}
bool ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const
diff --git a/solenv/gdb/libreoffice/svl.py b/solenv/gdb/libreoffice/svl.py
index f7d5dbcc5e90..05049652c434 100644
--- a/solenv/gdb/libreoffice/svl.py
+++ b/solenv/gdb/libreoffice/svl.py
@@ -34,8 +34,48 @@ class ItemSetPrinter(object):
return whiches
def children(self):
- children = [ ( 'items', self.value['m_aItems'] ) ]
- return children.__iter__()
+ 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
printer = None
diff --git a/svl/qa/unit/items/test_itempool.cxx b/svl/qa/unit/items/test_itempool.cxx
index 0987a6bc548a..00c2c2ee6eda 100644
--- a/svl/qa/unit/items/test_itempool.cxx
+++ b/svl/qa/unit/items/test_itempool.cxx
@@ -8,8 +8,6 @@
*/
#include <svl/itempool.hxx>
-#include <svl/itemset.hxx>
-#include <svl/itemiter.hxx>
#include <poolio.hxx>
#include <cppunit/TestAssert.h>
@@ -23,11 +21,13 @@ 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);
- CPPUNIT_TEST(testItemSet);
+
+ // End of test suite definition
CPPUNIT_TEST_SUITE_END();
};
@@ -99,53 +99,6 @@ 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());
- const SfxPoolItem *pFirstItem = aIter.FirstItem();
- CPPUNIT_ASSERT(pFirstItem);
- CPPUNIT_ASSERT_EQUAL((sal_uInt16)1, pFirstItem->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);
diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx
index e1e8baade8be..a42a90bc2358 100644
--- a/svl/source/items/itemiter.cxx
+++ b/svl/source/items/itemiter.cxx
@@ -25,50 +25,44 @@
SfxItemIter::SfxItemIter( const SfxItemSet& rItemSet )
: m_rSet( rItemSet )
{
- // 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;
+ if (!m_rSet.m_nCount)
+ {
+ m_nStart = 1;
+ m_nEnd = 0;
}
- m_iter = m_keys.begin();
-}
+ else
+ {
+ SfxItemArray ppFnd = m_rSet.m_pItems;
-SfxItemIter::~SfxItemIter()
-{
-}
+ // 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;
+ }
-SfxPoolItem const * SfxItemIter::FirstItem()
-{
- m_iter = m_keys.begin();
- return GetCurItem();
+ m_nCurrent = m_nStart;
}
-SfxPoolItem const * SfxItemIter::GetCurItem()
+SfxItemIter::~SfxItemIter()
{
- 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;
}
-SfxPoolItem const * SfxItemIter::NextItem()
+const SfxPoolItem* SfxItemIter::NextItem()
{
- if (m_iter == m_keys.end())
- return nullptr;
- ++m_iter;
- if (m_iter == m_keys.end())
- return nullptr;
- return GetCurItem();
-}
+ SfxItemArray ppFnd = m_rSet.m_pItems;
-bool SfxItemIter::IsAtEnd() const
-{
- return m_iter == m_keys.end() || std::next(m_iter) == m_keys.end();
+ if (m_nCurrent < m_nEnd)
+ {
+ do {
+ m_nCurrent++;
+ } while (m_nCurrent < m_nEnd && !*(ppFnd + m_nCurrent ));
+ return *(ppFnd+m_nCurrent);
+ }
+ return nullptr;
}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 468ecb75f06d..9e44a8ba1889 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -101,6 +101,25 @@ 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;
+}
+
}
/**
@@ -113,16 +132,21 @@ sal_uInt16 Count_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);
@@ -132,17 +156,21 @@ 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)
{
- InitializeRanges_Impl(m_pWhichRanges, pArgs, nWh1, nWh2, nNull);
+ sal_uInt16 nSize = InitializeRanges_Impl(m_pWhichRanges, pArgs, nWh1, nWh2, nNull);
+ m_pItems = new const SfxPoolItem*[nSize]{};
}
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);
@@ -171,6 +199,8 @@ 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 );
@@ -179,7 +209,9 @@ 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 )
@@ -189,6 +221,7 @@ 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;
@@ -199,51 +232,58 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
pPtr += 2;
}
+ m_pItems = new const SfxPoolItem* [ nCnt ];
+
// Copy attributes
- 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?
+ 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?
// Just copy the pointer
- m_aItems.insert(rSrcPair);
- else if (m_pPool->IsItemPoolable( *rSrcPair.second ))
+ *ppDst = *ppSrc;
+ else if (m_pPool->IsItemPoolable( **ppSrc ))
{
// Just copy the pointer and increase RefCount
- m_aItems.insert(rSrcPair);
- rSrcPair.second->AddRef();
+ *ppDst = *ppSrc;
+ (*ppDst)->AddRef();
}
- else if ( !rSrcPair.second->Which() )
- m_aItems[rSrcPair.first] = rSrcPair.second->Clone();
+ else if ( !(*ppSrc)->Which() )
+ *ppDst = (*ppSrc)->Clone();
else
// !IsPoolable() => assign via Pool
- m_aItems[rSrcPair.first] = &m_pPool->Put( *rSrcPair.second );
- }
+ *ppDst = &m_pPool->Put( **ppSrc );
// 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()
{
- 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 );
+ 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 );
+ }
}
- }
+ }
+ delete[] m_pItems;
if (m_pWhichRanges != m_pPool->GetFrozenIdRanges())
delete[] m_pWhichRanges;
m_pWhichRanges = nullptr; // for invariant-testing
@@ -258,67 +298,89 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
return 0;
sal_uInt16 nDel = 0;
+ SfxItemArray ppFnd = m_pItems;
if( nWhich )
{
- auto it = m_aItems.find(nWhich);
- if (it != m_aItems.end())
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
{
- 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) )
+ // Within this range?
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- if (SfxItemPool::IsWhich(nWhich))
+ // Actually set?
+ ppFnd += nWhich - *pPtr;
+ if( *ppFnd )
{
- const SfxPoolItem& rNew = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
+ // Due to the assertions in the sub calls, we need to do the following
+ --m_nCount;
+ const SfxPoolItem *pItemToClear = *ppFnd;
+ *ppFnd = nullptr;
- Changed( *pItemToClear, rNew );
+ 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;
}
- if ( pItemToClear->Which() )
- m_pPool->Remove( *pItemToClear );
+
+ // found => break
+ break;
}
- ++nDel;
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
}
}
else
{
- nDel = m_aItems.size();
+ nDel = m_nCount;
- SfxItemMap aTmp;
- aTmp.swap(m_aItems);
- for (auto & rPair : aTmp)
+ sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
{
- const SfxPoolItem *pItemToClear = rPair.second;
- nWhich = rPair.first;
-
- if ( !IsInvalidItem(pItemToClear) )
- {
- if (SfxItemPool::IsWhich(nWhich))
+ for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( *ppFnd )
{
- 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 );
- }
- }
+ // Due to the assertions in the sub calls, we need to do this
+ --m_nCount;
+ const SfxPoolItem *pItemToClear = *ppFnd;
+ *ppFnd = nullptr;
+
+ 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;
}
}
return nDel;
@@ -326,30 +388,25 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
void SfxItemSet::ClearInvalidItems()
{
- for (auto it = m_aItems.begin(); it != m_aItems.end(); )
+ sal_uInt16* pPtr = m_pWhichRanges;
+ SfxItemArray ppFnd = m_pItems;
+ while( *pPtr )
{
- if( IsInvalidItem(it->second) )
- {
- it = m_aItems.erase(it);
- }
- else
- ++it;
+ for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( IsInvalidItem(*ppFnd) )
+ {
+ *ppFnd = nullptr;
+ --m_nCount;
+ }
+ pPtr += 2;
}
}
void SfxItemSet::InvalidateAllItems()
{
- 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;
- }
+ assert( !m_nCount && "There are still Items set" );
+ m_nCount = TotalCount();
+ memset(static_cast<void*>(m_pItems), -1, m_nCount * sizeof(SfxPoolItem*));
}
SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
@@ -361,44 +418,39 @@ 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) )
{
- 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;
+ // Within this range
+ ppFnd += nWhich - *pPtr;
+ if ( !*ppFnd )
+ {
+ eRet = SfxItemState::DEFAULT;
+ if( !bSrchInParent )
+ return eRet; // Not present
+ break; // Keep searching in the parents!
+ }
- if ( dynamic_cast<const SfxVoidItem *>(it->second) != nullptr )
- return SfxItemState::DISABLED;
+ if ( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd )
+ // Different ones are present
+ return SfxItemState::DONTCARE;
- if (ppItem)
- {
- *ppItem = it->second;
+ if ( dynamic_cast<const SfxVoidItem *>(*ppFnd) != nullptr )
+ return SfxItemState::DISABLED;
+
+ if (ppItem)
+ {
+ *ppItem = *ppFnd;
+ }
+ return SfxItemState::SET;
}
- return SfxItemState::SET;
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
}
}
} while (bSrchInParent && nullptr != (pAktSet = pAktSet->m_pParent));
@@ -418,83 +470,82 @@ const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich
if ( !nWhich )
return nullptr; //FIXME: Only because of Outliner bug
- bool bFound = false;
+ SfxItemArray ppFnd = m_pItems;
const sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- bFound = true;
- break;
- }
- pPtr += 2;
- }
- if (!bFound)
- return nullptr;
-
- auto it = m_aItems.find(nWhich);
- if (it != m_aItems.end()) // Already one present
- {
- // Same Item already present?
- if ( it->second == &rItem )
- return nullptr;
+ // Within this range
+ ppFnd += nWhich - *pPtr;
+ if( *ppFnd ) // Already one present
+ {
+ // Same Item already present?
+ if ( *ppFnd == &rItem )
+ return nullptr;
- // 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;
- }
- return it->second;
- }
+ // 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;
+ }
- // Turns into disabled?
- if( !rItem.Which() )
- {
- if (IsInvalidItem(it->second) || it->second->Which() != 0) {
- it->second = rItem.Clone(m_pPool);
+ // 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 );
+ }
}
- 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))
+ else
{
- const SfxPoolItem& rOld = m_pParent
- ? m_pParent->Get( nWhich )
- : m_pPool->GetDefaultItem( nWhich );
- Changed( rOld, rNew );
+ ++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 );
+ }
+ }
}
+ 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;
}
- 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;
+ return nullptr;
}
bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
@@ -502,19 +553,26 @@ bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
bool bRet = false;
if( rSet.Count() )
{
- for (auto const & rPair : rSet.m_aItems)
+ SfxItemArray ppFnd = rSet.m_pItems;
+ const sal_uInt16* pPtr = rSet.m_pWhichRanges;
+ while ( *pPtr )
{
- 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 );
+ 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;
}
}
return bRet;
@@ -543,15 +601,14 @@ 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 )
- {
- auto it = rSet.m_aItems.find(nWhich);
- if( it != rSet.m_aItems.end() )
+ for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( *ppFnd )
{
- if ( IsInvalidItem( it->second ) )
+ if ( IsInvalidItem( *ppFnd ) )
{
// Item ist DontCare:
switch ( eDontCareAs )
@@ -574,7 +631,7 @@ void SfxItemSet::PutExtended
}
else
// Item is set:
- Put( *it->second, nWhich );
+ Put( **ppFnd, nWhich );
}
else
{
@@ -597,7 +654,6 @@ void SfxItemSet::PutExtended
assert(!"invalid Argument for eDefaultAs");
}
}
- }
pPtr += 2;
}
}
@@ -693,8 +749,12 @@ void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
}
// create new item-array (by iterating through all new ranges)
- SfxItemMap aNewItems;
- if (!m_aItems.empty())
+ 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
{
sal_uInt16 n = 0;
for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
@@ -703,40 +763,45 @@ void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
{
// direct move of pointer (not via pool)
- auto it = m_aItems.find(nWID);
- if ( it == m_aItems.end())
+ SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
+ if ( SfxItemState::SET == eState )
{
- // default
+ // increment new item count and possibly increment ref count
+ ++nNewCount;
+ aNewItems[n]->AddRef();
}
- else if ( reinterpret_cast<SfxPoolItem*>(-1) == it->second )
+ else if ( SfxItemState::DISABLED == eState )
{
- // don't care
- aNewItems[nWID] = reinterpret_cast<SfxPoolItem*>(-1);
+ // put "disabled" item
+ ++nNewCount;
+ aNewItems[n] = new SfxVoidItem(0);
}
- else if ( dynamic_cast<const SfxVoidItem *>(it->second) != nullptr )
+ else if ( SfxItemState::DONTCARE == eState )
{
- // put "disabled" item
- aNewItems[nWID] = new SfxVoidItem(0);
+ ++nNewCount;
+ aNewItems[n] = reinterpret_cast<SfxPoolItem*>(-1);
}
else
{
- aNewItems[nWID] = it->second;
- // increment new item count and possibly increment ref count
- aNewItems[nWID]->AddRef();
+ // default
+ aNewItems[n] = nullptr;
}
}
}
// free old items
- for ( auto & rPair : m_aItems )
+ sal_uInt16 nOldTotalCount = TotalCount();
+ for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
{
- const SfxPoolItem *pItem = rPair.second;
- if ( !IsInvalidItem(pItem) && pItem->Which() )
+ const SfxPoolItem *pItem = m_pItems[nItem];
+ if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
m_pPool->Remove(*pItem);
}
}
// replace old items-array and ranges
- m_aItems.swap(aNewItems);
+ delete[] m_pItems;
+ m_pItems = aNewItems;
+ m_nCount = nNewCount;
if( pNewRanges == GetPool()->GetFrozenIdRanges() )
{
@@ -789,7 +854,7 @@ bool SfxItemSet::Set
)
{
bool bRet = false;
- if (!m_aItems.empty())
+ if (m_nCount)
ClearItem();
if ( bDeep )
{
@@ -833,24 +898,39 @@ const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
{
if( pAktSet->Count() )
{
- auto it = pAktSet->m_aItems.find(nWhich);
- if( it != pAktSet->m_aItems.end() )
+ SfxItemArray ppFnd = pAktSet->m_pItems;
+ const sal_uInt16* pPtr = pAktSet->m_pWhichRanges;
+ while( *pPtr )
{
- 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 );
- }
+ 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 );
+ }
#ifdef DBG_UTIL
- const SfxPoolItem *pItem = it->second;
- if ( dynamic_cast<const SfxVoidItem *>(pItem) != nullptr || !pItem->Which() )
- SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+ const SfxPoolItem *pItem = *ppFnd;
+ if ( dynamic_cast<const SfxVoidItem *>(pItem) != nullptr || !pItem->Which() )
+ SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
#endif
- return *it->second;
+ return **ppFnd;
+ }
+ break; // Continue with Parent
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
}
}
+//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
@@ -872,7 +952,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;
@@ -880,7 +960,7 @@ sal_uInt16 SfxItemSet::TotalCount() const
/**
* Only retain the Items that are also present in rSet
- * (never mind their value).
+ * (nevermind their value).
*/
void SfxItemSet::Intersect( const SfxItemSet& rSet )
{
@@ -895,17 +975,64 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet )
return;
}
- // 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;
+ // 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;
+ }
}
- for (sal_uInt16 nWhich : keys)
+ else
{
- if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
- ClearItem( nWhich ); // Delete
+ 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();
+ }
}
}
@@ -914,17 +1041,65 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
if( !Count() || !rSet.Count() )// None set?
return;
- // 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;
+ // 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;
+ }
}
- for (sal_uInt16 nWhich : keys)
+ else
{
- if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
- ClearItem( nWhich ); // Delete
+ 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();
+ }
+
}
}
@@ -1006,63 +1181,66 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
* dontcare unknown != sal_True - - -
* unknown unknown != sal_True - - -
*/
-static void MergeItem_Impl( SfxItemPool *_pPool,
- SfxItemMap& rItems, sal_uInt16 nWhich, const SfxPoolItem *pFnd2,
+static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
+ const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
bool bIgnoreDefaults )
{
- auto ppFnd1 = rItems.find(nWhich);
+ assert(ppFnd1 != nullptr && "Merging to 0-Item");
// 1st Item is Default?
- if ( ppFnd1 == rItems.end() )
+ if ( !*ppFnd1 )
{
if ( IsInvalidItem(pFnd2) )
// Decision table: default, dontcare, doesn't matter, doesn't matter
- rItems[nWhich] = reinterpret_cast<SfxPoolItem*>(-1);
+ *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
else if ( pFnd2 && !bIgnoreDefaults &&
_pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
// Decision table: default, set, !=, sal_False
- rItems[nWhich] = reinterpret_cast<SfxPoolItem*>(-1);
+ *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
else if ( pFnd2 && bIgnoreDefaults )
// Decision table: default, set, doesn't matter, sal_True
- rItems[nWhich] = &_pPool->Put( *pFnd2 );
+ *ppFnd1 = &_pPool->Put( *pFnd2 );
+
+ if ( *ppFnd1 )
+ ++rCount;
}
// 1st Item set?
- else if ( !IsInvalidItem(ppFnd1->second) )
+ else if ( !IsInvalidItem(*ppFnd1) )
{
if ( !pFnd2 )
{
// 2nd Item is Default
if ( !bIgnoreDefaults &&
- *ppFnd1->second != _pPool->GetDefaultItem(ppFnd1->second->Which()) )
+ **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
{
// Decision table: set, default, !=, sal_False
- _pPool->Remove( *ppFnd1->second );
- ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
}
}
else if ( IsInvalidItem(pFnd2) )
{
// 2nd Item is dontcare
if ( !bIgnoreDefaults ||
- *ppFnd1->second != _pPool->GetDefaultItem( ppFnd1->second->Which()) )
+ **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
{
// Decision table: set, dontcare, doesn't matter, sal_False
// or: set, dontcare, !=, sal_True
- _pPool->Remove( *ppFnd1->second );
- ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
}
}
else
{
// 2nd Item is set
- if ( *ppFnd1->second != *pFnd2 )
+ if ( **ppFnd1 != *pFnd2 )
{
// Decision table: set, set, !=, doesn't matter
- _pPool->Remove( *ppFnd1->second );
- ppFnd1->second = reinterpret_cast<SfxPoolItem*>(-1);
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
}
}
}
@@ -1087,82 +1265,96 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet )
if( n & 1 )
nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
}
+ bool bEqual = *pWh1 == *pWh2; // Also check for 0
- SfxWhichIter aIter( rSet );
- sal_uInt16 nWhich;
- while( 0 != ( nWhich = aIter.NextWhich() ) )
+ // If the Ranges match, they are easier to process!
+ if( bEqual )
{
- const SfxPoolItem* pItem = nullptr;
- (void)rSet.GetItemState( nWhich, true, &pItem );
- if( !pItem )
+ 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() ) )
{
- // Not set, so default
- MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ) );
+ 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 );
}
- 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) )
{
- bFound = true;
+ ppFnd += nWhich - *pPtr;
+ MergeItem_Impl(m_pPool, m_nCount, ppFnd, &rAttr, bIgnoreDefaults);
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 )
{
- bool bFound = false;
+ SfxItemArray ppFnd = m_pItems;
const sal_uInt16* pPtr = m_pWhichRanges;
while( *pPtr )
{
if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
{
- bFound = true;
+ // 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;
+ }
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 )
{
- sal_uInt16 n = *(pPtr+1) - *pPtr + 1;
+ n = ( *(pPtr+1) - *pPtr ) + 1;
if( nPos < n )
return *(pPtr)+nPos;
nPos = nPos - n;
@@ -1194,10 +1386,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_aItems.size() );
+ rStream.WriteUInt16( m_nCount );
// If there's nothing to save, don't construct an ItemIter
- if (!m_aItems.empty())
+ if (m_nCount)
{
// Keep record of how many Items are really saved
sal_uInt16 nWrittenCount = 0; // Count of Items streamed in 'rStream'
@@ -1217,7 +1409,7 @@ void SfxItemSet::Store
}
// Fewer written than read (e.g. old format)
- if (nWrittenCount != m_aItems.size())
+ if (nWrittenCount != m_nCount)
{
// Store real count in the stream
sal_uLong nPos = rStream.Tell();
@@ -1270,23 +1462,25 @@ 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) )
{
- bFound = true;
+ // 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;
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;
- }
}
}
}
@@ -1333,29 +1527,27 @@ bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
}
// Are all pointers the same?
- if ( m_aItems == rCmp.m_aItems )
+ if (0 == memcmp( m_pItems, rCmp.m_pItems, nCount1 * sizeof(m_pItems[0]) ))
return true;
// We need to compare each one separately then
- auto it1 = m_aItems.begin();
- auto it2 = rCmp.m_aItems.begin();
- for (;; ++it1, ++it2)
+ const SfxPoolItem **ppItem1 = m_pItems;
+ const SfxPoolItem **ppItem2 = rCmp.m_pItems;
+ for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
{
- 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)
+ // 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 ) )
return false;
+
+ ++ppItem1;
+ ++ppItem2;
}
+
return true;
}
@@ -1386,42 +1578,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) )
{
- bFound = true;
- break;
- }
- pPtr += 2;
- }
- if (!bFound)
- return;
+ // 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;
- 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) )
+ *ppFnd = &m_pPool->Put( rItem );
+ else
+ {
+ *ppFnd = &rItem;
+ if( !IsStaticDefaultItem( &rItem ) )
+ rItem.AddRef();
+ }
- // Add the new one
- if( IsPoolDefaultItem(&rItem) )
- m_aItems[nWhich] = &m_pPool->Put( rItem );
- else
- {
- m_aItems[nWhich] = &rItem;
- if( !IsStaticDefaultItem( &rItem ) )
- rItem.AddRef();
+ return;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
}
}
@@ -1455,6 +1648,9 @@ 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]{};
}
@@ -1503,17 +1699,61 @@ 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;
}
@@ -1523,24 +1763,35 @@ 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 )
{
- // Grow range downwards
+ // Range grows 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) )
{
- // Grow range upwards
+ // Range grows 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;
}
@@ -1562,28 +1813,32 @@ 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
- auto it = m_aItems.find(nWhich);
- const SfxPoolItem* pOld = nullptr;
- if (it != m_aItems.end())
- pOld = it->second;
+ bool bIncrementCount = false;
+ const SfxPoolItem* pOld = *( m_pItems + nPos );
if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare"
pOld = nullptr;
if ( !pOld )
{
- if (m_pParent)
- pOld = &m_pParent->Get( nWhich );
- else if (SfxItemPool::IsWhich(nWhich))
- pOld = &m_pPool->GetDefaultItem(nWhich);
+ bIncrementCount = true;
+ pOld = (m_pParent)
+ ? &m_pParent->Get( nWhich )
+ : (SfxItemPool::IsWhich(nWhich)
+ ? &m_pPool->GetDefaultItem(nWhich)
+ : nullptr);
}
// Add new Item to ItemSet
- m_aItems[nWhich] = &rNew;
+ *(m_pItems + nPos) = &rNew;
// Send Changed Notification
if ( pOld )
@@ -1593,6 +1848,9 @@ 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 630b111edf02..a7f025d1c11d 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 = aIter.GetCurWhich();
+ nWhich = rSet.GetWhichByPos( aIter.GetCurPos() );
aItem.pItem = const_cast<SfxPoolItem*>(pItem);
}
else
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 5e347f9fbac7..73b577712c86 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 = aIter.GetFirstWhich();
- nArrLen = aIter.GetLastWhich() - nArrStart + 1;
+ nArrStart = aCmpSet.GetWhichByPos( aIter.GetFirstPos() );
+ nArrLen = aCmpSet.GetWhichByPos( aIter.GetLastPos() ) - 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 = aIter.GetCurWhich();
+ nWhich = aCmpSet.GetWhichByPos( aIter.GetCurPos() );
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 = aIter.GetCurWhich();
+ nWhich = rCmpSet.GetWhichByPos( aIter.GetCurPos() );
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 331470225d06..0b0b21f33e69 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -531,7 +531,8 @@ void SwUndoSetFlyFormat::UndoImpl(::sw::UndoRedoContext & rContext)
while( pItem )
{
if( IsInvalidItem( pItem ))
- pFrameFormat->ResetFormatAttr( aIter.GetCurWhich() );
+ pFrameFormat->ResetFormatAttr( pItemSet->GetWhichByPos(
+ aIter.GetCurPos() ));
else
pFrameFormat->SetFormatAttr( *pItem );
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index 7a8a5f848822..a4257fa71fb3 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -1677,7 +1677,8 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet,
{
// use method <SwDoc::ResetAttrAtFormat(..)> in order to
// create an Undo object for the attribute reset.
- rDoc.ResetAttrAtFormat( aIter.GetCurWhich(), *pFormat );
+ rDoc.ResetAttrAtFormat( rSet.GetWhichByPos(aIter.GetCurPos()),
+ *pFormat );
}
if( aIter.IsAtEnd() )