fpspreadsheet: Improved file format detection

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3905 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-01-29 11:01:49 +00:00
parent 8f3d5d471f
commit 9ff9bc15b5
2 changed files with 36 additions and 41 deletions

View File

@ -964,7 +964,7 @@ implementation
uses uses
Math, StrUtils, TypInfo, lazutf8, Math, StrUtils, TypInfo, lazutf8,
fpsPatches, fpsStrings, fpsStreams, fpsPatches, fpsStrings, fpsStreams, uvirtuallayer_ole,
fpsUtils, fpsCurrency, fpsNumFormatParser, fpsExprParser; fpsUtils, fpsCurrency, fpsNumFormatParser, fpsExprParser;
const const
@ -6434,18 +6434,27 @@ const
$09,$00, $04,$00, $00,$00, $10,$00, $31,$00, $0A,$00, $C8,$00, $00,$00); $09,$00, $04,$00, $00,$00, $10,$00, $31,$00, $0A,$00, $C8,$00, $00,$00);
BIFF58_HEADER: array[0..7] of byte = ( BIFF58_HEADER: array[0..7] of byte = (
$D0,$CF, $11,$E0, $A1,$B1, $1A,$E1); $D0,$CF, $11,$E0, $A1,$B1, $1A,$E1);
BIFF5_MARKER: array[0..7] of widechar = (
'B', 'o', 'o', 'k', #0, #0, #0, #0); function ValidOLEStream(AStream: TStream; AName: String): Boolean;
BIFF8_MARKER:array[0..7] of widechar = ( var
'W', 'o', 'r', 'k', 'b', 'o', 'o', 'k'); fsOLE: TVirtualLayer_OLE;
begin
AStream.Position := 0;
fsOLE := TVirtualLayer_OLE.Create(AStream);
try
fsOLE.Initialize;
Result := fsOLE.FileExists('/'+AName);
finally
fsOLE.Free;
end;
end;
var var
buf: packed array[0..16] of byte; buf: packed array[0..16] of byte = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
stream: TStream; stream: TStream;
i: Integer; i: Integer;
ok: Boolean; ok: Boolean;
begin begin
buf[0] := 0; // Silence the compiler...
Result := false; Result := false;
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone); stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
try try
@ -6471,28 +6480,20 @@ begin
if buf[i] <> BIFF58_HEADER[i] then if buf[i] <> BIFF58_HEADER[i] then
exit; exit;
// Further information begins at offset $480: // Now we know that the file is a Microsoft compound document.
stream.Position := $480;
stream.ReadBuffer(buf, 16); // We check for Excel 5 in which the stream is named "Book"
// Check for Excel5 if ValidOLEStream(stream, 'Book') then begin
ok := true;
for i:=0 to 7 do
if WideChar(buf[i*2]) <> BIFF5_MARKER[i] then
begin
ok := false;
break;
end;
if ok then
begin
SheetType := sfExcel5; SheetType := sfExcel5;
Exit(True); exit(True);
end; end;
// Check for Excel8
for i:=0 to 7 do // Now we check for Excel 8 which names the stream "Workbook"
if WideChar(buf[i*2]) <> BIFF8_MARKER[i] then if ValidOLEStream(stream, 'Workbook') then begin
exit(false); SheetType := sfExcel8;
SheetType := sfExcel8; exit(True);
Exit(True); end;
finally finally
stream.Free; stream.Free;
end; end;
@ -8447,17 +8448,10 @@ procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook
var var
InputFile: TStream; InputFile: TStream;
begin begin
if (boBufStream in Workbook.Options) then if (boBufStream in Workbook.Options) then
InputFile := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyNone) InputFile := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyNone)
else else
InputFile := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone); InputFile := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
{
//<--
InputFile := TMemoryStream.Create;
TMemoryStream(InputFile).LoadFromFile(AFilename);
//--->
}
try try
ReadFromStream(InputFile, AData); ReadFromStream(InputFile, AData);

View File

@ -27,6 +27,7 @@ type
function FindMounted(const APath: UTF8String): TVirtualLayer; overload; function FindMounted(const APath: UTF8String): TVirtualLayer; overload;
function PreviousPath(const APath: UTF8String): UTF8String; function PreviousPath(const APath: UTF8String): UTF8String;
function StripMountPoints(const APath: UTF8String): UTF8String; function StripMountPoints(const APath: UTF8String): UTF8String;
protected protected
FParentLayer: TVirtualLayer; FParentLayer: TVirtualLayer;
FVirtualLayerStream: TStream; FVirtualLayerStream: TStream;
@ -59,8 +60,8 @@ type
procedure Lock(); virtual; procedure Lock(); virtual;
procedure Unlock(); virtual; procedure Unlock(); virtual;
public
public
function MakeFolder(const AFolder: UTF8String): Boolean; function MakeFolder(const AFolder: UTF8String): Boolean;
function RemoveFolder(const AFolder: UTF8String): Boolean; function RemoveFolder(const AFolder: UTF8String): Boolean;
function DeleteFile(const AFileName: UTF8String): Boolean; function DeleteFile(const AFileName: UTF8String): Boolean;
@ -100,11 +101,11 @@ type
implementation implementation
type type
TFileRecLocal=record TFileRecLocal = record
FL: TVirtualLayer_FolderList; FL: TVirtualLayer_FolderList;
Attr: LongInt; Attr: LongInt;
end; end;
PFileRecLocal=^TFileRecLocal; PFileRecLocal=^TFileRecLocal;
{ TVirtualLayer } { TVirtualLayer }