[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - sc/inc sc/source

László Németh laszlo.nemeth at collabora.com
Mon Feb 2 12:15:01 PST 2015


 sc/inc/address.hxx                  |    5 +
 sc/source/core/tool/address.cxx     |  128 +++++++++++++++++++++---------------
 sc/source/filter/excel/xeroot.cxx   |    1 
 sc/source/filter/excel/xestream.cxx |   10 +-
 sc/source/filter/excel/xetable.cxx  |   13 +--
 sc/source/filter/excel/xeview.cxx   |    6 -
 sc/source/filter/inc/xeroot.hxx     |    5 +
 sc/source/filter/inc/xestream.hxx   |    5 -
 8 files changed, 105 insertions(+), 68 deletions(-)

New commits:
commit 86df2b436d387ff1282089267e1837f17aff5cda
Author: László Németh <laszlo.nemeth at collabora.com>
Date:   Mon Feb 2 08:52:53 2015 +0100

    tdf#88810 avoid unnecessary massive O(U)String allocations in XLSX export
    
    ToOString(XclAddress/ScAddress) functions are replaced with
    ToOString(OStringBuffer&, XclAddress/ScAddress) ones, using
    the new shared OStringBuffer variable of XclExpRootData
    
    Cherry-picked from master:
    
    b2df899dbb038acfe3c47eef303345ceaf3725b8 (build fix)
    99674f754323ca78ac45499439b9983b31ebd444 (append() for number to string conv.)
    f0152b737d9a196e83752a546154735efee5c2be (more cleanup)
    cc724c37232b721537d66c997a66c0d7866948ea (cleanup)
    779581feed4886313746a71e9e738d736977be1b (original)
    
    Change-Id: I06b705e2159a1ef5990f9eb0ffedd20fe277c616
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 06c450b..6bf55340 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,10 @@ public:
                     ExternalInfo* pExtInfo = NULL,
                     const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = NULL );
 
