[Libreoffice-commits] core.git: Branch 'feature/chart-opengl2' - sc/source

Michael Meeks michael.meeks at collabora.com
Wed Jan 1 06:07:15 PST 2014


 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 6204b78822ffcb1c2fd2a769bf52d7c10604af10
Author: Michael Meeks <michael.meeks at 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 cb3d683..f4847cf 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"
@@ -299,7 +300,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 */ );
 
@@ -459,6 +460,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();


More information about the Libreoffice-commits mailing list