summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <laszlo.nemeth@collabora.com>2015-01-27 09:17:50 +0100
committerLászló Németh <laszlo.nemeth@collabora.com>2015-01-27 09:20:14 +0100
commit779581feed4886313746a71e9e738d736977be1b (patch)
tree9b630f18061d7b07cb743866dfd1eb5e2747ee7d
parent58a50c3dc74cc9bd298d6b4156e45a8dbbffc116 (diff)
tdf#88810 avoid unnecessary massive O(U)String allocations in XLSX export
Using OStringBuffer instead of fixed size character arrays. Change-Id: I06b705e2159a1ef5990f9eb0ffedd20fe277c616
-rw-r--r--sc/inc/address.hxx6
-rw-r--r--sc/source/core/tool/address.cxx62
-rw-r--r--sc/source/filter/excel/xeroot.cxx1
-rw-r--r--sc/source/filter/excel/xestream.cxx10
-rw-r--r--sc/source/filter/excel/xetable.cxx10
-rw-r--r--sc/source/filter/inc/xeroot.hxx5
-rw-r--r--sc/source/filter/inc/xestream.hxx3
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 );