diff --git a/components/fpspreadsheet/examples/excel8demo/excel8write.lpr b/components/fpspreadsheet/examples/excel8demo/excel8write.lpr index a5ee50491..a1f212c5c 100644 --- a/components/fpspreadsheet/examples/excel8demo/excel8write.lpr +++ b/components/fpspreadsheet/examples/excel8demo/excel8write.lpr @@ -10,7 +10,7 @@ program excel8write; {$mode delphi}{$H+} uses - Classes, SysUtils, fpspreadsheet, fpsRPN, xlsbiff8, fpsTypes, fpsHelpers; + Classes, SysUtils, fpspreadsheet, fpsRPN, xlsbiff8, fpsTypes, fpsCell; const Str_First = 'First'; diff --git a/components/fpspreadsheet/examples/fpsspeedtest/fpsspeedtest.lpi b/components/fpspreadsheet/examples/fpsspeedtest/fpsspeedtest.lpi index c8699c9cf..100e21dc8 100644 --- a/components/fpspreadsheet/examples/fpsspeedtest/fpsspeedtest.lpi +++ b/components/fpspreadsheet/examples/fpsspeedtest/fpsspeedtest.lpi @@ -60,7 +60,6 @@ - diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 9af2d29bd..0ee00f9f9 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -8447,10 +8447,18 @@ procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook var InputFile: TStream; begin + if (boBufStream in Workbook.Options) then InputFile := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyNone) else InputFile := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone); + { + //<-- + InputFile := TMemoryStream.Create; + TMemoryStream(InputFile).LoadFromFile(AFilename); + //---> + } + try ReadFromStream(InputFile, AData); finally diff --git a/components/fpspreadsheet/fpsstreams.pas b/components/fpspreadsheet/fpsstreams.pas index c285aef73..8e25e4069 100644 --- a/components/fpspreadsheet/fpsstreams.pas +++ b/components/fpspreadsheet/fpsstreams.pas @@ -18,6 +18,8 @@ type private FFileStream: TFileStream; FMemoryStream: TMemoryStream; + FFileStreamPos: Int64; + FFileStreamSize: Int64; FBufWritten: Boolean; FBufSize: Int64; FKeepTmpFile: Boolean; @@ -144,10 +146,13 @@ begin if FFileStream = nil then begin if FFileName = '' then FFileName := ChangeFileExt(GetTempFileName, '.~abc'); FFileStream := TFileStream.Create(FFileName, FFileMode); + FFileStreamSize := FFileStream.Size; + FFileStreamPos := 0; end; end; -{ Reads FBufSize bytes from the stream into the buffer } +{ Reads FBufSize bytes from the stream into the buffer. + Called when reading. } procedure TBufStream.FillBuffer; var p, n: Int64; @@ -156,19 +161,23 @@ begin FMemoryStream.Clear; FMemoryStream.Position := 0; FFileStream.Position := p; - n := Min(FBufSize, FFileStream.Size - p); + n := Min(FBufSize, FFileStreamSize - p); FMemoryStream.CopyFrom(FFileStream, n); FMemoryStream.Position := 0; - FFileStream.Position := p; + FFileStream.Position := p; // The file stream ends where the memorystream begins! + FFileStreamPos := p; end; -{ Flushes the contents of the memory stream to file } +{ Flushes the contents of the memory stream to file + Called when writing. } procedure TBufStream.FlushBuffer; begin if (FMemoryStream.Size > 0) and not FBufWritten and IsWritingMode then begin FMemoryStream.Position := 0; CreateFileStream; FFileStream.CopyFrom(FMemoryStream, FMemoryStream.Size); + FFileStreamPos := FFileStream.Position; + FFileStreamSize := FFileStream.Size; FMemoryStream.Clear; FBufWritten := true; end; @@ -181,7 +190,8 @@ begin if FFileStream = nil then Result := FMemoryStream.Position else - Result := FFileStream.Position + FMemoryStream.Position; + // Result := FFileStream.Position + FMemoryStream.Position; + Result := FFileStreamPos + FMemoryStream.Position; end; { Returns the size of the stream. Both memory and file streams are considered @@ -192,14 +202,15 @@ var begin if IsWritingMode then begin if FFileStream <> nil then - n := FFileStream.Size + n := FFileStreamSize +// n := FFileStream.Size else n := 0; if n = 0 then n := FMemoryStream.Size; Result := Max(n, GetPosition); end else begin CreateFileStream; - Result := FFileStream.Size; + Result := FFileStreamSize; end; end; @@ -238,6 +249,7 @@ begin CreateFileStream; if IsWritingMode then begin Result := FFileStream.Read(Buffer, Count); + FFileStreamPos := FFileStream.Position; end else begin FillBuffer; Result := FMemoryStream.Read(Buffer, Count); @@ -256,6 +268,7 @@ begin FlushBuffer; FFileStream.Position := p; Result := FFileStream.Read(Buffer, Count); + FFileStreamPos := p + Count; end else begin FillBuffer; Result := FMemoryStream.Read(Buffer, Count); @@ -285,10 +298,12 @@ begin CreateFileStream; // case #2: New position is within buffer, file stream exists - if (newPos >= FFileStream.Position) and (newPos < FFileStream.Position + FMemoryStream.Size) +// if (newPos >= FFileStream.Position) and (newPos < FFileStream.Position + FMemoryStream.Size) + if (newPos >= FFileStreamPos) and (newPos < FFileStreamPos + FMemoryStream.Size) then begin - FMemoryStream.Position := newPos - FFileStream.Position; - Result := FMemoryStream.Position; + // FMemoryStream.Position := newPos - FFileStream.Position; + FMemoryStream.Position := newPos - FFileStreamPos; + Result := newpos; //FMemoryStream.Position; exit; end; @@ -296,6 +311,7 @@ begin if IsWritingMode then FlushBuffer; FFileStream.Position := newPos; + FFileStreamPos := newPos; FMemoryStream.Position := 0; if not IsWritingMode then FillBuffer; @@ -306,17 +322,20 @@ var savedPos: Int64; begin // Case #1: Bytes fit into buffer - if FMemoryStream.Position + ACount < FBufSize then begin + if FMemoryStream.Position + ACount < FBufSize then + begin Result := FMemoryStream.Write(ABuffer, ACount); FBufWritten := false; - exit; - end; - + end else // Case #2: Buffer would overflow - savedPos := GetPosition; - FlushBuffer; - FFileStream.Position := savedPos; - Result := FFileStream.Write(ABuffer, ACount); + begin; + savedPos := GetPosition; + FlushBuffer; + FFileStream.Position := savedPos; + Result := FFileStream.Write(ABuffer, ACount); + FFileStreamPos := savedPos + ACount; + FFileStreamSize := FFileStream.Size; + end; end; diff --git a/components/fpspreadsheet/tests/spreadtestgui.lpi b/components/fpspreadsheet/tests/spreadtestgui.lpi index a992ec463..a33d91a06 100644 --- a/components/fpspreadsheet/tests/spreadtestgui.lpi +++ b/components/fpspreadsheet/tests/spreadtestgui.lpi @@ -69,6 +69,7 @@ +