WEBSITE ALPHA · AI-assisted, source-reviewed documentation · Full-stack docs reconciled 2026-08-26
64x64base

DBF_64 Specification

The 64-bit-capacity DBF table layout: version, header, field descriptors, and records.

DBF_64 is x64base's 64-bit-capacity evolution of the xBase DBF table. It keeps the familiar self-describing header + fixed-length records, but lifts record counts and file offsets past the classic 32-bit ceiling while staying backward-compatible with tools that read the legacy header. This page is a source-derived summary of the engine's own reader/writer and validator (src/xbase/dbf_file.cpp, include/xbase/dbf_create.hpp, src/cli/dbf64_header_validate.cpp).

Current explanatory diagrams

Diagram attachments: DIAG-X64GEOM-005, DIAG-X64SELFDESC-006

Trinity headers

x64 self-describing DBF

Current sources:

  • docs/manuals/assets/diagrams/trinity_headers_v1.svg
  • docs/manuals/assets/diagrams/x64_self_describing_dbf_v1.svg

Version byte

The header's version byte identifies the flavor. The engine recognizes the classic families (0x03, 0x83, 0xF5) and Visual FoxPro (0x30, 0x31, 0x32), and adds its own DBF_VERSION_64 marker for 64-bit tables. When the version byte is DBF_VERSION_64, the authoritative record count is the 64-bit field (below) rather than the legacy 32-bit one.

Table header

The base header follows the VFP-style layout (version byte, last-update date, record count, header length, and record length), so legacy readers still see a valid DBF. DBF_64 then carries a large-header extension whose record_count is a 64-bit value.

  • The classic 32-bit record count at offset 4 is preserved and patched for compatibility (clamped when the true count exceeds a 32-bit maximum).
  • The 64-bit record count in the extension is the authoritative row count for a DBF_VERSION_64 table.
  • Header length and record length locate the first data byte and the fixed record stride.

Field descriptors

Each field descriptor defines a name, a type, a length, and decimal places (for numeric types). Which type codes CREATE accepts depends on the DBF flavor. The classic types are shared by every flavor; the binary Visual FoxPro types (I/B/Y/T) are stored as real binary — not the fixed-width ASCII placeholders older builds used — and are accepted by the VFP and x64 flavors.

TypeCodeOn-disk storagedBASE / MSDOSFoxPro 2.6VFPx64
CharacterCfixed-width text
NumericNASCII numeric
FloatFASCII numeric
DateDYYYYMMDD text
LogicalLT / F / ?
MemoMsidecar reference
IntegerI4-byte little-endian int32
DoubleB8-byte IEEE-754
CurrencyY8-byte int64, scaled 10⁴
DateTimeT4-byte Julian day + 4-byte ms
Custom(registered)codec-defined

The four binary types round-trip as their true VFP encodings — verified against an independent, spec-based VFP reader and writer in both directions — rather than the ASCII placeholders earlier builds stored. Custom field types register a type code once (codec + on-disk width + flavor eligibility + display name) and then flow through CREATE, validation, and storage with no further engine change; the built-in binary types use that same registry.

Memo (M) fields store a reference, not the payload — see FPT64 Memo Format.

The catalog also reserves V (Varchar), Q (Varbinary), W (Blob), G (General), and the SQL-native extensions (BigInt, Timestamp, Uuid, …) as planned types; these are not yet accepted by CREATE.

Records

  • Fixed-length records; the stride is the header's record length.
  • A leading deleted flag byte (space = live, * = deleted) precedes the field-aligned payload.
  • Record positions are computed as data_start + recno * record_length using 64-bit arithmetic with overflow checks, so the positioning math itself is not the 32-bit ceiling (subject to the path-by-path status in 64-Bit Capacity Math).
  • A trailing 0x1A byte marks end-of-file.

Runtime widening status (public build, 2026-07)

The on-disk layout above is 64-bit, and the runtime that operates on it has been widened to match. In the current public build, 64-bit record positioning (gotoRec64), the navigation commands, the record-lock API, and the active CDX/LMDB index record numbers are widened and regression-checked (CURSOR, INDEX_X64); the classic recno()/recLength()/recCount()/cpr() accessors now return -1 past their 32-bit range instead of clamping to INT_MAX. A synthetic boundary unit test and a real sparse-file end-to-end test resolve distinct record numbers past 2^31 — the engine reads records at recno 2^31+1/+2 off a sparse x64 table whose record_count is 2^31+2 — so 64-bit record addressing is proven past 2^31. Materializing a fully populated multi-billion-row table is a separate data-volume question. The path-by-path status lives in 64-Bit Capacity Math.

See also