mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 03:19:29 +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
|
||||
case version of
|
||||
$30, $31, $32: FDbfVersion:=xVisualFoxPro;
|
||||
$F5: FDbfVersion:=xFoxPro;
|
||||
$F5, $FB: FDbfVersion:=xFoxPro;
|
||||
end;
|
||||
if FDbfVersion = xUnknown then
|
||||
case (version and $07) of
|
||||
@ -366,11 +366,7 @@ var
|
||||
$02, $05:
|
||||
FDbfVersion := xFoxPro;
|
||||
else
|
||||
// todo: check visual foxpro, modify
|
||||
if ((version and $FE) = $30) or (version = $F5) or (version = $FB) then
|
||||
begin
|
||||
FDbfVersion := xFoxPro;
|
||||
end else begin
|
||||
// not a valid DBF file
|
||||
raise EDbfError.Create(STRING_INVALID_DBF_FILE);
|
||||
end;
|
||||
@ -677,6 +673,8 @@ begin
|
||||
{$endif}
|
||||
then
|
||||
begin
|
||||
// Up to 32kb strings
|
||||
// Stores high byte of size in precision, low in size
|
||||
lPrec := lSize shr 8;
|
||||
lSize := lSize and $FF;
|
||||
end;
|
||||
@ -699,6 +697,7 @@ begin
|
||||
lFieldDescIII.FieldPrecision := lPrec;
|
||||
if (FDbfVersion in [xFoxPro,xVisualFoxPro]) then
|
||||
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
|
||||
PDbfHdr(Header)^.VerDBF := $30; {Visual FoxPro}
|
||||
if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then
|
||||
|
@ -80,7 +80,7 @@ type
|
||||
// Native dbf field type
|
||||
property NativeFieldType: TDbfFieldType read FNativeFieldType write SetNativeFieldType;
|
||||
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;
|
||||
// Precision in dbase file (not VCL/LCL)
|
||||
property Precision: Integer read FPrecision write SetPrecision;
|
||||
@ -118,7 +118,7 @@ uses
|
||||
|
||||
const
|
||||
(*
|
||||
The theory is:
|
||||
The theory for Delphi/FPC is:
|
||||
ftSmallint 16 bits = -32768 to 32767
|
||||
123456 = 6 digit max theorically
|
||||
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
|
||||
database.
|
||||
ftSmallint 16 bits = -32768 to 32767
|
||||
-999 to 9999
|
||||
4 digits max theorically
|
||||
DIGITS_SMALLINT = 4;
|
||||
... dbf supports: -999 to 9999
|
||||
4 digits max in practice
|
||||
therefore DIGITS_SMALLINT = 4;
|
||||
ftInteger 32 bits = -2147483648 to 2147483647
|
||||
-99999999 to 999999999 12345678901 = 11 digits max
|
||||
DIGITS_INTEGER = 9;
|
||||
... dbf supports: -99999999 to 999999999 12345678901 = 11 digits max
|
||||
therefore DIGITS_INTEGER = 9;
|
||||
ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807
|
||||
-99999999999999999 to 999999999999999999
|
||||
DIGITS_LARGEINT = 18;
|
||||
... dbf supports: -99999999999999999 to 999999999999999999
|
||||
therefore DIGITS_LARGEINT = 18;
|
||||
*)
|
||||
DIGITS_SMALLINT = 4;
|
||||
DIGITS_INTEGER = 9;
|
||||
|
@ -101,16 +101,20 @@ uses
|
||||
//=== Memo and binary fields support
|
||||
//====================================================================
|
||||
type
|
||||
|
||||
// DBase III+ dbt memo file
|
||||
PDbtHdr = ^rDbtHdr;
|
||||
rDbtHdr = record
|
||||
NextBlock : dword;
|
||||
Dummy : array [4..7] of Byte;
|
||||
NextBlock : dword; // 0..3
|
||||
// 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
|
||||
// DBase III only: version number $03
|
||||
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
|
||||
Dummy3 : array [22..511] of Byte;
|
||||
Dummy3 : array [22..511] of Byte;// 22..511 First block; garbage contents
|
||||
end;
|
||||
|
||||
PFptHdr = ^rFptHdr;
|
||||
@ -121,10 +125,12 @@ type
|
||||
Dummy3 : array [8..511] of Byte;
|
||||
end;
|
||||
|
||||
// Header of a memo data block:
|
||||
PBlockHdr = ^rBlockHdr;
|
||||
rBlockHdr = record
|
||||
MemoType : Cardinal;
|
||||
MemoSize : Cardinal;
|
||||
// DBase IV(+) identifier: $FF $FF $08 $00
|
||||
MemoType : Cardinal; // 0..4
|
||||
MemoSize : Cardinal; // 5..7
|
||||
end;
|
||||
|
||||
|
||||
@ -184,7 +190,8 @@ begin
|
||||
RecordSize := GetBlockLen;
|
||||
// checking for right blocksize not needed for foxpro?
|
||||
// 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
|
||||
SetBlockLen(512);
|
||||
RecordSize := 512;
|
||||
@ -271,15 +278,15 @@ begin
|
||||
// dbase III memo
|
||||
done := false;
|
||||
repeat
|
||||
// scan for EOF
|
||||
// scan for EOF marker
|
||||
endMemo := MemScan(FBuffer, $1A, RecordSize);
|
||||
// EOF found?
|
||||
if endMemo <> nil then
|
||||
begin
|
||||
// really EOF?
|
||||
if (endMemo-FBuffer < RecordSize - 1) and ((endMemo[1] = #$1A) or (endMemo[1] = #0)) then
|
||||
// really EOF? expect another 1A or null character
|
||||
if (endMemo-FBuffer < RecordSize - 1) and
|
||||
((endMemo[1] = #$1A) or (endMemo[1] = #0)) then
|
||||
begin
|
||||
// yes, EOF found
|
||||
done := true;
|
||||
numBytes := endMemo - FBuffer;
|
||||
end else begin
|
||||
@ -344,7 +351,7 @@ begin
|
||||
begin
|
||||
bytesBefore := SizeOf(rBlockHdr);
|
||||
bytesAfter := 0;
|
||||
end else begin // dBase3 type
|
||||
end else begin // dBase3 type, Clipper?
|
||||
bytesBefore := 0;
|
||||
bytesAfter := 2;
|
||||
end;
|
||||
@ -383,7 +390,7 @@ begin
|
||||
repeat
|
||||
// read bytes, don't overwrite header
|
||||
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
|
||||
begin
|
||||
FBuffer[readBytes] := #$1A;
|
||||
@ -428,7 +435,7 @@ end;
|
||||
|
||||
function TDbaseMemoFile.GetMemoSize: Integer;
|
||||
begin
|
||||
// dBase4 memofiles contain small 'header'
|
||||
// dBase4 memofiles contain a small 'header'
|
||||
if PInteger(@FBuffer[0])^ = Integer(SwapIntLE($0008FFFF)) then
|
||||
Result := SwapIntLE(PBlockHdr(FBuffer)^.MemoSize)-8
|
||||
else
|
||||
|
@ -51,9 +51,9 @@ type
|
||||
rFieldDescIII = packed record
|
||||
FieldName : array[0..10] of Char;
|
||||
FieldType : Char; // 11
|
||||
FieldOffset : Integer; // 12..15
|
||||
// FieldOffset only applicable to (visual) foxpro databases
|
||||
// DBase III uses it for address in memory
|
||||
FieldOffset : Integer; // 12..15
|
||||
FieldSize : Byte; // 16
|
||||
FieldPrecision : Byte; // 17, also known as decimal count
|
||||
FoxProFlags : Byte; // 18
|
||||
|
Loading…
Reference in New Issue
Block a user