+    SC_DLLPUBLIC void Format( OStringBuffer& r, 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;
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 1efcac7..06e49b7 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -1672,50 +1672,81 @@ sal_uInt16 ScRange::ParseRows( const OUString& rStr, ScDocument* pDoc,
     return (p != NULL && *p == '\0') ? nRes : 0;
 }
 
-static inline void lcl_a1_append_c ( OUStringBuffer &rString, int nCol, bool bIsAbs )
+template<typename T > static inline void lcl_ScColToAlpha( T& 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
+    {
+        sal_Int32 nInsert = rBuf.getLength();
+        while (nCol >= 26)
+        {
+            SCCOL nC = nCol % 26;
+            rBuf.insert(nInsert, static_cast<char> ( 'A' + nC ));
+            nCol = sal::static_int_cast<SCCOL>( nCol - nC );
+            nCol = nCol / 26 - 1;
+        }
+        rBuf.insert(nInsert, static_cast<char> ( 'A' + nCol ));
+    }
+}
+
+void ScColToAlpha( OUStringBuffer& rBuf, SCCOL nCol)
+{
+    lcl_ScColToAlpha(rBuf, nCol);
+}
+
+template <typename T > static inline void lcl_a1_append_c ( T &rString, int nCol, bool bIsAbs )
 {
     if( bIsAbs )
         rString.append("$");
-    ScColToAlpha( rString, sal::static_int_cast<SCCOL>(nCol) );
+    lcl_ScColToAlpha( rString, sal::static_int_cast<SCCOL>(nCol) );
 }
 
-static inline void lcl_a1_append_r ( OUStringBuffer &rString, int nRow, bool bIsAbs )
+template <typename T > static inline void lcl_a1_append_r ( T &rString, sal_Int32 nRow, bool bIsAbs )
 {
     if ( bIsAbs )
         rString.append("$");
-    rString.append(OUString::number( nRow+1 ));
+    rString.append( nRow + 1 );
 }
 
-static inline void lcl_r1c1_append_c ( OUStringBuffer &rString, int nCol, bool bIsAbs,
+template <typename T > static inline void lcl_r1c1_append_c ( T &rString, sal_Int32 nCol, bool bIsAbs,
                                        const ScAddress::Details& rDetails )
 {
     rString.append("C");
     if (bIsAbs)
     {
-        rString.append(OUString::number( nCol + 1 ));
+        rString.append( nCol + 1 );
     }
     else
     {
         nCol -= rDetails.nCol;
         if (nCol != 0) {
-            rString.append("[").append(OUString::number( nCol )).append("]");
+            rString.append("[").append(nCol).append("]");
         }
     }
 }
 
-static inline void lcl_r1c1_append_r ( OUStringBuffer &rString, int nRow, bool bIsAbs,
+template <typename T > static inline void lcl_r1c1_append_r ( T &rString, sal_Int32 nRow, bool bIsAbs,
                                        const ScAddress::Details& rDetails )
 {
     rString.append("R");
     if (bIsAbs)
     {
-        rString.append(OUString::number( nRow + 1 ));
+        rString.append( nRow + 1 );
     }
     else
     {
         nRow -= rDetails.nRow;
         if (nRow != 0) {
-            rString.append("[").append(OUString::number( nRow )).append("]");
+            rString.append("[").append(nRow).append("]");
         }
     }
 }
@@ -1745,17 +1776,29 @@ static OUString getFileNameFromDoc( const ScDocument* pDoc )
     return sFileName;
 }
 
-OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
-                           const Details& rDetails) const
+
+static inline void lcl_string_append(OUStringBuffer &rString, const OUString &sString)
+{
+    rString.append(sString);
+}
+
+static inline void lcl_string_append(OStringBuffer &rString, const OUString &sString)
+{
+    rString.append(OUStringToOString( sString, RTL_TEXTENCODING_UTF8  ));
+}
+
+template<typename T > inline void lcl_Format( T& r, SCTAB nTab, SCROW nRow, SCCOL nCol, sal_uInt16 nFlags,
+                                  const ScDocument* pDoc,
+                                  const ScAddress::Details& rDetails)
 {
-    OUStringBuffer r;
     if( nFlags & SCA_VALID )
         nFlags |= ( SCA_VALID_ROW | SCA_VALID_COL | SCA_VALID_TAB );
     if( pDoc && (nFlags & SCA_VALID_TAB ) )
     {
         if ( nTab >= pDoc->GetTableCount() )
         {
-            return ScGlobal::GetRscString( STR_NOREF_STR );
+            lcl_string_append(r, ScGlobal::GetRscString( STR_NOREF_STR ));
+            return;
         }
         if( nFlags & SCA_TAB_3D )
         {
@@ -1786,10 +1829,10 @@ OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
             {
             default :
             case formula::FormulaGrammar::CONV_OOO:
-                r.append(aDocName);
+                lcl_string_append(r, aDocName);
                 if( nFlags & SCA_TAB_ABSOLUTE )
                     r.append("$");
-                r.append(aTabName);
+                lcl_string_append(r, aTabName);
                 r.append(".");
                 break;
 
@@ -1798,9 +1841,10 @@ OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
             case formula::FormulaGrammar::CONV_XL_OOX:
                 if (!aDocName.isEmpty())
                 {
-                    r.append("[").append(aDocName).append("]");
+                    lcl_string_append(r.append("["), aDocName);
+                    r.append("]");
                 }
-                r.append(aTabName);
+                lcl_string_append(r, aTabName);
                 r.append("!");
                 break;
             }
@@ -1825,6 +1869,20 @@ OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
             lcl_r1c1_append_c ( r, nCol, (nFlags & SCA_COL_ABSOLUTE) != 0, rDetails );
         break;
     }
+}
+
+void ScAddress::Format( OStringBuffer& r, sal_uInt16 nFlags,
+                                  const ScDocument* pDoc,
+                                  const Details& rDetails) const
+{
+    lcl_Format(r, nTab, nRow, nCol, nFlags, pDoc, rDetails);
+}
+
+OUString ScAddress::Format(sal_uInt16 nFlags, const ScDocument* pDoc,
+                           const Details& rDetails) const
+{
+    OUStringBuffer r;
+    lcl_Format(r, nTab, nRow, nCol, nFlags, pDoc, rDetails);
     return r.makeStringAndClear();
 }
 
@@ -2030,7 +2088,7 @@ OUString ScAddress::GetColRowString( bool bAbsolute,
     if (bAbsolute)
         aString.append("$");
 
-    ScColToAlpha( aString, nCol);
+    lcl_ScColToAlpha( aString, nCol);
 
     if ( bAbsolute )
         aString.append("$");
@@ -2070,38 +2128,6 @@ OUString ScRefAddress::GetRefString( ScDocument* pDoc, SCTAB nActTab,
     return aAdr.Format(nFlags, pDoc, rDetails);
 }
 
-void ScColToAlpha( OUStringBuffer& rBuf, SCCOL nCol )
-{
-    if (nCol < 26*26)
-    {
-        if (nCol < 26)
-            rBuf.append( static_cast<sal_Unicode>( 'A' +
-                        static_cast<sal_uInt16>(nCol)));
-        else
-        {
-            rBuf.append( static_cast<sal_Unicode>( 'A' +
-                        (static_cast<sal_uInt16>(nCol) / 26) - 1));
-            rBuf.append( static_cast<sal_Unicode>( 'A' +
-                        (static_cast<sal_uInt16>(nCol) % 26)));
-        }
-    }
-    else
-    {
-        OUString aStr;
-        while (nCol >= 26)
-        {
-            SCCOL nC = nCol % 26;
-            aStr += OUString( static_cast<sal_Unicode>( 'A' +
-                    static_cast<sal_uInt16>(nC)));
-            nCol = sal::static_int_cast<SCCOL>( nCol - nC );
-            nCol = nCol / 26 - 1;
-        }
-        aStr += OUString(static_cast<sal_Unicode>( 'A' +
-                static_cast<sal_uInt16>(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..96f5085 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();
 }
 
 XclExpRootData::~XclExpRootData()
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index e5ff50c..48153eb 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -718,10 +718,10 @@ OString XclXmlUtils::ToOString( const OUString& s )
     return OUStringToOString( s, RTL_TEXTENCODING_UTF8  );
 }
 
-OString XclXmlUtils::ToOString( const ScAddress& rAddress )
+OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const ScAddress& rAddress )
 {
-    OUString sAddress(rAddress.Format(SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1)));
-    return ToOString( sAddress );
+    rAddress.Format(s, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1));
+    return s;
 }
 
 OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
@@ -760,9 +760,9 @@ static ScAddress lcl_ToAddress( const XclAddress& rAddress )
     return aAddress;
 }
 
-OString XclXmlUtils::ToOString( const XclAddress& rAddress )
+OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const XclAddress& rAddress )
 {
-    return ToOString( lcl_ToAddress( rAddress ) );
+    return ToOString( s, lcl_ToAddress( rAddress ));
 }
 
 OString XclXmlUtils::ToOString( const XclExpString& s )
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 23adf6e..53a3c86 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -632,7 +632,7 @@ void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      "n",
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -663,7 +663,7 @@ void XclExpBooleanCell::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      "b",
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -766,7 +766,7 @@ void XclExpLabelCell::SaveXml( XclExpXmlStream& rStrm )
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      "s",
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -923,11 +923,10 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
 {
     const char* sType = NULL;
     OUString    sValue;
-
     XclXmlUtils::GetFormulaTypeAndValue( mrScFmlaCell, sType, sValue );
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), GetXclPos() ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
             XML_t,      sType,
             // OOXTODO: XML_cm, XML_vm, XML_ph
@@ -1277,7 +1276,7 @@ void XclExpBlankCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->singleElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( rAddress ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), rAddress ).getStr(),
             XML_s,      lcl_GetStyleId( rStrm, nXFId ).getStr(),
             FSEND );
 }
