diff options
author | László Németh <laszlo.nemeth@collabora.com> | 2015-01-27 09:17:50 +0100 |
---|---|---|
committer | László Németh <laszlo.nemeth@collabora.com> | 2015-01-27 09:20:14 +0100 |
commit | 779581feed4886313746a71e9e738d736977be1b (patch) | |
tree | 9b630f18061d7b07cb743866dfd1eb5e2747ee7d /sc | |
parent | 58a50c3dc74cc9bd298d6b4156e45a8dbbffc116 (diff) |
tdf#88810 avoid unnecessary massive O(U)String allocations in XLSX export
Using OStringBuffer instead of fixed size character arrays.
Change-Id: I06b705e2159a1ef5990f9eb0ffedd20fe277c616
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/address.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/address.cxx | 62 | ||||
-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 | 10 | ||||
-rw-r--r-- | sc/source/filter/inc/xeroot.hxx | 5 | ||||
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 3 |
7 files changed, 93 insertions, 4 deletions
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx index 06c450b8eb27..a745c73ecfff 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 39fc9a4dd253..36cdb928fc3f 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 819fe93553db..29f655160771 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 e5ff50c431c7..04dbb5f0086a 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 70f3373771b4..5919c6145c01 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 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..0b10e4851a19 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 ); |