Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating Visual FoxPro files results in an incorrect Header Length #117

Open
d4mation opened this issue Sep 12, 2022 · 1 comment
Open

Comments

@d4mation
Copy link

d4mation commented Sep 12, 2022

I've noticed that if a Visual FoxPro DBase file (TableType::VISUAL_FOXPRO) already exists, you can open and modify it just fine. This is because its Header Length is already defined.

However, if you're creating one from scratch, it has to generate the Header and this fails. This is because there is no Specification defined for Visual FoxPro so it falls back to the default. Edit: Actually, the issue is TableCreator::prepare_header() in this case. See my next comment.

$spec = new Specification();
switch ($version) {
case TableType::DBASE_7_MEMO:
case TableType::DBASE_7_NOMEMO:
$spec->headerTopLength = 68; // 32 + [Language driver name](32) + [Reserved](4) +
$spec->fieldLength = 48;
break;
}

This results in a non-integer value from VisualFoxproHeaderReader::getLogicalFieldCount() which throws an exception.

I've been trying to determine how to get the necessary values for a valid Specification without success. Is there any documentation out there regarding how to get this information? I've been unable to find anything myself.

@d4mation
Copy link
Author

d4mation commented Sep 13, 2022

Update:

It seems the default Spec may be correct. https://web.archive.org/web/20160324152619/https://fox.wikis.com/wc.dll?Wiki~TableFileStructure

It seems that the Header Length itself just needs some adjustments in how it is calculated, likely using the extractArgs method for the VisualFoxproHeaderReader Class.

Edit:

The primary culprit is TableCreator::prepareHeader() where it writes the Header Length. This doesn't take into consideration the Backlist Length for Visual FoxPro files.

Given the global use of TableCreator for any DBase file, I don't think there's a good way to adjust that behavior without making Classes that extend it to adjust this behavior similar to how the Specification and HeaderReader Classes work.

In my case, I may just calculate the appropriate Header Length and write it to the file after it is created. This should solve my immediate problem.

Edit 2:

Here's the code I wrote to patch the Header Length after creating my table.

$file_stream = Stream::createFromFile( $path, 'rb+' );

// Position of first record is stored in bytes 8-9
$file_stream->seek( 8 );
$saved_header_length = $file_stream->readUShort();

// Calculate correct Header Length. Just have to add the length of the Backlist in there
$header_length = $saved_header_length + VisualFoxproHeaderReader::VFP_BACKLIST_LENGTH;

// Write the corrected Header Length to the proper offset
$file_stream->seek( 8 );
$file_stream->writeUShort( $header_length );

$file_stream->close();

// This helps to confirm that our adjusted Header Length worked by attempting to parse the Header
$table_reader = new TableReader( $path );
$table_reader->close();

@d4mation d4mation changed the title Creating Visual FoxPro files Creating Visual FoxPro files results in an incorrect Header Length Sep 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant