sc/source/filter/inc/formulabuffer.hxx | 40 +++++++++++++---------- sc/source/filter/oox/formulabuffer.cxx | 51 +++++++++++++++--------------- sc/source/filter/oox/workbookfragment.cxx | 6 ++- 3 files changed, 55 insertions(+), 42 deletions(-)
New commits: commit d17a83fa549f828f29e6939b16ba8b568a75f95e Author: Michael Meeks <michael.me...@collabora.com> Date: Wed Jan 1 14:06:05 2014 +0000 oox: fix crash with threaded xlsx loading by pre-allocating sheet storage. Change-Id: I12c8afe6467bf3ae755faf8c6d01c6aa37d5be27 diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx index 2411466..6be0a25 100644 --- a/sc/source/filter/inc/formulabuffer.hxx +++ b/sc/source/filter/inc/formulabuffer.hxx @@ -91,21 +91,21 @@ public: }; private: - typedef ::std::map< SCTAB, std::vector<TokenAddressItem> > FormulaDataMap; - typedef ::std::map< SCTAB, std::vector<TokenRangeAddressItem> > ArrayFormulaDataMap; + // Vectors indexed by SCTAB - cf. SetSheetCount + typedef ::std::vector< std::vector<TokenAddressItem> > FormulaDataArray; + typedef ::std::vector< std::vector<TokenRangeAddressItem> > ArrayFormulaDataArray; // sheet -> list of shared formula descriptions - typedef ::std::map< SCTAB, std::vector<SharedFormulaDesc> > SheetToSharedFormulaid; + typedef ::std::vector< std::vector<SharedFormulaDesc> > SheetToSharedFormulaid; // sheet -> stuff needed to create shared formulae - typedef ::std::map< SCTAB, std::vector<SharedFormulaEntry> > SheetToFormulaEntryMap; - - typedef ::std::map< SCTAB, std::vector<ValueAddressPair> > FormulaValueMap; + typedef ::std::vector< std::vector<SharedFormulaEntry> > SheetToFormulaEntryArray; + typedef ::std::vector< std::vector<ValueAddressPair> > FormulaValueArray; osl::Mutex maMtxData; - FormulaDataMap maCellFormulas; - ArrayFormulaDataMap maCellArrayFormulas; - SheetToFormulaEntryMap maSharedFormulas; - SheetToSharedFormulaid maSharedFormulaIds; - FormulaValueMap maCellFormulaValues; + FormulaDataArray maCellFormulas; + ArrayFormulaDataArray maCellArrayFormulas; + SheetToFormulaEntryArray maSharedFormulas; + SheetToSharedFormulaid maSharedFormulaIds; + FormulaValueArray maCellFormulaValues; SheetItem getSheetItem( SCTAB nTab ); @@ -118,14 +118,20 @@ public: const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType ); - void setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue ); - void setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const OUString& ); - void createSharedFormulaMapEntry( - const com::sun::star::table::CellAddress& rAddress, - const com::sun::star::table::CellRangeAddress& rRange, - sal_Int32 nSharedId, const OUString& rTokens ); + void setCellFormulaValue( const ::css::table::CellAddress& rAddress, + double fValue ); + void setCellArrayFormula( const ::css::table::CellRangeAddress& rRangeAddress, + const ::css::table::CellAddress& rTokenAddress, + const OUString& ); + void createSharedFormulaMapEntry( const ::css::table::CellAddress& rAddress, + const ::css::table::CellRangeAddress& rRange, + sal_Int32 nSharedId, const OUString& rTokens ); + + /// ensure sizes of vectors matches the number of sheets + void SetSheetCount( SCTAB nSheets ); }; + }} #endif diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx index cb427f2..9f4404b 100644 --- a/sc/source/filter/oox/formulabuffer.cxx +++ b/sc/source/filter/oox/formulabuffer.cxx @@ -335,6 +335,15 @@ FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( { } +void FormulaBuffer::SetSheetCount( SCTAB nSheets ) +{ + maCellFormulas.resize( nSheets ); + maCellArrayFormulas.resize( nSheets ); + maSharedFormulas.resize( nSheets ); + maSharedFormulaIds.resize( nSheets ); + maCellFormulaValues.resize( nSheets ); +} + void FormulaBuffer::finalizeImport() { ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() ); @@ -401,35 +410,24 @@ FormulaBuffer::SheetItem FormulaBuffer::getSheetItem( SCTAB nTab ) osl::MutexGuard aGuard(&maMtxData); SheetItem aItem; - { - FormulaDataMap::iterator it = maCellFormulas.find(nTab); - if (it != maCellFormulas.end()) - aItem.mpCellFormulas = &it->second; - } - - { - ArrayFormulaDataMap::iterator it = maCellArrayFormulas.find(nTab); - if (it != maCellArrayFormulas.end()) - aItem.mpArrayFormulas = &it->second; - } + if( (size_t) nTab >= maCellFormulas.size() ) { - FormulaValueMap::iterator it = maCellFormulaValues.find(nTab); - if (it != maCellFormulaValues.end()) - aItem.mpCellFormulaValues = &it->second; + SAL_WARN( "sc", "Tab " << nTab << " out of bounds " << maCellFormulas.size() ); + return aItem; } - { - SheetToFormulaEntryMap::iterator it = maSharedFormulas.find(nTab); - if (it != maSharedFormulas.end()) - aItem.mpSharedFormulaEntries = &it->second; - } + if( maCellFormulas[ nTab ].size() > 0 ) + aItem.mpCellFormulas = &maCellFormulas[ nTab ]; + if( maCellArrayFormulas[ nTab ].size() > 0 ) + aItem.mpArrayFormulas = &maCellArrayFormulas[ nTab ]; + if( maCellFormulaValues[ nTab ].size() > 0 ) + aItem.mpCellFormulaValues = &maCellFormulaValues[ nTab ]; + if( maSharedFormulas[ nTab ].size() > 0 ) + aItem.mpSharedFormulaEntries = &maSharedFormulas[ nTab ]; + if( maSharedFormulaIds[ nTab ].size() > 0 ) + aItem.mpSharedFormulaIDs = &maSharedFormulaIds[ nTab ]; - { - SheetToSharedFormulaid::iterator it = maSharedFormulaIds.find(nTab); - if (it != maSharedFormulaIds.end()) - aItem.mpSharedFormulaIDs = &it->second; - } return aItem; } @@ -437,6 +435,7 @@ void FormulaBuffer::createSharedFormulaMapEntry( const table::CellAddress& rAddress, const table::CellRangeAddress& rRange, sal_Int32 nSharedId, const OUString& rTokens ) { + assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulas.size() ); std::vector<SharedFormulaEntry>& rSharedFormulas = maSharedFormulas[ rAddress.Sheet ]; SharedFormulaEntry aEntry(rAddress, rRange, rTokens, nSharedId); rSharedFormulas.push_back( aEntry ); @@ -444,12 +443,14 @@ void FormulaBuffer::createSharedFormulaMapEntry( void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const OUString& rTokenStr ) { + assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulas.size() ); maCellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) ); } void FormulaBuffer::setCellFormula( const table::CellAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType ) { + assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulaIds.size() ); maSharedFormulaIds[rAddress.Sheet].push_back( SharedFormulaDesc(rAddress, nSharedId, rCellValue, nValueType)); } @@ -458,11 +459,13 @@ void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRang { TokenAddressItem tokenPair( rTokenStr, rTokenAddress ); + assert( rRangeAddress.Sheet >= 0 && (size_t)rRangeAddress.Sheet < maCellArrayFormulas.size() ); maCellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) ); } void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue ) { + assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulaValues.size() ); maCellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) ); } diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index bfc5e7b..23c4552 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -32,6 +32,7 @@ #include "connectionsfragment.hxx" #include "externallinkbuffer.hxx" #include "externallinkfragment.hxx" +#include "formulabuffer.hxx" #include "pivotcachebuffer.hxx" #include "sharedstringsbuffer.hxx" #include "sharedstringsfragment.hxx" @@ -297,7 +298,7 @@ public: } }; -void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets ) +static void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets ) { sal_Int32 nThreads = std::min( rSheets.size(), (size_t) 4 /* FIXME: ncpus/2 */ ); @@ -455,6 +456,9 @@ void WorkbookFragment::finalizeImport() } } + // setup structure sizes for the number of sheets + getFormulaBuffer().SetSheetCount( aSheetFragments.size() ); + // create all defined names and database ranges getDefinedNames().finalizeImport(); getTables().finalizeImport(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits