summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/source/core/bastyp/swcache.cxx17
-rw-r--r--sw/source/core/inc/swcache.hxx20
-rw-r--r--sw/source/core/inc/txtfrm.hxx4
-rw-r--r--sw/source/core/text/porrst.cxx2
-rw-r--r--sw/source/core/text/txtcache.cxx20
-rw-r--r--sw/source/core/text/txtcache.hxx2
-rw-r--r--sw/source/core/text/txtfrm.cxx5
7 files changed, 52 insertions, 18 deletions
diff --git a/sw/source/core/bastyp/swcache.cxx b/sw/source/core/bastyp/swcache.cxx
index 64eb233b6bf7..443e267b9006 100644
--- a/sw/source/core/bastyp/swcache.cxx
+++ b/sw/source/core/bastyp/swcache.cxx
@@ -296,6 +296,7 @@ void SwCache::DeleteObj( SwCacheObj *pObj )
pObj->GetNext()->SetPrev( pObj->GetPrev() );
m_aFreePositions.push_back( pObj->GetCachePos() );
+ assert(m_aCacheObjects[pObj->GetCachePos()].get() == pObj);
m_aCacheObjects[pObj->GetCachePos()] = nullptr; // deletes pObj
CHECK;
@@ -340,10 +341,18 @@ void SwCache::Delete( const void *pOwner )
DeleteObj( pObj );
}
-bool SwCache::Insert( SwCacheObj *pNew )
+bool SwCache::Insert(SwCacheObj *const pNew, bool const isDuplicateOwnerAllowed)
{
CHECK;
OSL_ENSURE( !pNew->GetPrev() && !pNew->GetNext(), "New but not new." );
+ if (!isDuplicateOwnerAllowed)
+ {
+ for (auto const & rpObj : m_aCacheObjects)
+ { // check owner doesn't have a cache object yet; required for SwTextLine
+ assert(!rpObj || rpObj->GetOwner() != pNew->GetOwner());
+ (void) rpObj;
+ }
+ }
sal_uInt16 nPos;
if ( m_aCacheObjects.size() < m_nCurMax )
@@ -374,7 +383,7 @@ bool SwCache::Insert( SwCacheObj *pNew )
{
SAL_WARN("sw.core", "SwCache overflow.");
IncreaseMax(100); // embiggen & try again
- return Insert(pNew);
+ return Insert(pNew, isDuplicateOwnerAllowed);
}
nPos = pObj->GetCachePos();
@@ -485,12 +494,12 @@ SwCacheAccess::~SwCacheAccess()
m_pObj->Unlock();
}
-void SwCacheAccess::Get_()
+void SwCacheAccess::Get_(bool const isDuplicateOwnerAllowed)
{
OSL_ENSURE( !m_pObj, "SwCacheAcces Obj already available." );
m_pObj = NewObj();
- if ( !m_rCache.Insert( m_pObj ) )
+ if (!m_rCache.Insert(m_pObj, isDuplicateOwnerAllowed))
{
delete m_pObj;
m_pObj = nullptr;
diff --git a/sw/source/core/inc/swcache.hxx b/sw/source/core/inc/swcache.hxx
index fe2d516168be..b8aa145e3a3e 100644
--- a/sw/source/core/inc/swcache.hxx
+++ b/sw/source/core/inc/swcache.hxx
@@ -101,7 +101,7 @@ public:
const bool bToTop = true );
void ToTop( SwCacheObj *pObj );
- bool Insert( SwCacheObj *pNew );
+ bool Insert(SwCacheObj *pNew, bool isDuplicateOwnerAllowed);
void Delete(const void * pOwner, sal_uInt16 nIndex);
void Delete( const void *pOwner );
@@ -146,7 +146,15 @@ class SwCacheObj
void SetNext( SwCacheObj *pNew ) { m_pNext = pNew; }
void SetPrev( SwCacheObj *pNew ) { m_pPrev = pNew; }
- void SetCachePos( const sal_uInt16 nNew ) { m_nCachePos = nNew; }
+ void SetCachePos(const sal_uInt16 nNew)
+ {
+ if (m_nCachePos != nNew)
+ {
+ m_nCachePos = nNew;
+ UpdateCachePos();
+ }
+ }
+ virtual void UpdateCachePos() { }
protected:
const void *m_pOwner;
@@ -187,7 +195,7 @@ class SwCacheAccess
{
SwCache &m_rCache;
- void Get_();
+ void Get_(bool isDuplicateOwnerAllowed);
protected:
SwCacheObj *m_pObj;
@@ -195,7 +203,7 @@ protected:
virtual SwCacheObj *NewObj() = 0;
- inline SwCacheObj *Get();
+ inline SwCacheObj *Get(bool isDuplicateOwnerAllowed);
inline SwCacheAccess( SwCache &rCache, const void *pOwner, bool bSeek );
inline SwCacheAccess( SwCache &rCache, const void* nCacheId, const sal_uInt16 nIndex );
@@ -241,10 +249,10 @@ inline SwCacheAccess::SwCacheAccess( SwCache &rC, const void* nCacheId,
m_pObj->Lock();
}
-inline SwCacheObj *SwCacheAccess::Get()
+inline SwCacheObj *SwCacheAccess::Get(bool const isDuplicateOwnerAllowed = true)
{
if ( !m_pObj )
- Get_();
+ Get_(isDuplicateOwnerAllowed);
return m_pObj;
}
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index c9deeb0c827e..afe590517923 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -602,8 +602,10 @@ public:
sal_uInt16 GetCacheIdx() const { return mnCacheIndex; }
void SetCacheIdx( const sal_uInt16 nNew ) { mnCacheIndex = nNew; }
- /// Removes the Line information from the Cache
+ /// Removes the Line information from the Cache but retains the entry itself
void ClearPara();
+ /// Removes this frame completely from the Cache
+ void RemoveFromCache();
/// Am I a FootnoteFrame, with a number at the start of the paragraph?
bool IsFootnoteNumFrame() const
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 3ae4b9623978..09611e728441 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -330,7 +330,7 @@ bool SwTextFrame::FormatEmpty()
ClearPara();
ResetBlinkPor();
}
- SetCacheIdx( USHRT_MAX );
+ RemoveFromCache();
if( !IsEmpty() )
{
SetEmpty( true );
diff --git a/sw/source/core/text/txtcache.cxx b/sw/source/core/text/txtcache.cxx
index fcc8b434cdd8..17eedcc17626 100644
--- a/sw/source/core/text/txtcache.cxx
+++ b/sw/source/core/text/txtcache.cxx
@@ -34,6 +34,13 @@ SwTextLine::~SwTextLine()
{
}
+void SwTextLine::UpdateCachePos()
+{
+ // note: SwTextFrame lives longer than its SwTextLine, see ~SwTextFrame
+ assert(m_pOwner);
+ const_cast<SwTextFrame *>(static_cast<SwTextFrame const *>(m_pOwner))->SetCacheIdx(GetCachePos());
+}
+
SwCacheObj *SwTextLineAccess::NewObj()
{
return new SwTextLine( static_cast<SwTextFrame const *>(m_pOwner) );
@@ -46,7 +53,7 @@ SwParaPortion *SwTextLineAccess::GetPara()
pRet = static_cast<SwTextLine*>(m_pObj);
else
{
- pRet = static_cast<SwTextLine*>(Get());
+ pRet = static_cast<SwTextLine*>(Get(false));
const_cast<SwTextFrame *>(static_cast<SwTextFrame const *>(m_pOwner))->SetCacheIdx( pRet->GetCachePos() );
}
if ( !pRet->GetPara() )
@@ -109,6 +116,15 @@ void SwTextFrame::ClearPara()
}
}
+void SwTextFrame::RemoveFromCache()
+{
+ if (GetCacheIdx() != USHRT_MAX)
+ {
+ s_pTextCache->Delete(this, GetCacheIdx());
+ SetCacheIdx(USHRT_MAX);
+ }
+}
+
void SwTextFrame::SetPara( SwParaPortion *pNew, bool bDelete )
{
if ( GetCacheIdx() != USHRT_MAX )
@@ -129,7 +145,7 @@ void SwTextFrame::SetPara( SwParaPortion *pNew, bool bDelete )
else if ( pNew )
{ // Insert a new one
SwTextLine *pTextLine = new SwTextLine( this, std::unique_ptr<SwParaPortion>(pNew) );
- if ( SwTextFrame::GetTextCache()->Insert( pTextLine ) )
+ if (SwTextFrame::GetTextCache()->Insert(pTextLine, false))
mnCacheIndex = pTextLine->GetCachePos();
else
{
diff --git a/sw/source/core/text/txtcache.hxx b/sw/source/core/text/txtcache.hxx
index c5f52944460f..d04a0eb63323 100644
--- a/sw/source/core/text/txtcache.hxx
+++ b/sw/source/core/text/txtcache.hxx
@@ -29,6 +29,8 @@ class SwTextLine : public SwCacheObj
{
std::unique_ptr<SwParaPortion> pLine;
+ virtual void UpdateCachePos() override;
+
public:
SwTextLine( SwTextFrame const *pFrame, std::unique_ptr<SwParaPortion> pNew = nullptr );
virtual ~SwTextLine() override;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 1c1443042649..931fbd75a4fa 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -881,10 +881,7 @@ void SwTextFrame::DestroyImpl()
SwTextFrame::~SwTextFrame()
{
- if (GetCacheIdx() != USHRT_MAX)
- {
- s_pTextCache->Delete(this, GetCacheIdx());
- }
+ RemoveFromCache();
}
namespace sw {