@@ -1309,7 +1308,7 @@ void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& r
 {
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     rWorksheet->startElement( XML_c,
-            XML_r,      XclXmlUtils::ToOString( rAddress ).getStr(),
+            XML_r,      XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), 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/excel/xeview.cxx b/sc/source/filter/excel/xeview.cxx
index 5e5ded5..3cea6ab 100644
--- a/sc/source/filter/excel/xeview.cxx
+++ b/sc/source/filter/excel/xeview.cxx
@@ -182,7 +182,7 @@ void XclExpPane::SaveXml( XclExpXmlStream& rStrm )
     rStrm.GetCurrentStream()->singleElement( XML_pane,
             XML_xSplit,         OString::number( mnSplitX ).getStr(),
             XML_ySplit,         OString::number( mnSplitY ).getStr(),
-            XML_topLeftCell,    XclXmlUtils::ToOString( maSecondXclPos ).getStr(),
+            XML_topLeftCell,    XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), maSecondXclPos ).getStr(),
             XML_activePane,     lcl_GetActivePane( mnActivePane ),
             XML_state,          mbFrozenPanes ? "frozen" : "split",
             FSEND );
@@ -225,7 +225,7 @@ void XclExpSelection::SaveXml( XclExpXmlStream& rStrm )
 {
     rStrm.GetCurrentStream()->singleElement( XML_selection,
             XML_pane,           lcl_GetActivePane( mnPane ),
-            XML_activeCell,     XclXmlUtils::ToOString( maSelData.maXclCursor ).getStr(),
+            XML_activeCell,     XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), maSelData.maXclCursor ).getStr(),
             XML_activeCellId,   OString::number(  maSelData.mnCursorIdx ).getStr(),
             XML_sqref,          XclXmlUtils::ToOString( maSelData.maXclSelection ).getStr(),
             FSEND );
