fpspreadsheet: Fix reading of all BIFF formula attributes, also for BIFF2.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6581 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-08-10 09:41:18 +00:00
parent 7f09efa7de
commit e908d9ba3b
2 changed files with 39 additions and 24 deletions

View File

@@ -67,7 +67,7 @@ type
procedure ReadPROTECT(AStream: TStream);
procedure ReadRowColXF(AStream: TStream; out ARow, ACol: Cardinal; out AXF: Word); override;
procedure ReadRowInfo(AStream: TStream); override;
function ReadRPNAttr(AStream: TStream; AIdentifier: Byte): Boolean; override;
procedure ReadRPNAttr(AStream: TStream; AIdentifier: Byte); override;
function ReadRPNFunc(AStream: TStream): Word; override;
procedure ReadRPNSharedFormulaBase(AStream: TStream; out ARow, ACol: Cardinal); override;
function ReadRPNTokenArraySize(AStream: TStream): Word; override;
@@ -998,15 +998,27 @@ begin
lRow^.FormatIndex := XFToFormatIndex(xf);
end;
function TsSpreadBIFF2Reader.ReadRPNAttr(AStream: TStream; AIdentifier: Byte): Boolean;
{ ------------------------------------------------------------------------------
Reads the RPN attribute. Most attributes are not handled, but the
data associated with it must be read to keep the stream in sync with the
data structure.
This version of the method is valid for BIFF2 only.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF2Reader.ReadRPNAttr(AStream: TStream; AIdentifier: Byte);
var
nc: Byte;
begin
Result := false;
case AIdentifier of
$01: AStream.ReadByte; // tAttrVolatile, data not used
$10: AStream.ReadByte; // tAttrSum, data not used
else exit; // others not supported by fpspreadsheet --> Result = false
$02: AStream.ReadByte; // tAttrIF, not explicitely used
$04: begin // tAttrChoose, not supported
nc := AStream.ReadByte;
AStream.Position := AStream.Position + 2*nc + 1;
end;
$08: AStream.ReadByte; // tAttrSkip, data not used
$10: AStream.ReadByte; // tAttrSum, to be processed by ReadRPNTokenArray, byte not used
$20: AStream.ReadByte; // tAttrAssign, not used
end;
Result := true;
end;
{@@ ----------------------------------------------------------------------------

View File

@@ -514,7 +514,7 @@ type
procedure ReadRowColXF(AStream: TStream; out ARow, ACol: Cardinal; out AXF: Word); virtual;
// Read row info
procedure ReadRowInfo(AStream: TStream); virtual;
function ReadRPNAttr(AStream: TStream; AIdentifier: Byte): boolean; virtual;
procedure ReadRPNAttr(AStream: TStream; AIdentifier: Byte); virtual;
// Read the array of RPN tokens of a formula
procedure ReadRPNCellAddress(AStream: TStream; out ARow, ACol: Cardinal;
out AFlags: TsRelFlags); virtual;
@@ -2522,22 +2522,28 @@ end;
{@@ ----------------------------------------------------------------------------
Reads the special attribute of an RPN formula element.
Attributes are ignored by fpspreadsheet.
Attributes are usually ignored by fpspreadsheet; this method reads the
associated data which is needed to keep the stream in sync with the data
structure.
Structure is value for BIFF3 - BIFF8. Must be overridden for BIFF2.
Returns false if the structure is too complex for fps.
-------------------------------------------------------------------------------}
function TsSpreadBIFFReader.ReadRPNAttr(AStream: TStream; AIdentifier: Byte): Boolean;
procedure TsSpreadBIFFReader.ReadRPNAttr(AStream: TStream; AIdentifier: Byte);
var
nc: Integer;
begin
Result := false;
case AIdentifier of
$01: AStream.ReadWord; // tAttrVolatile token, data not used
$02: AStream.ReadWord; // tAttrIf token, data not used
$08: AStream.ReadWord; // tAttrSkip token, data not used
$40: AStream.ReadWord; // tAttrSum token, data not used
$49: AStream.ReadWord; // tAttrSpace, data not used
else exit; // others not supported by fps --> Result = false
$01: AStream.ReadWord; // tAttrVolatile token, skip
$02: AStream.ReadWord; // tAttrIf token, supported, but data seem to be redundant
$04: begin // tAttrChoose, skip
nc := WordLEToN(AStream.ReadWord);
AStream.Position := AStream.Position + 2*nc + 2;
end;
$08: AStream.ReadWord; // tAttrSkip token, skip
$10: AStream.ReadWord; // tAttrSUM, will be processed by ReadRPNTokenArray, data not used
$20: AStream.ReadWord; // tAttrAssign token, skip
$40: AStream.ReadWord; // tAttrSpace token, skip
$41: AStream.ReadWord; // tAttrSpaceVolatile, skip
end;
Result := true;
end;
{@@ ----------------------------------------------------------------------------
@@ -2943,12 +2949,9 @@ begin
INT_EXCEL_TOKEN_TATTR:
begin
b := AStream.ReadByte;
supported := ReadRPNAttr(AStream, b);
if supported then begin
case b of
$02: ; // IF parameter tag
$10: rpnItem := RPNFunc('SUM', 1, rpnItem); // one-parameter SUM
end;
ReadRPNAttr(AStream, b);
case b of
$10: rpnItem := RPNFunc('SUM', 1, rpnItem); // one-parameter SUM
end;
end;
INT_EXCEL_TOKEN_TREFV: