summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--formula/source/core/api/token.cxx54
-rw-r--r--include/formula/tokenarray.hxx14
2 files changed, 68 insertions, 0 deletions
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 3c3bdc55124a..0eb906642636 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -856,6 +856,60 @@ FormulaToken* FormulaTokenArray::ReplaceToken( sal_uInt16 nOffset, FormulaToken*
}
}
+void FormulaTokenArray::RemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount )
+{
+ if (nOffset < nLen)
+ {
+ SAL_WARN_IF( nOffset + nCount > nLen, "formula.core",
+ "FormulaTokenArray::RemoveToken - nOffset " << nOffset << " + nCount " << nCount << " > nLen " << nLen);
+ const sal_uInt16 nStop = ::std::min( static_cast<sal_uInt16>(nOffset + nCount), nLen);
+ nCount = nStop - nOffset;
+ for (sal_uInt16 j = nOffset; j < nStop; ++j)
+ {
+ FormulaToken* p = pCode[j];
+ if (p->GetRef() > 1)
+ {
+ for (sal_uInt16 i=0; i < nRPN; ++i)
+ {
+ if (pRPN[i] == p)
+ {
+ // Shift remaining tokens in pRPN down.
+ for (sal_uInt16 x=i+1; x < nRPN; ++x)
+ {
+ pRPN[x-1] = pRPN[x];
+ }
+ --nRPN;
+
+ p->DecRef();
+ if (p->GetRef() == 1)
+ break; // for
+ }
+ }
+ }
+ p->DecRef(); // may be dead now
+ }
+
+ // Shift remaining tokens in pCode down.
+ for (sal_uInt16 x = nStop; x < nLen; ++x)
+ {
+ pCode[x-nCount] = pCode[x];
+ }
+ nLen -= nCount;
+
+ if (nIndex >= nOffset)
+ {
+ if (nIndex < nStop)
+ nIndex = nOffset + 1;
+ else
+ nIndex -= nStop - nOffset;
+ }
+ }
+ else
+ {
+ SAL_WARN("formula.core","FormulaTokenArray::RemoveToken - nOffset " << nOffset << " >= nLen " << nLen);
+ }
+}
+
FormulaToken* FormulaTokenArray::Add( FormulaToken* t )
{
if( !pCode )
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 6ba48febea67..e7f32316eae2 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -155,6 +155,20 @@ protected:
*/
FormulaToken* ReplaceToken( sal_uInt16 nOffset, FormulaToken*, ReplaceMode eMode );
+ /** Remove a sequence of tokens from pCode array, and pRPN array if the
+ tokens are referenced there.
+
+ This' nLen and nRPN are adapted, as is nIndex if it points behind
+ nOffset. If nIndex points into the to be removed range
+ (nOffset < nIndex < nOffset+nCount) it is set to nOffset+1.
+
+ @param nOffset
+ Start offset into pCode.
+ @param nCount
+ Count of tokens to remove.
+ */
+ void RemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount );
+
inline void SetCombinedBitsRecalcMode( ScRecalcMode nBits )
{ nMode |= (nBits & ~RECALCMODE_EMASK); }
inline ScRecalcMode GetCombinedBitsRecalcMode() const