@@ -426,7 +426,7 @@ void XclExpTabViewSettings::SaveXml( XclExpXmlStream& rStrm )
             XML_defaultGridColor,           mnGridColorId == XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT ) ? "true" : "false",
             // OOXTODO: XML_showWhiteSpace,
             XML_view,                       maData.mbPageMode ? "pageBreakPreview" : "normal",  // OOXTODO: pageLayout
-            XML_topLeftCell,                XclXmlUtils::ToOString( maData.maFirstXclPos ).getStr(),
+            XML_topLeftCell,                XclXmlUtils::ToOString( rStrm.GetRoot().GetStringBuf(), maData.maFirstXclPos ).getStr(),
             XML_colorId,                    OString::number(  rStrm.GetRoot().GetPalette().GetColorIndex( mnGridColorId ) ).getStr(),
             XML_zoomScale,                  lcl_GetZoom( maData.mnCurrentZoom ).getStr(),
             XML_zoomScaleNormal,            lcl_GetZoom( maData.mnNormalZoom ).getStr(),
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..5bb2b20 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,10 +267,10 @@ public:
     static OString ToOString( const Color& rColor );
     static OString ToOString( const OUString& s );
     static OString ToOString( const ScfUInt16Vec& rBuffer );
-    static OString ToOString( const ScAddress& rRange );
+    static OStringBuffer& ToOString( OStringBuffer& s, const ScAddress& rRange );
     static OString ToOString( const ScRange& rRange );
     static OString ToOString( const ScRangeList& rRangeList );
-    static OString ToOString( const XclAddress& rAddress );
+    static OStringBuffer& ToOString( OStringBuffer& s, const XclAddress& rAddress );
     static OString ToOString( const XclExpString& s );
     static OString ToOString( const XclRange& rRange );
     static OString ToOString( const XclRangeList& rRangeList );


More information about the Libreoffice-commits mailing list