TParadoxDataset: Simplify finding field data and blob data.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6904 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2019-05-10 22:32:13 +00:00
parent cf7fa56835
commit 467b0968ad

View File

@ -125,11 +125,11 @@ type
{ fileData size varies according to maxTableSize } { fileData size varies according to maxTableSize }
end; end;
{ APdoxBlk = packed record TPxField = record
Next, Info: PFldInfoRec;
Prev, Offset: LongInt;
Last: Word; Name: String;
end;} end;
{10-byte Blob Info Block} {10-byte Blob Info Block}
TPxBlobInfo = packed record TPxBlobInfo = packed record
@ -166,6 +166,7 @@ type
FTableNameLen: Integer; FTableNameLen: Integer;
FInputEncoding: String; FInputEncoding: String;
FTargetEncoding: String; FTargetEncoding: String;
FPxFields: Array of TPxField;
procedure SetFileName(const AValue: TFileName); procedure SetFileName(const AValue: TFileName);
function GetEncrypted: Boolean; function GetEncrypted: Boolean;
@ -207,7 +208,7 @@ type
destructor Destroy; override; destructor Destroy; override;
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
procedure SetFieldData(Field: TField; Buffer: Pointer); override; procedure SetFieldData({%H-}Field: TField; {%H-}Buffer: Pointer); override;
property Encrypted: Boolean read GetEncrypted; property Encrypted: Boolean read GetEncrypted;
published published
property TableName: TFileName read FFileName write SetFileName; property TableName: TFileName read FFileName write SetFileName;
@ -425,6 +426,7 @@ var
F: PFldInfoRec; F: PFldInfoRec;
FNamesStart: PChar; FNamesStart: PChar;
fname: String; fname: String;
offs: LongInt;
begin begin
FieldDefs.Clear; FieldDefs.Clear;
F := FFieldInfoPtr; { begin with the first field identifier } F := FFieldInfoPtr; { begin with the first field identifier }
@ -433,6 +435,10 @@ begin
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, FTableNameLen); // over Tablename and padding inc(FNamesStart, FTableNameLen); // over Tablename and padding
SetLength(FPxFields, FHeader^.NumFields);
offs := 0;
for i := 1 to FHeader^.NumFields do for i := 1 to FHeader^.NumFields do
begin begin
fname := ConvertEncoding(StrPas(FNamesStart), GetInputEncoding, GetTargetEncoding); fname := ConvertEncoding(StrPas(FNamesStart), GetInputEncoding, GetTargetEncoding);
@ -455,6 +461,12 @@ begin
pxfBCD: FieldDefs.Add(fname, ftBCD, F^.fSize); pxfBCD: FieldDefs.Add(fname, ftBCD, F^.fSize);
pxfBytes: FieldDefs.Add(fname, ftBytes, F^.fSize); // was: ftString pxfBytes: FieldDefs.Add(fname, ftBytes, F^.fSize); // was: ftString
end; end;
with FPxFields[i-1] do begin
Name := fname;
Info := F;
Offset := offs;
end;
offs := offs + F^.fSize;
inc(FNamesStart, Length(fname)+1); inc(FNamesStart, Length(fname)+1);
inc(F); inc(F);
end; end;
@ -661,25 +673,11 @@ begin
if (RecordCount = 0) then if (RecordCount = 0) then
exit; exit;
F := FFieldInfoPtr; { begin with the first field identifier } F := FPxFields[Field.FieldNo - 1].Info;
p := ActiveBuffer; p := ActiveBuffer + FPxFields[Field.FieldNo - 1].Offset;
for i := 1 to FHeader^.numFields do
begin
if i = Field.FieldNo then
break;
if F^.fType = pxfBCD then { BCD field size value not used for field size }
Inc(p, 17)
else
Inc(p, F^.fSize);
Inc(F);
end;
if F^.fType = pxfBCD then { BCD field size value not used for field size }
size := 17
else
size := F^.fSize; size := F^.fSize;
// These numeric fields are stored as big endian // These numeric fields are stored as big endian --> swap bytes
if F^.fType in [pxfDate..pxfNumber, pxfTime..pxfAutoInc] then begin if F^.fType in [pxfDate..pxfNumber, pxfTime..pxfAutoInc] then begin
for i := 0 to pred(size) do for i := 0 to pred(size) do
s[pred(size-i)] := byte(p[i]); s[pred(size-i)] := byte(p[i]);
@ -701,53 +699,40 @@ begin
Result := true; Result := true;
end; end;
pxfDate: pxfDate:
begin if int <> $FFFFFFFF80000000 then begin // This transforms to Dec/12/9999 and probably is NULL
i := int; Move(int, Buffer^, SizeOf(LongInt));
if i <> $FFFFFFFF80000000 then begin // This transforms to Dec/12/9999 and probably is NULL
Move(i,Buffer^,sizeof(Integer));
Result := True; Result := True;
end; end;
end;
pxfShort: pxfShort:
begin begin
i := si; Move(si, Buffer^, SizeOf(SmallInt));
Move(i,Buffer^,sizeof(Integer));
Result := True; Result := True;
end; end;
pxfLong, pxfAutoInc: pxfLong, pxfAutoInc:
begin begin
i := int; Move(int, Buffer^, SizeOf(LongInt));
Move(i,Buffer^,sizeof(Integer));
Result := True; Result := True;
end; end;
pxfCurrency, pxfNumber: pxfCurrency, pxfNumber, pxfTimeStamp:
begin begin
Move(d,Buffer^,sizeof(d)); Move(d, Buffer^, SizeOf(d));
Result := True; Result := True;
end; end;
pxfLogical: pxfLogical:
begin begin
b := not ((p^ = #$80) or (p^ = #0)); b := not ((p^ = #$80) or (p^ = #0));
if Assigned(Buffer) then if Assigned(Buffer) then
Move(b, Buffer^, Sizeof(b)); Move(b, Buffer^, SizeOf(b));
Result := true; Result := true; // Keep outside "if Assigned" otherwise checkboxes will be wrong.
end; end;
pxfTime: pxfTime:
begin begin
i := int; Move(int, Buffer^, SizeOf(LongInt));
Move(i,Buffer^,sizeof(Integer));
Result := True; Result := True;
end; end;
pxfTimeStamp:
begin
Move(s[0], Buffer^, 8);
Result := true;
end;
pxfGraphic: pxfGraphic:
begin
Result := ActiveBuffer <> nil; Result := ActiveBuffer <> nil;
end; end;
end;
end; end;
constructor TParadoxDataSet.Create(AOwner: TComponent); constructor TParadoxDataSet.Create(AOwner: TComponent);
@ -767,7 +752,6 @@ function TParadoxDataset.CreateBlobStream(Field: TField;
Mode: TBlobStreamMode): TStream; Mode: TBlobStreamMode): TStream;
var var
memStream: TMemoryStream; memStream: TMemoryStream;
F: PFldInfoRec;
p: PChar; p: PChar;
header: PAnsiChar; header: PAnsiChar;
idx: Byte; idx: Byte;
@ -783,19 +767,7 @@ begin
if (Mode <> bmRead) then if (Mode <> bmRead) then
exit; exit;
F := FFieldInfoPtr; { begin with the first field identifier } p := ActiveBuffer + FPxFields[Field.FieldNo - 1].Offset;
p := ActiveBuffer;
for i := 1 to FHeader^.numFields do
begin
if i = Field.FieldNo then
break;
if F^.fType = pxfBCD then { BCD field size value not used for field size }
Inc(p, 17)
else
Inc(p, F^.fSize);
Inc(F);
end;
header := p + Field.Size - SizeOf(TPxBlobInfo); header := p + Field.Size - SizeOf(TPxBlobInfo);
Move(header^, blobInfo{%H-}, SizeOf(blobInfo)); Move(header^, blobInfo{%H-}, SizeOf(blobInfo));
if blobInfo.Length = 0 then if blobInfo.Length = 0 then