diff options
author | László Németh <laszlo.nemeth@collabora.com> | 2015-01-26 15:45:05 +0100 |
---|---|---|
committer | László Németh <laszlo.nemeth@collabora.com> | 2015-01-26 15:54:01 +0100 |
commit | ace8f9c2a31795cc2329c6bb27deacde9f4c18df (patch) | |
tree | c7c30cb015863693e098be4ab56f25339beaebf6 /sc/source | |
parent | c221a1b93dd70a14b897c3a96b8e032cd97b9593 (diff) |
fdo#88810 avoid unnecessary massive O(U)String allocations in XLSX export
Change-Id: Ie6a024463e7ee9b0f4492b2431533708a578faf0
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/tool/address.cxx | 45 | ||||
-rw-r--r-- | sc/source/filter/excel/xestream.cxx | 10 | ||||
-rw-r--r-- | sc/source/filter/excel/xetable.cxx | 14 | ||||
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 2 |
4 files changed, 68 insertions, 3 deletions
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 1efcac723c3f..bb7a1bf4fc6d 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -1745,6 +1745,51 @@ 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(char * 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 : + // Note: length of s (defined by SIMPLEADDRESSLEN) supports the following simple addresses + case formula::FormulaGrammar::CONV_OOO: + case formula::FormulaGrammar::CONV_XL_A1: + case formula::FormulaGrammar::CONV_XL_OOX: + if (nCol >= 26 * 26) + // TODO: extend it for full column range + return false; + if( nCol < 26 ) + *s = 'A' + nCol; + else + { + *s = 'A' + nCol / 26 - 1; + s++; + *s = 'A' + nCol % 26; + } + sprintf(s + 1, "%d", 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 { diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx index e5ff50c431c7..188fcd668250 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::TryToChar( char * 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::TryToChar( sal_Char * s, const XclAddress& rAddress ) +{ + return TryToChar( 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 23adf6e3f0db..f32cdce88223 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -41,6 +41,11 @@ using namespace ::oox; namespace ApiScriptType = ::com::sun::star::i18n::ScriptType; +// max string length of simple addresses (eg. ABC1000000\0) +#if MAXROWCOUNT_DEFINE < 9999999 +#define SIMPLEADDRESSLEN 11 +#endif + // Helper records for cell records XclExpStringRec::XclExpStringRec( const XclExpRoot& rRoot, const OUString& rResult ) : @@ -630,9 +635,10 @@ static OString lcl_GetStyleId( XclExpXmlStream& rStrm, const XclExpCellBase& rCe void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm ) { + char fastAdr[SIMPLEADDRESSLEN]; sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); rWorksheet->startElement( XML_c, - XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(), + XML_r, XclXmlUtils::TryToChar( fastAdr, GetXclPos() ) ? fastAdr : XclXmlUtils::ToOString( GetXclPos() ).getStr(), XML_s, lcl_GetStyleId( rStrm, *this ).getStr(), XML_t, "n", // OOXTODO: XML_cm, XML_vm, XML_ph @@ -923,11 +929,12 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm ) { const char* sType = NULL; OUString sValue; + char fastAdr[SIMPLEADDRESSLEN]; XclXmlUtils::GetFormulaTypeAndValue( mrScFmlaCell, sType, sValue ); sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); rWorksheet->startElement( XML_c, - XML_r, XclXmlUtils::ToOString( GetXclPos() ).getStr(), + XML_r, XclXmlUtils::TryToChar( fastAdr, GetXclPos() ) ? fastAdr : XclXmlUtils::ToOString( GetXclPos() ).getStr(), XML_s, lcl_GetStyleId( rStrm, *this ).getStr(), XML_t, sType, // OOXTODO: XML_cm, XML_vm, XML_ph @@ -1307,9 +1314,10 @@ bool XclExpRkCell::TryMerge( const XclExpCellBase& rCell ) void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol ) { + char fastAdr[SIMPLEADDRESSLEN]; sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); rWorksheet->startElement( XML_c, - XML_r, XclXmlUtils::ToOString( rAddress ).getStr(), + XML_r, XclXmlUtils::TryToChar( fastAdr, rAddress ) ? fastAdr : 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/xestream.hxx b/sc/source/filter/inc/xestream.hxx index df1f7a30a17a..8454b2e2b2b8 100644 --- a/sc/source/filter/inc/xestream.hxx +++ b/sc/source/filter/inc/xestream.hxx @@ -266,9 +266,11 @@ public: static OString ToOString( const Color& rColor ); static OString ToOString( const OUString& s ); static OString ToOString( const ScfUInt16Vec& rBuffer ); + static bool TryToChar( char * s, const ScAddress& rRange ); static OString ToOString( const ScAddress& rRange ); static OString ToOString( const ScRange& rRange ); static OString ToOString( const ScRangeList& rRangeList ); + static bool TryToChar( char * s, const XclAddress& rAddress ); static OString ToOString( const XclAddress& rAddress ); static OString ToOString( const XclExpString& s ); static OString ToOString( const XclRange& rRange ); |