From 002d6de3f2e11b2d23c6b229795d2282513fbdc7 Mon Sep 17 00:00:00 2001 From: reiniero Date: Mon, 8 Apr 2013 10:20:18 +0000 Subject: [PATCH] fcl-base/dbase: * fix foxpro (tablelevel 25) files so they are readable by visual foxpro + added file specification links for FoxPro 2.x + added file specification links for Visual FoxPro 9 specific changes git-svn-id: trunk@24204 - --- packages/fcl-db/src/dbase/dbf.pas | 4 ++-- packages/fcl-db/src/dbase/dbf_dbffile.pas | 21 +++++++++++++-------- packages/fcl-db/src/dbase/dbf_fields.pas | 22 +++++++++++++++++++--- packages/fcl-db/src/dbase/dbf_lang.pas | 4 ++-- packages/fcl-db/src/dbase/dbf_pgfile.pas | 4 ++-- packages/fcl-db/src/dbase/readme.txt | 8 +++++++- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/packages/fcl-db/src/dbase/dbf.pas b/packages/fcl-db/src/dbase/dbf.pas index 80c6a7d074..d18e9c06c1 100644 --- a/packages/fcl-db/src/dbase/dbf.pas +++ b/packages/fcl-db/src/dbase/dbf.pas @@ -567,7 +567,7 @@ var begin if FDirty then begin - Size := Position; // Strange but it leave tailing trash bytes if I do not write that. + Size := Position; // Strange but it leaves tailing trash bytes if I do not write that. Dbf := TDbf(FBlobField.DataSet); Translate(true); Dbf.FDbfFile.MemoFile.WriteMemo(FMemoRecNo, FReadSize, Self); @@ -1361,7 +1361,7 @@ begin // store recno we are editing FEditingRecNo := FCursor.PhysicalRecNo; // reread blobs, execute cancel -> clears remembered memo pageno, - // causing it to reread the memo contents + // causing it to reread the x contents for I := 0 to Pred(FieldDefs.Count) do if Assigned(FBlobStreams^[I]) then FBlobStreams^[I].Cancel; diff --git a/packages/fcl-db/src/dbase/dbf_dbffile.pas b/packages/fcl-db/src/dbase/dbf_dbffile.pas index 3a87aa4399..c333aacb60 100644 --- a/packages/fcl-db/src/dbase/dbf_dbffile.pas +++ b/packages/fcl-db/src/dbase/dbf_dbffile.pas @@ -98,7 +98,7 @@ type procedure RepageIndex(AIndexFile: string); procedure CompactIndex(AIndexFile: string); function Insert(Buffer: TRecordBuffer): integer; - // Write relevant dbf head as well as EOF marker at end of file if necessary + // Write relevant dbf header as well as EOF marker at end of file if necessary procedure WriteHeader; override; procedure ApplyAutoIncToBuffer(DestBuf: TRecordBuffer); // dBase7 support. Writeback last next-autoinc value procedure FastPackTable; @@ -352,19 +352,19 @@ var // (including the correction at the bottom): // http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx case version of - $30, $31, $32: FDbfVersion:=xVisualFoxPro; + $30, $31, $32 {VFP9 with new data types}: FDbfVersion:=xVisualFoxPro; $F5, $FB: FDbfVersion:=xFoxPro; end; if FDbfVersion = xUnknown then case (version and $07) of - $03: + $03: //dbf without memo. Could be foxpro, too if LanguageID = 0 then FDbfVersion := xBaseIII else FDbfVersion := xBaseIV; $04: FDbfVersion := xBaseVII; - $02, $05: + $02 {FoxBase, not readable by current Visual FoxPro driver}, $05: FDbfVersion := xFoxPro; else begin @@ -631,9 +631,10 @@ begin // Note: VerDBF may be changed later on depending on what features/fields are used // (autoincrement etc) case FDbfVersion of - xFoxPro: PDbfHdr(Header)^.VerDBF := $02; {FoxBASE} + xFoxPro: PDbfHdr(Header)^.VerDBF := $03; {FoxBASE+/FoxPro/dBASE III PLUS/dBASE IV, no memo + alternative $02 FoxBASE is not readable by current Visual FoxPro drivers} xVisualFoxPro: PDbfHdr(Header)^.VerDBF := $30; {Visual FoxPro no autoincrement,no varchar} - else PDbfHdr(Header)^.VerDBF := $03; {FoxBASE+/dBASE III PLUS, no memo!?} + else PDbfHdr(Header)^.VerDBF := $03; {FoxBASE+/FoxPro/dBASE III PLUS/dBASE IV, no memo} end; // standard language WE/Western Europe, dBase III no language support if FDbfVersion = xBaseIII then @@ -699,7 +700,10 @@ begin 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 + // VerDBF=$03 also includes dbase formats, so we perform an extra check + if (FDBFVersion in [xUnknown,xFoxPro,xVisualFoxPro]) and + (PDbfHdr(Header)^.VerDBF in [$02,$03]) and + (lFieldDef.NativeFieldType in ['0', 'Y', 'T', 'O', '+']) then PDbfHdr(Header)^.VerDBF := $30; {Visual FoxPro} if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then PDbfHdr(Header)^.VerDBF := $31; {Visual FoxPro, autoincrement enabled} @@ -727,7 +731,7 @@ begin begin case FDbfVersion of xBaseIII: PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $80; - xFoxPro: if PDbfHdr(Header)^.VerDBF = $02 then {change from FoxBASE to...} + xFoxPro: if (PDbfHdr(Header)^.VerDBF in [$02,$03]) then {change from FoxBASE to...} PDbfHdr(Header)^.VerDBF := $F5; {...FoxPro 2.x (or earlier) with memo} xVisualFoxPro: //MSDN says field 28 or $02 to set memo flag PDbfHdr(Header)^.MDXFlag := PDbfHdr(Header)^.MDXFlag or $02; @@ -1773,6 +1777,7 @@ begin Dst := PChar(Dst) + TempFieldDef.Offset; asciiContents := false; // todo: check/add visualfoxpro autoincrement capability, null values, DateTime, Currency, and Double data types + // see comments in dbf_fields for details case TempFieldDef.NativeFieldType of '+', 'I' {autoincrement, integer}: begin diff --git a/packages/fcl-db/src/dbase/dbf_fields.pas b/packages/fcl-db/src/dbase/dbf_fields.pas index 7a55b0aadb..df41d82a95 100644 --- a/packages/fcl-db/src/dbase/dbf_fields.pas +++ b/packages/fcl-db/src/dbase/dbf_fields.pas @@ -568,9 +568,25 @@ begin No check, includes: http://msdn.microsoft.com/en-US/library/ww305zh2%28v=vs.80%29.aspx P Picture (in at least Visual FoxPro) - V Varchar/varchar binary (in at least Visual FoxPro) 1 byte up to 255 bytes (or perhaps 254) - W Blob (in at least Visual FoxPro), 4 bytes in a table; stored in .fpt - Q Varbinary (in at least Visual Foxpro) + V Varchar/varchar binary (in Visual FoxPro 9) 1 byte up to 254 bytes. + Same storage as char (padded spaces) but padding is removed on display + http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm + W Blob (Visual FoxPro 9), 4 bytes in a table; stored in .fpt + http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm + Q Varchar (binary) (in Visual Foxpro 9): + accepts null, up to 254 characters (stored as padded with spaces), no code page translations + note varchar (binary)<>varbinary + http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm + Varchar/varbinary storage: + Uses _NullFlags: + bit n=1: nullable field number n is null (as in previous versions) + bit n=0: varchar/varbinary field is full/fills space + bit n=1: varchar/varbinary is not full; last byte of field data contains size + If varchar/varbinary field AND nullable field, 2 bits are used: + - lower bit=full status + - higher bit=null status + + } end; // case end; diff --git a/packages/fcl-db/src/dbase/dbf_lang.pas b/packages/fcl-db/src/dbase/dbf_lang.pas index 1e31f74f10..6e851bf89b 100644 --- a/packages/fcl-db/src/dbase/dbf_lang.pas +++ b/packages/fcl-db/src/dbase/dbf_lang.pas @@ -85,7 +85,7 @@ const FoxLangId_Iceland_861 = $67; // DOS FoxLangId_Czech_895 = $68; // DOS Kamenicky // ... - DbfLangId_POL_620 = $69; // DOS Mazovia + DbfLangId_POL_620 = $69; // DOS Polish Mazovia // ... FoxLangId_Greek_737 = $6A; // DOS (437G) FoxLangId_Turkish_857 = $6B; // DOS @@ -123,7 +123,7 @@ const DbfLocale_Bul868 = $020000; //*************************************************************************// -// DB3/DB4/FoxPro/Visual Foxpro Language ID to CodePage convert table +// DB3/DB4/FoxPro/Visual Foxpro Language ID to CodePage conversion table // Visual FoxPro docs call language ID "code page mark" // or "code page identifier" //*************************************************************************// diff --git a/packages/fcl-db/src/dbase/dbf_pgfile.pas b/packages/fcl-db/src/dbase/dbf_pgfile.pas index 4f585cacb7..efd9ddb23f 100644 --- a/packages/fcl-db/src/dbase/dbf_pgfile.pas +++ b/packages/fcl-db/src/dbase/dbf_pgfile.pas @@ -560,7 +560,7 @@ begin begin // get size left in file for header size := FStream.Size - FHeaderOffset; - // header start before EOF? + // does header start before EOF? if size >= 0 then begin // go to header start @@ -576,7 +576,7 @@ begin Read(FHeader, size); end; end else begin - // header start before EOF, clear header + // clear header size := 0; end; FillChar(FHeader[size], FHeaderSize-size, 0); diff --git a/packages/fcl-db/src/dbase/readme.txt b/packages/fcl-db/src/dbase/readme.txt index 6d7de07eb3..5c78bdcc0a 100644 --- a/packages/fcl-db/src/dbase/readme.txt +++ b/packages/fcl-db/src/dbase/readme.txt @@ -27,5 +27,11 @@ http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx note however that the file type/magic number at offset 0 is incorrect. A community member amended these. See bottom of page +Visual FoxPro 9 specific changes: +http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm + +FoxPro 2.x: +http://support.microsoft.com/kb/98743/en-us + +Flagship/FoxPro/Clipper/DBase III..V .dbf file format description ftp://fship.com/pub/multisoft/flagship/docu/dbfspecs.txt -Flagship/FoxPro/Clipper/DBase III..V .dbf file format description \ No newline at end of file