summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <laszlo.nemeth@collabora.com>2015-02-02 08:52:53 +0100
committerMichael Meeks <michael.meeks@collabora.com>2015-02-02 21:18:49 +0100
commit86df2b436d387ff1282089267e1837f17aff5cda (patch)
treee3b911769664b6293823efb4fc77835e676333c3
parentaafb2fd9c7580a0de98f2d60657576c62175a5ee (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.hxx5
-rw-r--r--sc/source/core/tool/address.cxx128
-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.cxx13
-rw-r--r--sc/source/filter/excel/xeview.cxx6
-rw-r--r--sc/source/filter/inc/xeroot.hxx5
-rw-r--r--sc/source/filter/inc/xestream.hxx5
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 );