TParadoxDataset: Fix several crashes and differences in presentation relative to pxlib.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6897 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2019-05-08 20:18:48 +00:00
parent 9a2aca4fed
commit 60842879dd

View File

@@ -154,6 +154,7 @@ type
FBlockReaded: Boolean; FBlockReaded: Boolean;
FBookmarkOfs: LongWord; FBookmarkOfs: LongWord;
FFieldInfoPtr: PFldInfoRec; FFieldInfoPtr: PFldInfoRec;
FTableNameLen: Integer;
procedure SetFileName(const AValue: TFileName); procedure SetFileName(const AValue: TFileName);
function GetEncrypted: Boolean; function GetEncrypted: Boolean;
@@ -304,19 +305,35 @@ begin
end; end;
procedure TParadoxDataSet.InternalOpen; procedure TParadoxDataSet.InternalOpen;
var
hdrSize: Word;
begin begin
FStream := TFileStream.Create(FFilename,fmOpenRead or fmShareDenyNone); FStream := TFileStream.Create(FFilename,fmOpenRead or fmShareDenyNone);
FHeader := AllocMem($800); FStream.Position := 2;
hdrSize := FStream.ReadWord;
FHeader := AllocMem(hdrSize);
FStream.Position := 0; FStream.Position := 0;
if not FStream.Read(FHeader^, $800) = sizeof(FHeader^) then if not FStream.Read(FHeader^, hdrSize) = hdrSize then
DatabaseError('No valid Paradox file !'); DatabaseError('No valid Paradox file !');
{
if not ((FHeader^.maxTableSize >= 1) and (FHeader^.maxTableSize <= 4)) then if not ((FHeader^.maxTableSize >= 1) and (FHeader^.maxTableSize <= 4)) then
DatabaseError('No valid Paradox file !'); DatabaseError('No valid Paradox file !');
}
if not ((FHeader^.maxTableSize >= 1) and (FHeader^.maxTableSize <= 32)) then
DatabaseError('No valid Paradox file !');
if (FHeader^.fileVersionID = 12) then
FTableNameLen := 261
else
FTableNameLen := 79;
if (FHeader^.fileVersionID <= 4) or not (FHeader^.FileType in [0,2,3,5]) then if (FHeader^.fileVersionID <= 4) or not (FHeader^.FileType in [0,2,3,5]) then
FFieldInfoPtr := @FHeader^.FieldInfo35 FFieldInfoPtr := @FHeader^.FieldInfo35
else else
FFieldInfoPtr := @FHeader^.FieldInfo; FFieldInfoPtr := @FHeader^.FieldInfo;
if Encrypted then exit; if Encrypted then exit;
FaBlock := AllocMem(FHeader^.maxTableSize * $0400); FaBlock := AllocMem(FHeader^.maxTableSize * $0400);
BookmarkSize := SizeOf(longword); BookmarkSize := SizeOf(longword);
InternalFirst; InternalFirst;
@@ -347,33 +364,31 @@ begin
FieldDefs.Clear; FieldDefs.Clear;
F := FFieldInfoPtr; { begin with the first field identifier } F := FFieldInfoPtr; { begin with the first field identifier }
FNamesStart := Pointer(F); FNamesStart := Pointer(F);
inc(FNamesStart, sizeof(F^)*(FHeader^.numFields)); //Jump over Fielddefs inc(FNamesStart, SizeOf(F^)*(FHeader^.numFields)); //Jump over Fielddefs
inc(FNamesStart, sizeof(LongInt)); //over TableName pointer inc(FNamesStart, SizeOf(LongInt)); //over TableName pointer
inc(FNamesStart, sizeof(LongInt)*(FHeader^.numFields)); //over FieldName pointers inc(FNamesStart, SizeOf(LongInt)*(FHeader^.numFields)); //over FieldName pointers
inc(FNamesStart, Strlen(FNamesStart)+1); //over Tablename inc(FNamesStart, FTableNameLen); // over Tablename and padding
while FNamesStart^ = char(0) do
inc(FNamesStart); //over Padding
for i := 1 to FHeader^.NumFields do for i := 1 to FHeader^.NumFields do
begin begin
fname := StrPas(FNamesStart); fname := StrPas(FNamesStart);
case F^.fType of case F^.fType of
pxfAlpha: Fielddefs.Add(fname, ftString, F^.fSize); pxfAlpha: FieldDefs.Add(fname, ftString, F^.fSize);
pxfDate: Fielddefs.Add(fname, ftDate, 0); pxfDate: FieldDefs.Add(fname, ftDate, 0);
pxfShort: Fielddefs.Add(fname, ftSmallInt, F^.fSize); pxfShort: FieldDefs.Add(fname, ftSmallInt, F^.fSize);
pxfLong: Fielddefs.Add(fname, ftInteger, F^.fSize); pxfLong: FieldDefs.Add(fname, ftInteger, F^.fSize);
pxfCurrency: Fielddefs.Add(fname, ftFloat, F^.fSize); pxfCurrency: FieldDefs.Add(fname, ftCurrency, F^.fSize);
pxfNumber: Fielddefs.Add(fname, ftFloat, F^.fSize); pxfNumber: FieldDefs.Add(fname, ftFloat, F^.fSize);
pxfLogical: Fielddefs.Add(fname, ftBoolean, F^.fSize); pxfLogical: FieldDefs.Add(fname, ftBoolean, 0); //F^.fSize);
pxfMemoBLOb: Fielddefs.Add(fname, ftMemo, F^.fSize); pxfMemoBLOb: FieldDefs.Add(fname, ftMemo, F^.fSize);
pxfBLOb: Fielddefs.Add(fname, ftBlob, F^.fSize); pxfBLOb: FieldDefs.Add(fname, ftBlob, F^.fSize);
pxfFmtMemoBLOb: Fielddefs.Add(fname, ftMemo, F^.fSize); pxfFmtMemoBLOb: FieldDefs.Add(fname, ftMemo, F^.fSize);
pxfOLE: Fielddefs.Add(fname, ftBlob, F^.fSize); pxfOLE: FieldDefs.Add(fname, ftBlob, F^.fSize);
pxfGraphic: Fielddefs.Add(fname, ftBlob, F^.fSize); pxfGraphic: FieldDefs.Add(fname, ftBlob, F^.fSize);
pxfTime: Fielddefs.Add(fname, ftTime, F^.fSize); pxfTime: FieldDefs.Add(fname, ftTime, 0); //F^.fSize);
pxfTimestamp: Fielddefs.Add(fname, ftDateTime, 0); pxfTimestamp: FieldDefs.Add(fname, ftDateTime, 0);
pxfAutoInc: Fielddefs.Add(fname, ftAutoInc, F^.fSize); pxfAutoInc: FieldDefs.Add(fname, ftAutoInc, F^.fSize);
pxfBCD: Fielddefs.Add(fname, ftBCD, F^.fSize); pxfBCD: FieldDefs.Add(fname, ftBCD, F^.fSize);
pxfBytes: Fielddefs.Add(fname, ftString, F^.fSize); pxfBytes: FieldDefs.Add(fname, ftString, F^.fSize);
end; end;
inc(FNamesStart, Length(fname)+1); inc(FNamesStart, Length(fname)+1);
inc(F); inc(F);
@@ -396,8 +411,10 @@ end;
function TParadoxDataSet.GetRecordCount: Integer; function TParadoxDataSet.GetRecordCount: Integer;
begin begin
if not Assigned(Fheader) then exit; if Assigned(FHeader) then
Result := FHeader^.numRecords; Result := FHeader^.numRecords
else
Result := 0;
end; end;
function TParadoxDataSet.IsCursorOpen: Boolean; function TParadoxDataSet.IsCursorOpen: Boolean;
@@ -566,7 +583,7 @@ function TParadoxDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
type type
TNRec= array[0..16] of byte; TNRec= array[0..16] of byte;
var var
b : Boolean; b: WordBool;
F: PFldInfoRec; F: PFldInfoRec;
i: Integer; i: Integer;
size: Integer; size: Integer;
@@ -577,23 +594,19 @@ var
d: Double absolute s; d: Double absolute s;
begin begin
Result := False; Result := False;
// F := FHeader^.fldInfoPtr; { begin with the first field identifier }
F := FFieldInfoPtr; { begin with the first field identifier } F := FFieldInfoPtr; { begin with the first field identifier }
p := ActiveBuffer; p := ActiveBuffer;
For i := 1 to FHeader^.numFields do for i := 1 to FHeader^.numFields do
begin begin
if i = Field.FieldNo then if i = Field.FieldNo then
break; break;
If F^.fType = pxfBCD then { BCD field size value not used for field size } if F^.fType = pxfBCD then { BCD field size value not used for field size }
//Inc(ptrrec(p).ofs, 17)
Inc(p, 17) Inc(p, 17)
else else
//Inc(ptrrec(p).ofs, F^.fSize);
Inc(p, F^.fSize); Inc(p, F^.fSize);
//Inc(ptrrec(F).ofs, sizeof(F^));
Inc(F); Inc(F);
end; end;
If F^.fType = pxfBCD then { BCD field size value not used for field size } if F^.fType = pxfBCD then { BCD field size value not used for field size }
size := 17 size := 17
else else
size := F^.fSize; size := F^.fSize;
@@ -638,12 +651,12 @@ begin
Move(d,Buffer^,sizeof(d)); Move(d,Buffer^,sizeof(d));
Result := True; Result := True;
end; end;
pxfLogical: pxfLogical:
begin begin
// b := (p^ = #80); b := not ((p^ = #$80) or (p^ = #0));
// Move(b,Buffer^,sizeof(Boolean)); if Assigned(Buffer) then
// Result := True; Move(b, Buffer^, Sizeof(b));
Result := true;
end; end;
pxfTime: pxfTime:
begin begin
@@ -651,8 +664,10 @@ begin
Move(i,Buffer^,sizeof(Integer)); Move(i,Buffer^,sizeof(Integer));
Result := True; Result := True;
end; end;
pxfTimestamp: pxfTimeStamp:
begin begin
Move(s[0], Buffer^, 8);
Result := true;
end; end;
end; end;
end; end;