[Libreoffice-commits] core.git: sc/inc sc/source

László Németh laszlo.nemeth at collabora.com
Tue Jan 27 00:21:13 PST 2015


 sc/inc/address.hxx                  |    6 +++
 sc/source/core/tool/address.cxx     |   62 ++++++++++++++++++++++++++++++++++++
 sc/source/filter/excel/xeroot.cxx   |    1 
 sc/source/filter/excel/xestream.cxx |   10 +++++
 sc/source/filter/excel/xetable.cxx  |   10 +++--
 sc/source/filter/inc/xeroot.hxx     |    5 ++
 sc/source/filter/inc/xestream.hxx   |    3 +
 7 files changed, 93 insertions(+), 4 deletions(-)

New commits:
commit 779581feed4886313746a71e9e738d736977be1b
Author: László Németh <laszlo.nemeth at collabora.com>
Date:   Tue Jan 27 09:17:50 2015 +0100

    tdf#88810 avoid unnecessary massive O(U)String allocations in XLSX export
    
    Using OStringBuffer instead of fixed size character arrays.
    
    Change-Id: I06b705e2159a1ef5990f9eb0ffedd20fe277c616

diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 06c450b..a745c73 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -22,6 +22,7 @@
 
 #include <tools/stream.hxx>
 #include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
 #include <osl/endian.h>
 
 #include <limits>
@@ -325,6 +326,9 @@ public:
                     ExternalInfo* pExtInfo = NULL,
                     const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = NULL );
 
+    SC_DLLPUBLIC bool TryFormat( OStringBuffer& s, sal_uInt16 nFlags = 0,
+                                  const ScDocument* pDocument = NULL,
+                                  const Details& rDetails = detailsOOOa1) const;
     SC_DLLPUBLIC OUString Format( sal_uInt16 nFlags = 0,
                                   const ScDocument* pDocument = NULL,
                                   const Details& rDetails = detailsOOOa1) const;
@@ -888,6 +892,8 @@ bool ConvertDoubleRef( ScDocument* pDocument, const OUString& rRefString,
 /// append alpha representation of column to buffer
 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
 
+SC_DLLPUBLIC void ScColToAlpha( OStringBuffer& rBuffer, SCCOL nCol);
+
 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
 {
     OUStringBuffer aBuf(2);
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 39fc9a4..36cdb92 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -1745,6 +1745,40 @@ static OUString getFileNameFromDoc( const ScDocument* pDoc )
     return sFileName;
 }
 
+/** Tries to obtain a simple address without OUString/OString allocation
+ *
+ *  @returns TRUE at success (it is enough to call OUString Format() at FALSE)
+ *
+ */
+
+bool ScAddress::TryFormat(OStringBuffer& s, sal_uInt16 nFlags, const ScDocument* pDoc,
+                           const Details& rDetails) const
+{
+    if( nFlags & SCA_VALID )
+        nFlags |= ( SCA_VALID_ROW | SCA_VALID_COL | SCA_VALID_TAB );
+    if(( pDoc && (nFlags & SCA_VALID_TAB ) && ( nTab >= pDoc->GetTableCount() || ( nFlags & SCA_TAB_3D ))) ||
+         ! (nFlags & SCA_VALID_COL) || ! (nFlags & SCA_VALID_ROW) ||
+            (nFlags & SCA_COL_ABSOLUTE) != 0 || (nFlags & SCA_ROW_ABSOLUTE) != 0 )
+    {
+       return false;
+    }
+
+    switch( rDetails.eConv )
+    {
+    default :
+    case formula::FormulaGrammar::CONV_OOO:
+    case formula::FormulaGrammar::CONV_XL_A1:
+    case formula::FormulaGrammar::CONV_XL_OOX:
+        ScColToAlpha( s, nCol );
+        s.append( OString::number(nRow+1) );
+        break;
+    case formula::FormulaGrammar::CONV_XL_R1C1:
+        // not used in XLSX export
+        return false;
+    }
+    return true;
+}
+
 OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
                            const Details& rDetails) const
 {
@@ -2102,6 +2136,34 @@ void ScColToAlpha( OUStringBuffer& rBuf, SCCOL nCol )
     }
 }
 
+void ScColToAlpha( OStringBuffer& rBuf, SCCOL nCol )
+{
+    if (nCol < 26*26)
+    {
+        if (nCol < 26)
+            rBuf.append( static_cast<char>( 'A' + nCol ));
+        else
+        {
+            rBuf.append( static_cast<char>( 'A' + nCol / 26 - 1 ));
+            rBuf.append( static_cast<char>( 'A' + nCol % 26 ));
+        }
+    }
+    else
+    {
+        OString aStr;
+        while (nCol >= 26)
+        {
+            SCCOL nC = nCol % 26;
+            aStr += OString( static_cast<char> ( 'A' + nC ));
+            nCol = sal::static_int_cast<SCCOL>( nCol - nC );
+            nCol = nCol / 26 - 1;
+        }
+        aStr += OString( static_cast<char> ( 'A' + nCol ));
+        rBuf.append(comphelper::string::reverseString(aStr));
+    }
+}
+
+
 bool AlphaToCol( SCCOL& rCol, const OUString& rStr)
 {
     SCCOL nResult = 0;
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
index 819fe93..29f6551 100644
--- a/sc/source/filter/excel/xeroot.cxx
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -57,6 +57,7 @@ XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
 {
     SvtSaveOptions aSaveOpt;
     mbRelUrl = mrMedium.IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
+    maStringBuf = OStringBuffer(10); // for simple addresses, like ABC1000000
 }
 
 XclExpRootData::~XclExpRootData()
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index e5ff50c..04dbb5f 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -718,6 +718,11 @@ OString XclXmlUtils::ToOString( const OUString& s )
     return OUStringToOString( s, RTL_TEXTENCODING_UTF8  );
 }
 
+bool XclXmlUtils::TryToOString( OStringBuffer& s, const ScAddress& rAddress )
+{
+    return rAddress.TryFormat(s, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1));
+}
+
 OString XclXmlUtils::ToOString( const ScAddress& rAddress )
 {
     OUString sAddress(rAddress.Format(SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1)));
@@ -760,6 +765,11 @@ static ScAddress lcl_ToAddress( const XclAddress& rAddress )
     return aAddress;
 }
 
+bool XclXmlUtils::TryToOString( OStringBuffer& s, const XclAddress& rAddress )
+{
+    return TryToOString( s, lcl_ToAddress( rAddress ));
+}
+
 OString XclXmlUtils::ToOString( const XclAddress& rAddress )
 {
     return ToOString( lcl_ToAddress( rAddress ) );
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 70f3373..5919c61 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -631,8 +631,9 @@ static OString lcl_GetStyleId( XclExpXmlStream& rStrm, const XclExpCellBase& rCe
 void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+    OStringBuffer rBuf = rStrm.GetRoot().GetStringBuf();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::TryToOString( rBuf, GetXclPos() ) ? rBuf.getStr() : XclXmlUtils::ToOString( GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      "n",
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -923,11 +924,11 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
 {
     const char* sType = NULL;
     OUString    sValue;
-
     XclXmlUtils::GetFormulaTypeAndValue( mrScFmlaCell, sType, sValue );
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+    OStringBuffer rBuf = rStrm.GetRoot().GetStringBuf();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::TryToOString( rBuf, GetXclPos() ) ? rBuf.getStr() : XclXmlUtils::ToOString( GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      sType,
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -1308,8 +1309,9 @@ bool XclExpRkCell::TryMerge( const XclExpCellBase& rCell )
 void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+    OStringBuffer rBuf = rStrm.GetRoot().GetStringBuf();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( rAddress ).getStr(),
+            XML_r,      XclXmlUtils::TryToOString( rBuf, rAddress ) ? rBuf.getStr() : XclXmlUtils::ToOString( rAddress ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, nXFId ).getStr(),
             XML_t,      "n",
             // OOXTODO: XML_cm, XML_vm, XML_ph
diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx
index 698b0e4..2272134 100644
--- a/sc/source/filter/inc/xeroot.hxx
+++ b/sc/source/filter/inc/xeroot.hxx
@@ -99,6 +99,8 @@ struct XclExpRootData : public XclRootData
 
     bool                mbRelUrl;           /// true = Store URLs relative.
 
+    OStringBuffer       maStringBuf;        /// buffer to avoid massive OUString allocations
+
     explicit            XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
                             SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc );
     virtual             ~XclExpRootData();
@@ -150,6 +152,9 @@ public:
     /** Returns the differential formatting list */
     XclExpDxfs&          GetDxfs() const;
 
+    /** Clean and return the OStringBuffer */
+    inline OStringBuffer&   GetStringBuf() const { mrExpData.maStringBuf.setLength(0); return mrExpData.maStringBuf; }
+
     XclExpXmlPivotTableManager& GetXmlPivotTableManager();
 
     /** Is called when export filter starts to create the Excel document (all BIFF versions). */
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index df1f7a3..0b10e48 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -25,6 +25,7 @@
 #include <map>
 #include <stack>
 #include <string>
+#include <rtl/strbuf.hxx>
 
 #include <oox/core/xmlfilterbase.hxx>
 #include <oox/token/tokens.hxx>
@@ -266,9 +267,11 @@ public:
     static OString ToOString( const Color& rColor );
     static OString ToOString( const OUString& s );
     static OString ToOString( const ScfUInt16Vec& rBuffer );
+    static bool TryToOString( OStringBuffer& s, const ScAddress& rRange );
     static OString ToOString( const ScAddress& rRange );
     static OString ToOString( const ScRange& rRange );
     static OString ToOString( const ScRangeList& rRangeList );
+    static bool TryToOString( OStringBuffer& s, const XclAddress& rAddress );
     static OString ToOString( const XclAddress& rAddress );
     static OString ToOString( const XclExpString& s );
     static OString ToOString( const XclRange& rRange );


More information about the Libreoffice-commits mailing list