[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