mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 21:09:07 +02:00
* fcl-base/dbase: memo definitions clarified
git-svn-id: trunk@24159 -
This commit is contained in:
parent
17f65340c4
commit
5c6b0d39e9
@ -352,7 +352,7 @@ var
|
|||||||
// http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx
|
// http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx
|
||||||
case version of
|
case version of
|
||||||
$30, $31, $32: FDbfVersion:=xVisualFoxPro;
|
$30, $31, $32: FDbfVersion:=xVisualFoxPro;
|
||||||
$F5: FDbfVersion:=xFoxPro;
|
$F5, $FB: FDbfVersion:=xFoxPro;
|
||||||
end;
|
end;
|
||||||
if FDbfVersion = xUnknown then
|
if FDbfVersion = xUnknown then
|
||||||
case (version and $07) of
|
case (version and $07) of
|
||||||
@ -366,11 +366,7 @@ var
|
|||||||
$02, $05:
|
$02, $05:
|
||||||
FDbfVersion := xFoxPro;
|
FDbfVersion := xFoxPro;
|
||||||
else
|
else
|
||||||
// todo: check visual foxpro, modify
|
|
||||||
if ((version and $FE) = $30) or (version = $F5) or (version = $FB) then
|
|
||||||
begin
|
begin
|
||||||
FDbfVersion := xFoxPro;
|
|
||||||
end else begin
|
|
||||||
// not a valid DBF file
|
// not a valid DBF file
|
||||||
raise EDbfError.Create(STRING_INVALID_DBF_FILE);
|
raise EDbfError.Create(STRING_INVALID_DBF_FILE);
|
||||||
end;
|
end;
|
||||||
@ -677,6 +673,8 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
|
// Up to 32kb strings
|
||||||
|
// Stores high byte of size in precision, low in size
|
||||||
lPrec := lSize shr 8;
|
lPrec := lSize shr 8;
|
||||||
lSize := lSize and $FF;
|
lSize := lSize and $FF;
|
||||||
end;
|
end;
|
||||||
@ -699,6 +697,7 @@ begin
|
|||||||
lFieldDescIII.FieldPrecision := lPrec;
|
lFieldDescIII.FieldPrecision := lPrec;
|
||||||
if (FDbfVersion in [xFoxPro,xVisualFoxPro]) then
|
if (FDbfVersion in [xFoxPro,xVisualFoxPro]) then
|
||||||
lFieldDescIII.FieldOffset := SwapIntLE(lFieldOffset);
|
lFieldDescIII.FieldOffset := SwapIntLE(lFieldOffset);
|
||||||
|
// Adjust the version info if needed for supporting field types used:
|
||||||
if (PDbfHdr(Header)^.VerDBF = $02) and (lFieldDef.NativeFieldType in ['0', 'Y', 'T', 'O', '+']) then
|
if (PDbfHdr(Header)^.VerDBF = $02) and (lFieldDef.NativeFieldType in ['0', 'Y', 'T', 'O', '+']) then
|
||||||
PDbfHdr(Header)^.VerDBF := $30; {Visual FoxPro}
|
PDbfHdr(Header)^.VerDBF := $30; {Visual FoxPro}
|
||||||
if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then
|
if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then
|
||||||
|
@ -80,7 +80,7 @@ type
|
|||||||
// Native dbf field type
|
// Native dbf field type
|
||||||
property NativeFieldType: TDbfFieldType read FNativeFieldType write SetNativeFieldType;
|
property NativeFieldType: TDbfFieldType read FNativeFieldType write SetNativeFieldType;
|
||||||
property NullPosition: integer read FNullPosition write FNullPosition;
|
property NullPosition: integer read FNullPosition write FNullPosition;
|
||||||
// Size in dbase file (not VCL/LCL)
|
// Size in memory (not VCL/LCL)
|
||||||
property Size: Integer read FSize write SetSize;
|
property Size: Integer read FSize write SetSize;
|
||||||
// Precision in dbase file (not VCL/LCL)
|
// Precision in dbase file (not VCL/LCL)
|
||||||
property Precision: Integer read FPrecision write SetPrecision;
|
property Precision: Integer read FPrecision write SetPrecision;
|
||||||
@ -118,7 +118,7 @@ uses
|
|||||||
|
|
||||||
const
|
const
|
||||||
(*
|
(*
|
||||||
The theory is:
|
The theory for Delphi/FPC is:
|
||||||
ftSmallint 16 bits = -32768 to 32767
|
ftSmallint 16 bits = -32768 to 32767
|
||||||
123456 = 6 digit max theorically
|
123456 = 6 digit max theorically
|
||||||
DIGITS_SMALLINT = 6;
|
DIGITS_SMALLINT = 6;
|
||||||
@ -135,15 +135,15 @@ be able to handles fields with 999999 (6 digits).
|
|||||||
So I oversize the field type in order to accept anything coming from the
|
So I oversize the field type in order to accept anything coming from the
|
||||||
database.
|
database.
|
||||||
ftSmallint 16 bits = -32768 to 32767
|
ftSmallint 16 bits = -32768 to 32767
|
||||||
-999 to 9999
|
... dbf supports: -999 to 9999
|
||||||
4 digits max theorically
|
4 digits max in practice
|
||||||
DIGITS_SMALLINT = 4;
|
therefore DIGITS_SMALLINT = 4;
|
||||||
ftInteger 32 bits = -2147483648 to 2147483647
|
ftInteger 32 bits = -2147483648 to 2147483647
|
||||||
-99999999 to 999999999 12345678901 = 11 digits max
|
... dbf supports: -99999999 to 999999999 12345678901 = 11 digits max
|
||||||
DIGITS_INTEGER = 9;
|
therefore DIGITS_INTEGER = 9;
|
||||||
ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807
|
ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807
|
||||||
-99999999999999999 to 999999999999999999
|
... dbf supports: -99999999999999999 to 999999999999999999
|
||||||
DIGITS_LARGEINT = 18;
|
therefore DIGITS_LARGEINT = 18;
|
||||||
*)
|
*)
|
||||||
DIGITS_SMALLINT = 4;
|
DIGITS_SMALLINT = 4;
|
||||||
DIGITS_INTEGER = 9;
|
DIGITS_INTEGER = 9;
|
||||||
|
@ -101,16 +101,20 @@ uses
|
|||||||
//=== Memo and binary fields support
|
//=== Memo and binary fields support
|
||||||
//====================================================================
|
//====================================================================
|
||||||
type
|
type
|
||||||
|
// DBase III+ dbt memo file
|
||||||
PDbtHdr = ^rDbtHdr;
|
PDbtHdr = ^rDbtHdr;
|
||||||
rDbtHdr = record
|
rDbtHdr = record
|
||||||
NextBlock : dword;
|
NextBlock : dword; // 0..3
|
||||||
Dummy : array [4..7] of Byte;
|
// Dummy in DBaseIII; size of blocks in memo file; default 512 bytes
|
||||||
|
BlockSize : dword; // 4..7
|
||||||
|
// DBF file name without extension
|
||||||
DbfFile : array [0..7] of Byte; // 8..15
|
DbfFile : array [0..7] of Byte; // 8..15
|
||||||
|
// DBase III only: version number $03
|
||||||
bVer : Byte; // 16
|
bVer : Byte; // 16
|
||||||
Dummy2 : array [17..19] of Byte;
|
Dummy2 : array [17..19] of Byte; // 17..19
|
||||||
|
// Block length in bytes; DBaseIII: always $01
|
||||||
BlockLen : Word; // 20..21
|
BlockLen : Word; // 20..21
|
||||||
Dummy3 : array [22..511] of Byte;
|
Dummy3 : array [22..511] of Byte;// 22..511 First block; garbage contents
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PFptHdr = ^rFptHdr;
|
PFptHdr = ^rFptHdr;
|
||||||
@ -121,10 +125,12 @@ type
|
|||||||
Dummy3 : array [8..511] of Byte;
|
Dummy3 : array [8..511] of Byte;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Header of a memo data block:
|
||||||
PBlockHdr = ^rBlockHdr;
|
PBlockHdr = ^rBlockHdr;
|
||||||
rBlockHdr = record
|
rBlockHdr = record
|
||||||
MemoType : Cardinal;
|
// DBase IV(+) identifier: $FF $FF $08 $00
|
||||||
MemoSize : Cardinal;
|
MemoType : Cardinal; // 0..4
|
||||||
|
MemoSize : Cardinal; // 5..7
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -184,7 +190,8 @@ begin
|
|||||||
RecordSize := GetBlockLen;
|
RecordSize := GetBlockLen;
|
||||||
// checking for right blocksize not needed for foxpro?
|
// checking for right blocksize not needed for foxpro?
|
||||||
// mod 128 <> 0 <-> and 0x7F <> 0
|
// mod 128 <> 0 <-> and 0x7F <> 0
|
||||||
if (RecordSize = 0) and ((FDbfVersion in [xFoxPro,xVisualFoxPro]) or ((RecordSize and $7F) <> 0)) then
|
if (RecordSize = 0) and
|
||||||
|
((FDbfVersion in [xFoxPro,xVisualFoxPro]) or ((RecordSize and $7F) <> 0)) then
|
||||||
begin
|
begin
|
||||||
SetBlockLen(512);
|
SetBlockLen(512);
|
||||||
RecordSize := 512;
|
RecordSize := 512;
|
||||||
@ -271,15 +278,15 @@ begin
|
|||||||
// dbase III memo
|
// dbase III memo
|
||||||
done := false;
|
done := false;
|
||||||
repeat
|
repeat
|
||||||
// scan for EOF
|
// scan for EOF marker
|
||||||
endMemo := MemScan(FBuffer, $1A, RecordSize);
|
endMemo := MemScan(FBuffer, $1A, RecordSize);
|
||||||
// EOF found?
|
// EOF found?
|
||||||
if endMemo <> nil then
|
if endMemo <> nil then
|
||||||
begin
|
begin
|
||||||
// really EOF?
|
// really EOF? expect another 1A or null character
|
||||||
if (endMemo-FBuffer < RecordSize - 1) and ((endMemo[1] = #$1A) or (endMemo[1] = #0)) then
|
if (endMemo-FBuffer < RecordSize - 1) and
|
||||||
|
((endMemo[1] = #$1A) or (endMemo[1] = #0)) then
|
||||||
begin
|
begin
|
||||||
// yes, EOF found
|
|
||||||
done := true;
|
done := true;
|
||||||
numBytes := endMemo - FBuffer;
|
numBytes := endMemo - FBuffer;
|
||||||
end else begin
|
end else begin
|
||||||
@ -344,7 +351,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
bytesBefore := SizeOf(rBlockHdr);
|
bytesBefore := SizeOf(rBlockHdr);
|
||||||
bytesAfter := 0;
|
bytesAfter := 0;
|
||||||
end else begin // dBase3 type
|
end else begin // dBase3 type, Clipper?
|
||||||
bytesBefore := 0;
|
bytesBefore := 0;
|
||||||
bytesAfter := 2;
|
bytesAfter := 2;
|
||||||
end;
|
end;
|
||||||
@ -383,7 +390,7 @@ begin
|
|||||||
repeat
|
repeat
|
||||||
// read bytes, don't overwrite header
|
// read bytes, don't overwrite header
|
||||||
readBytes := Src.Read(FBuffer[bytesBefore], RecordSize{PDbtHdr(Header).BlockLen}-bytesBefore);
|
readBytes := Src.Read(FBuffer[bytesBefore], RecordSize{PDbtHdr(Header).BlockLen}-bytesBefore);
|
||||||
// end of input data reached ? check if need to write block terminators
|
// end of input data reached? check if we need to write block terminators
|
||||||
while (readBytes < RecordSize - bytesBefore) and (bytesAfter > 0) do
|
while (readBytes < RecordSize - bytesBefore) and (bytesAfter > 0) do
|
||||||
begin
|
begin
|
||||||
FBuffer[readBytes] := #$1A;
|
FBuffer[readBytes] := #$1A;
|
||||||
@ -428,7 +435,7 @@ end;
|
|||||||
|
|
||||||
function TDbaseMemoFile.GetMemoSize: Integer;
|
function TDbaseMemoFile.GetMemoSize: Integer;
|
||||||
begin
|
begin
|
||||||
// dBase4 memofiles contain small 'header'
|
// dBase4 memofiles contain a small 'header'
|
||||||
if PInteger(@FBuffer[0])^ = Integer(SwapIntLE($0008FFFF)) then
|
if PInteger(@FBuffer[0])^ = Integer(SwapIntLE($0008FFFF)) then
|
||||||
Result := SwapIntLE(PBlockHdr(FBuffer)^.MemoSize)-8
|
Result := SwapIntLE(PBlockHdr(FBuffer)^.MemoSize)-8
|
||||||
else
|
else
|
||||||
|
@ -51,9 +51,9 @@ type
|
|||||||
rFieldDescIII = packed record
|
rFieldDescIII = packed record
|
||||||
FieldName : array[0..10] of Char;
|
FieldName : array[0..10] of Char;
|
||||||
FieldType : Char; // 11
|
FieldType : Char; // 11
|
||||||
FieldOffset : Integer; // 12..15
|
|
||||||
// FieldOffset only applicable to (visual) foxpro databases
|
// FieldOffset only applicable to (visual) foxpro databases
|
||||||
// DBase III uses it for address in memory
|
// DBase III uses it for address in memory
|
||||||
|
FieldOffset : Integer; // 12..15
|
||||||
FieldSize : Byte; // 16
|
FieldSize : Byte; // 16
|
||||||
FieldPrecision : Byte; // 17, also known as decimal count
|
FieldPrecision : Byte; // 17, also known as decimal count
|
||||||
FoxProFlags : Byte; // 18
|
FoxProFlags : Byte; // 18
|
||||||
|
Loading…
Reference in New Issue
Block a user