[Libreoffice-commits] core.git: Branch 'private/kohei/formula-opencl-work' - 3 commits - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Mon Sep 9 17:36:27 PDT 2013
sc/inc/formulacell.hxx | 1
sc/inc/formularesult.hxx | 1
sc/source/core/data/column2.cxx | 168 ++++++++++++++++++++++++++--------
sc/source/core/data/formulacell.cxx | 11 ++
sc/source/core/tool/formulagroup.cxx | 28 ++---
sc/source/core/tool/formularesult.cxx | 49 +++++++++
6 files changed, 206 insertions(+), 52 deletions(-)
New commits:
commit e6d9e1fce1ed92d8e36af4d542690ccc246083cd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Sep 9 20:39:17 2013 -0400
Eliminate (almost) duplicate code blocks.
Change-Id: Ib5d0fae3efda6bde056f7e4990de57c8b3541549
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 048402f..42c5469 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2050,6 +2050,26 @@ void ScColumn::FillMatrix( ScMatrix& rMat, size_t nMatCol, SCROW nRow1, SCROW nR
namespace {
+template<typename _Blk>
+void getBlockIterators(
+ sc::CellStoreType::iterator it, size_t& rLenRemain,
+ typename _Blk::iterator& rData, typename _Blk::iterator& rDataEnd )
+{
+ rData = _Blk::begin(*it->data);
+ if (rLenRemain >= it->size)
+ {
+ // Block is shorter than the remaining requested length.
+ rDataEnd = _Blk::end(*it->data);
+ rLenRemain -= it->size;
+ }
+ else
+ {
+ rDataEnd = rData;
+ std::advance(rDataEnd, rLenRemain);
+ rLenRemain = 0;
+ }
+}
+
bool appendDouble(
sc::FormulaGroupContext::NumArrayType& rArray, size_t nLen,
sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
@@ -2064,20 +2084,8 @@ bool appendDouble(
{
case sc::element_type_numeric:
{
- sc::numeric_block::iterator itData = sc::numeric_block::begin(*it->data);
- sc::numeric_block::iterator itDataEnd;
- if (nLenRemain >= it->size)
- {
- // Block is shorter than the remaining requested length.
- itDataEnd = sc::numeric_block::end(*it->data);
- nLenRemain -= it->size;
- }
- else
- {
- itDataEnd = itData;
- std::advance(itDataEnd, nLenRemain);
- nLenRemain = 0;
- }
+ sc::numeric_block::iterator itData, itDataEnd;
+ getBlockIterators<sc::numeric_block>(it, nLenRemain, itData, itDataEnd);
for (; itData != itDataEnd; ++itData)
rArray.push_back(*itData);
@@ -2085,20 +2093,8 @@ bool appendDouble(
break;
case sc::element_type_formula:
{
- sc::formula_block::iterator itData = sc::formula_block::begin(*it->data);
- sc::formula_block::iterator itDataEnd;
- if (nLenRemain >= it->size)
- {
- // Block is shorter than the remaining requested length.
- itDataEnd = sc::formula_block::end(*it->data);
- nLenRemain -= it->size;
- }
- else
- {
- itDataEnd = itData;
- std::advance(itDataEnd, nLenRemain);
- nLenRemain = 0;
- }
+ sc::formula_block::iterator itData, itDataEnd;
+ getBlockIterators<sc::formula_block>(it, nLenRemain, itData, itDataEnd);
sal_uInt16 nErr;
double fVal;
@@ -2161,20 +2157,8 @@ bool appendStrings(
{
case sc::element_type_string:
{
- sc::string_block::iterator itData = sc::string_block::begin(*it->data);
- sc::string_block::iterator itDataEnd;
- if (nLenRemain >= it->size)
- {
- // Block is shorter than the remaining requested length.
- itDataEnd = sc::string_block::end(*it->data);
- nLenRemain -= it->size;
- }
- else
- {
- itDataEnd = itData;
- std::advance(itDataEnd, nLenRemain);
- nLenRemain = 0;
- }
+ sc::string_block::iterator itData, itDataEnd;
+ getBlockIterators<sc::string_block>(it, nLenRemain, itData, itDataEnd);
for (; itData != itDataEnd; ++itData)
rArray.push_back(rCxt.intern(*itData));
@@ -2182,20 +2166,8 @@ bool appendStrings(
break;
case sc::element_type_edittext:
{
- sc::edittext_block::iterator itData = sc::edittext_block::begin(*it->data);
- sc::edittext_block::iterator itDataEnd;
- if (nLenRemain >= it->size)
- {
- // Block is shorter than the remaining requested length.
- itDataEnd = sc::edittext_block::end(*it->data);
- nLenRemain -= it->size;
- }
- else
- {
- itDataEnd = itData;
- std::advance(itDataEnd, nLenRemain);
- nLenRemain = 0;
- }
+ sc::edittext_block::iterator itData, itDataEnd;
+ getBlockIterators<sc::edittext_block>(it, nLenRemain, itData, itDataEnd);
for (; itData != itDataEnd; ++itData)
{
@@ -2206,20 +2178,8 @@ bool appendStrings(
break;
case sc::element_type_formula:
{
- sc::formula_block::iterator itData = sc::formula_block::begin(*it->data);
- sc::formula_block::iterator itDataEnd;
- if (nLenRemain >= it->size)
- {
- // Block is shorter than the remaining requested length.
- itDataEnd = sc::formula_block::end(*it->data);
- nLenRemain -= it->size;
- }
- else
- {
- itDataEnd = itData;
- std::advance(itDataEnd, nLenRemain);
- nLenRemain = 0;
- }
+ sc::formula_block::iterator itData, itDataEnd;
+ getBlockIterators<sc::formula_block>(it, nLenRemain, itData, itDataEnd);
sal_uInt16 nErr;
OUString aStr;
commit 6fc2ca3ccabca19bb87bc53fcbe074a2a61bdb46
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Sep 9 19:36:30 2013 -0400
Support fetching string array that spans over multiple blocks.
Change-Id: I543fca231e0be886159b8ddbd83ceffa1bf69c1b
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 835eb91..a494759 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -252,6 +252,7 @@ public:
sal_uInt16 GetErrCode(); // interpret first if necessary
sal_uInt16 GetRawError(); // don't interpret, just return code or result error
bool GetErrorOrValue( sal_uInt16& rErr, double& rVal );
+ bool GetErrorOrString( sal_uInt16& rErr, OUString& rStr );
sal_uInt8 GetMatrixFlag() const;
ScTokenArray* GetCode();
const ScTokenArray* GetCode() const;
diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx
index f1f7b5d..2459bcf 100644
--- a/sc/inc/formularesult.hxx
+++ b/sc/inc/formularesult.hxx
@@ -135,6 +135,7 @@ public:
bool IsMultiline() const;
bool GetErrorOrDouble( sal_uInt16& rErr, double& rVal ) const;
+ bool GetErrorOrString( sal_uInt16& rErr, OUString& rStr ) const;
/** Get error code if set or GetCellResultType() is formula::svError or svUnknown,
else 0. */
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 7a97972..048402f 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2148,6 +2148,138 @@ bool appendDouble(
return false;
}
+bool appendStrings(
+ sc::FormulaGroupContext& rCxt, ScDocument* pDoc,
+ sc::FormulaGroupContext::StrArrayType& rArray, size_t nLen,
+ sc::CellStoreType::iterator it, const sc::CellStoreType::iterator& itEnd )
+{
+ size_t nLenRemain = nLen;
+
+ for (; it != itEnd; ++it)
+ {
+ switch (it->type)
+ {
+ case sc::element_type_string:
+ {
+ sc::string_block::iterator itData = sc::string_block::begin(*it->data);
+ sc::string_block::iterator itDataEnd;
+ if (nLenRemain >= it->size)
+ {
+ // Block is shorter than the remaining requested length.
+ itDataEnd = sc::string_block::end(*it->data);
+ nLenRemain -= it->size;
+ }
+ else
+ {
+ itDataEnd = itData;
+ std::advance(itDataEnd, nLenRemain);
+ nLenRemain = 0;
+ }
+
+ for (; itData != itDataEnd; ++itData)
+ rArray.push_back(rCxt.intern(*itData));
+ }
+ break;
+ case sc::element_type_edittext:
+ {
+ sc::edittext_block::iterator itData = sc::edittext_block::begin(*it->data);
+ sc::edittext_block::iterator itDataEnd;
+ if (nLenRemain >= it->size)
+ {
+ // Block is shorter than the remaining requested length.
+ itDataEnd = sc::edittext_block::end(*it->data);
+ nLenRemain -= it->size;
+ }
+ else
+ {
+ itDataEnd = itData;
+ std::advance(itDataEnd, nLenRemain);
+ nLenRemain = 0;
+ }
+
+ for (; itData != itDataEnd; ++itData)
+ {
+ OUString aStr = ScEditUtil::GetString(**itData, pDoc);
+ rArray.push_back(rCxt.intern(aStr));
+ }
+ }
+ break;
+ case sc::element_type_formula:
+ {
+ sc::formula_block::iterator itData = sc::formula_block::begin(*it->data);
+ sc::formula_block::iterator itDataEnd;
+ if (nLenRemain >= it->size)
+ {
+ // Block is shorter than the remaining requested length.
+ itDataEnd = sc::formula_block::end(*it->data);
+ nLenRemain -= it->size;
+ }
+ else
+ {
+ itDataEnd = itData;
+ std::advance(itDataEnd, nLenRemain);
+ nLenRemain = 0;
+ }
+
+ sal_uInt16 nErr;
+ OUString aStr;
+ for (; itData != itDataEnd; ++itData)
+ {
+ ScFormulaCell& rFC = **itData;
+ if (!rFC.GetErrorOrString(nErr, aStr) || nErr)
+ {
+ if (nErr == ScErrorCodes::errCircularReference)
+ {
+ // This cell needs to be recalculated on next visit.
+ rFC.SetErrCode(0);
+ rFC.SetDirtyVar();
+ }
+ return false;
+ }
+
+ rArray.push_back(rCxt.intern(aStr));
+ }
+ }
+ break;
+ case sc::element_type_empty:
+ {
+ // Fill it with NULL pointers.
+ if (nLenRemain >= it->size)
+ {
+ rArray.resize(rArray.size() + it->size, NULL);
+ nLenRemain -= it->size;
+ }
+ else
+ {
+ rArray.resize(rArray.size() + nLenRemain, NULL);
+ nLenRemain = 0;
+ }
+ }
+ break;
+ case sc::element_type_numeric:
+ default:
+ return false;
+ }
+
+ if (!nLenRemain)
+ return true;
+ }
+
+ return false;
+}
+
+void copyFirstBlock( sc::FormulaGroupContext& rCxt, size_t nLen, const sc::CellStoreType::position_type& rPos )
+{
+ rCxt.maStrArrays.push_back(new sc::FormulaGroupContext::StrArrayType);
+ sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
+ rArray.reserve(nLen);
+
+ const OUString* p = &sc::string_block::at(*rPos.first->data, rPos.second);
+ const OUString* pEnd = p + nLen;
+ for (; p != pEnd; ++p)
+ rArray.push_back(rCxt.intern(*p));
+}
+
}
formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 )
@@ -2256,20 +2388,20 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( sc::FormulaGroupContext&
if (nLenRequested <= nLen)
{
// Requested length fits a single block.
- rCxt.maStrArrays.push_back(new sc::FormulaGroupContext::StrArrayType);
+ copyFirstBlock(rCxt, nLenRequested, aPos);
sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
- rArray.reserve(nLenRequested);
-
- const OUString* p = &sc::string_block::at(*aPos.first->data, aPos.second);
- const OUString* pEnd = p + nLenRequested;
- for (; p != pEnd; ++p)
- rArray.push_back(rCxt.intern(*p));
-
return formula::VectorRefArray(&rArray[0]);
}
- // TODO: handle cases where the requested length goes beyond the
- // current block just like we do with numeric array.
+ copyFirstBlock(rCxt, nLen, aPos);
+ sc::FormulaGroupContext::StrArrayType& rArray = rCxt.maStrArrays.back();
+
+ // Fill the remaining array with values from the following blocks.
+ ++aPos.first;
+ if (!appendStrings(rCxt, pDocument, rArray, nLenRequested - nLen, aPos.first, maCells.end()))
+ return formula::VectorRefArray();
+
+ return formula::VectorRefArray(&rArray[0]);
}
break;
case sc::element_type_empty:
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 143351e8..f8f344d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2082,6 +2082,17 @@ bool ScFormulaCell::GetErrorOrValue( sal_uInt16& rErr, double& rVal )
return aResult.GetErrorOrDouble(rErr, rVal);
}
+bool ScFormulaCell::GetErrorOrString( sal_uInt16& rErr, OUString& rStr )
+{
+ MaybeInterpret();
+
+ rErr = pCode->GetCodeError();
+ if (rErr)
+ return true;
+
+ return aResult.GetErrorOrString(rErr, rStr);
+}
+
bool ScFormulaCell::HasOneReference( ScRange& r ) const
{
pCode->Reset();
diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index 77de2ae..c232a31 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -255,6 +255,19 @@ inline bool isValue( formula::StackVar sv )
|| sv == formula::svEmptyCell || sv == formula::svHybridValueCell;
}
+inline bool isString( formula::StackVar sv )
+{
+ switch (sv)
+ {
+ case formula::svString:
+ case formula::svHybridCell:
+ case formula::svHybridValueCell:
+ return true;
+ }
+
+ return false;
+}
+
}
bool ScFormulaResult::IsValue() const
@@ -321,6 +334,42 @@ bool ScFormulaResult::GetErrorOrDouble( sal_uInt16& rErr, double& rVal ) const
return true;
}
+bool ScFormulaResult::GetErrorOrString( sal_uInt16& rErr, OUString& rStr ) const
+{
+ if (mnError)
+ {
+ rErr = mnError;
+ return true;
+ }
+
+ formula::StackVar sv = GetCellResultType();
+ if (sv == formula::svError)
+ {
+ if (GetType() == formula::svMatrixCell)
+ {
+ // don't need to test for mpToken here, GetType() already did it
+ rErr = static_cast<const ScMatrixCellResultToken*>(mpToken)->
+ GetUpperLeftToken()->GetError();
+ }
+ else if (mpToken)
+ {
+ rErr = mpToken->GetError();
+ }
+ }
+
+ if (rErr)
+ return true;
+
+ if (!mbToken)
+ return false;
+
+ if (!isString(sv))
+ return false;
+
+ rStr = GetString();
+ return true;
+}
+
sal_uInt16 ScFormulaResult::GetResultError() const
{
if (mnError)
commit d27053e92838bf68e0e8348f65d6d111b318824c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Sep 9 18:53:33 2013 -0400
Move common code blocks to a function.
Change-Id: I1b1aaa0b1dd8cc6e14fbac1981c67a8b63c92c2c
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 0b37b97..5dff3d9 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -83,6 +83,18 @@ void fillMatrix( ScMatrix& rMat, size_t nCol, const double* pNums, size_t nLen )
}
}
+void flushSegment(
+ ScMatrix& rMat, size_t nCol, rtl_uString** pHead, rtl_uString** pCur, rtl_uString** pTop )
+{
+ size_t nOffset = pHead - pTop;
+ std::vector<OUString> aStrs;
+ aStrs.reserve(pCur - pHead);
+ for (; pHead != pCur; ++pHead)
+ aStrs.push_back(OUString(*pHead));
+
+ rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
+}
+
void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
{
rtl_uString** p = pStrs;
@@ -102,13 +114,7 @@ void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
if (pHead)
{
// Flush this non-empty segment to the matrix.
- size_t nOffset = pHead - pStrs;
- std::vector<OUString> aStrs;
- aStrs.reserve(p - pHead);
- for (; pHead != p; ++pHead)
- aStrs.push_back(OUString(*pHead));
-
- rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
+ flushSegment(rMat, nCol, pHead, p, pStrs);
pHead = NULL;
}
}
@@ -116,13 +122,7 @@ void fillMatrix( ScMatrix& rMat, size_t nCol, rtl_uString** pStrs, size_t nLen )
if (pHead)
{
// Flush last non-empty segment to the matrix.
- size_t nOffset = pHead - pStrs;
- std::vector<OUString> aStrs;
- aStrs.reserve(p - pHead);
- for (; pHead != p; ++pHead)
- aStrs.push_back(OUString(*pHead));
-
- rMat.PutString(&aStrs[0], aStrs.size(), nCol, nOffset);
+ flushSegment(rMat, nCol, pHead, p, pStrs);
}
}
More information about the Libreoffice-commits
mailing list