diff options
author | László Németh <laszlo.nemeth@collabora.com> | 2015-02-02 08:52:53 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-02-02 21:18:49 +0100 |
commit | 86df2b436d387ff1282089267e1837f17aff5cda (patch) | |
tree | e3b911769664b6293823efb4fc77835e676333c3 | |
parent | aafb2fd9c7580a0de98f2d60657576c62175a5ee (diff) |
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@collabora.com>
-rw-r--r-- | sc/inc/address.hxx | 5 | ||||
-rw-r--r-- | sc/source/core/tool/address.cxx | 128 | ||||
-rw-r--r-- | sc/source/filter/excel/xeroot.cxx | 1 | ||||
-rw-r--r-- | sc/source/filter/excel/xestream.cxx | 10 | ||||
-rw-r--r-- | sc/source/filter/excel/xetable.cxx | 13 | ||||
-rw-r--r-- | sc/source/filter/excel/xeview.cxx | 6 | ||||
-rw-r--r-- | sc/source/filter/inc/xeroot.hxx | 5 | ||||
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 5 |
8 files changed, 105 insertions, 68 deletions
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx index 06c450b8eb27..6bf55340f563 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 1efcac723c3f..06e49b78dc34 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 819fe93553db..96f508555503 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 e5ff50c431c7..48153ebe41e5 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 23adf6e3f0db..53a3c860dc5a 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 5e5ded5cb3f7..3cea6ab5e64b 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 698b0e4a49f6..2272134933d6 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 df1f7a30a17a..5bb2b204ed9d 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 ); |