summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-16 16:50:35 +0100
committerDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-16 16:50:35 +0100
commitdddebac86dd6b1608bb59479e672c69ef3a48e0e (patch)
tree1e13334be2e84dfbaf10623d48c7178ed60139fd
parent340bea2639e78081b9115a6077ea9d269061d983 (diff)
dr78: #i109800# SHEET record may not point to BOF but to any record in the sheet substream (but now with reading that record too)
-rw-r--r--sc/source/filter/excel/read.cxx99
-rw-r--r--sc/source/filter/excel/xiescher.cxx40
-rw-r--r--sc/source/filter/excel/xistream.cxx6
-rw-r--r--sc/source/filter/inc/xistream.hxx11
4 files changed, 93 insertions, 63 deletions
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 67f0965b1..67db61103 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -836,11 +836,56 @@ FltError ImportExcel8::Read( void )
if( eAkt == EXC_STATE_BEFORE_SHEET )
{
sal_uInt16 nScTab = GetCurrScTab();
- if( nScTab < maSheetOffsets.size() )
+ if( nScTab < maSheetOffsets.size() )
{
- nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
+ nProgressBaseSize += (maStrm.GetSvStreamPos() - nProgressBasePos);
nProgressBasePos = maSheetOffsets[ nScTab ];
- aIn.StartNextRecord( nProgressBasePos );
+ maStrm.StartNextRecord( nProgressBasePos );
+
+ // #94191# import only 256 sheets
+ if( nScTab > GetScMaxPos().Tab() )
+ {
+ if( maStrm.GetRecId() != EXC_ID_EOF )
+ XclTools::SkipSubStream( maStrm );
+ // #i29930# show warning box
+ GetAddressConverter().CheckScTab( nScTab, true );
+ eAkt = EXC_STATE_END;
+ }
+ else
+ {
+ // #i109800# SHEET record may point to any record inside the sheet substream
+ bool bIsBof = maStrm.GetRecId() == EXC_ID5_BOF;
+ if( bIsBof )
+ Bof5(); // read the BOF record
+ else
+ pExcRoot->eDateiTyp = Biff8; // on missing BOF, assume a standard worksheet
+
+ NeueTabelle();
+ switch( pExcRoot->eDateiTyp )
+ {
+ case Biff8: // worksheet
+ case Biff8M4: // macro sheet
+ eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
+ // go to next record
+ if( bIsBof ) maStrm.StartNextRecord();
+ maStrm.StoreGlobalPosition();
+ break;
+ case Biff8C: // chart sheet
+ GetCurrSheetDrawing().ReadTabChart( maStrm );
+ Eof();
+ GetTracer().TraceChartOnlySheet();
+ break;
+ case Biff8W: // workbook
+ DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" );
+ // run through
+ case Biff8V: // VB module
+ default:
+ // TODO: do not create a sheet in the Calc document
+ pD->SetVisible( GetCurrScTab(), FALSE );
+ XclTools::SkipSubStream( maStrm );
+ IncCurrScTab();
+ }
+ }
}
else
eAkt = EXC_STATE_END;
@@ -1018,54 +1063,6 @@ FltError ImportExcel8::Read( void )
break;
// ----------------------------------------------------------------
- // before worksheet: expecting worksheet BOF
- case EXC_STATE_BEFORE_SHEET:
- {
- // #94191# import only 256 sheets
- if( GetCurrScTab() > GetScMaxPos().Tab() )
- {
- if( nRecId != EXC_ID_EOF )
- XclTools::SkipSubStream( maStrm );
- // #i29930# show warning box
- GetAddressConverter().CheckScTab( GetCurrScTab(), true );
- eAkt = EXC_STATE_END;
- }
- else
- {
- /* #i109800# SHEET record may point to any record inside the
- sheet substream. We will assume a standard worksheet. */
- if( nRecId == EXC_ID5_BOF )
- Bof5();
- else
- pExcRoot->eDateiTyp = Biff8;
- NeueTabelle();
- switch( pExcRoot->eDateiTyp )
- {
- case Biff8: // worksheet
- case Biff8M4: // macro sheet
- eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch
- aIn.StoreGlobalPosition();
- break;
- case Biff8C: // chart sheet
- GetCurrSheetDrawing().ReadTabChart( maStrm );
- Eof();
- GetTracer().TraceChartOnlySheet();
- break;
- case Biff8W: // workbook
- DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" );
- // run through
- case Biff8V: // VB module
- default:
- // TODO: do not create a sheet in the Calc document
- pD->SetVisible( GetCurrScTab(), FALSE );
- XclTools::SkipSubStream( maStrm );
- IncCurrScTab();
- }
- }
- }
- break;
-
- // ----------------------------------------------------------------
// prefetch for worksheet
case EXC_STATE_SHEET_PRE:
{
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index c4a7715d0..c1ee4df43 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -1540,23 +1540,39 @@ XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) :
void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm )
{
- if( mbOwnTab ? (rStrm.GetRecId() == EXC_ID5_BOF) : ((rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord()) )
+ /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record
+ has already been read. If chart is embedded as object, the next record
+ has to be the BOF record. */
+ if( mbOwnTab )
{
- sal_uInt16 nBofType;
- rStrm.Seek( 2 );
- rStrm >> nBofType;
- DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
-
- // read chart, even if BOF record contains wrong substream identifier
- mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) );
- mxChart->ReadChartSubStream( rStrm );
- if( mbOwnTab )
- FinalizeTabChart();
+ /* #i109800# The input stream may point somewhere inside the chart
+ substream and not exactly to the leading BOF record. To read this
+ record correctly in the following, the stream has to rewind it, so
+ that the next call to StartNextRecord() will find it correctly. */
+ if( rStrm.GetRecId() != EXC_ID5_BOF )
+ rStrm.RewindRecord();
}
else
{
- DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
+ if( (rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord() )
+ {
+ sal_uInt16 nBofType;
+ rStrm.Seek( 2 );
+ rStrm >> nBofType;
+ DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
+ }
+ else
+ {
+ DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
+ return;
+ }
}
+
+ // read chart, even if BOF record contains wrong substream identifier
+ mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) );
+ mxChart->ReadChartSubStream( rStrm );
+ if( mbOwnTab )
+ FinalizeTabChart();
}
void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
index 84f28383e..cd20f26e3 100644
--- a/sc/source/filter/excel/xistream.cxx
+++ b/sc/source/filter/excel/xistream.cxx
@@ -431,6 +431,12 @@ void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
}
}
+void XclImpStream::RewindRecord()
+{
+ mnNextRecPos = maFirstRec.GetPos();
+ mbValid = mbValidRec = false;
+}
+
void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter )
{
mxDecrypter = xDecrypter;
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
index de4e86bf0..65d0e58c1 100644
--- a/sc/source/filter/inc/xistream.hxx
+++ b/sc/source/filter/inc/xistream.hxx
@@ -182,6 +182,9 @@ public:
sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
bool& rbValid ) const;
+ /** Returns the stored stream position. */
+ inline sal_Size GetPos() const { return mnPos; }
+
private:
sal_Size mnPos; /// Absolute position of the stream.
sal_Size mnNextPos; /// Absolute position of next record.
@@ -280,6 +283,14 @@ public:
started with StartNextRecord(). */
void ResetRecord( bool bContLookup,
sal_uInt16 nAltContId = EXC_ID_UNKNOWN );
+ /** Sets stream pointer before current record and invalidates stream.
+ @descr The next call to StartNextRecord() will start again the current
+ record. This can be used in situations where a loop or a function
+ leaves on a specific record, but the parent context expects to start
+ this record by itself. The stream is invalid as long as the first
+ record has not been started (it is not allowed to call any other stream
+ operation then). */
+ void RewindRecord();
/** Enables decryption of record contents for the rest of the stream. */
void SetDecrypter( XclImpDecrypterRef xDecrypter );