Repository navigation
Read fp3/fp5 values with two-byte field references - #32
Open
ChrisWaschl wants to merge 1 commit into
Open
ChrisWaschl wants to merge 1 commit into
ChrisWaschl wants to merge 1 commit into
Conversation
The fp3/fp5 value reader only accepted chunks with a one-byte field reference, so two kinds of values were silently dropped: - Values of columns with an index of 128 and above. Their reference is two bytes long and encoded like a path component (0x80 0x8D is column 269), the same index fmp_list_columns uses. Records whose values all live in such columns were missing from the output entirely. - Segments of long values with a two-byte segment number such as 0x00 0x01, e.g. 46 descriptions in CAKUNITS.FP5. Accept two-byte references and decode the column index from them at the record level. Output is unchanged for all other test files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The narrowly scoped changes reuse existing parser logic, include a regression check, and have no identified blocking issues.
No open issues 🎉
What changed in this PR
Fixes silently omitted fp3/fp5 values by allowing the value reader to handle two-byte field references through existing decoding and assembly logic.
Changes:
- Reads values for column indexes ≥128 and long-value segments with two-byte references.
- Documents both reference encodings in the fp5 format notes.
- Adds a CAKUNITS.FP5 regression check to Linux and macOS CI.
| File | Description |
|---|---|
src/read_values.c |
Accepts two-byte references and decodes record-level column indexes. |
HACKING |
Documents column-index and long-value segment encodings. |
.github/workflows/build.yml |
Checks that an FP5 export includes previously missing text. |
Review effort: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fmp_read_valuessilently drops values in fp3/fp5 files when their field reference is two bytes long.handle_chunk_read_values_v3only acceptsFMP_CHUNK_FIELD_REF_SIMPLE, andprocess_block_v3turns only one-byte references into that type. Two kinds of values are affected:[5].[record]with a two-byte reference (chunk code0x02) encoded like a path component, e.g.0x80 0x8Dfor column 269.path_valuedecodes it to the same indexfmp_list_columnsreads from[3].[5].[269]. Records whose values all live in such columns are missing from the output entirely.0x00 0x01at[5].[record].[column]. The column comes from the path here, andprocess_valuealready handles these chunks; they just never reached it.Column names and column count are correct and nearly all records appear, so the loss only shows up when checking the content.
Changes
handle_chunk_read_values_v3also acceptsFMP_CHUNK_FIELD_REF_LONGwith a two-byte reference. Longer references are still skipped, since nothing here shows what they mean.process_valuedecodes the column index from a two-byte reference at the record level when its high bit is set, usingpath_value.HACKINGdocuments both encodings in the fp5 section.CAKUNITS.FP5and checks for a description that was missing before.Testing
test/dataexceptCAKUNITS.FP3andCAKUNITS.FP5. These keep their 1,351 records and get 84 more values in 57 records (e.g.Description1,231 → 1,277); no existing value changes. Files that failed before still fail the same way.fmp2sqlitewith and without the patch:fmpdumpoutput: every value thatfmpdumpprints as text ends up in the column defined at[3].[5].[index]. The 251 KB file shows the boundary: column 127 was read before, column 128 was not.-Wall -Werror -pedantic-errors.Open question
The rich-text filter in
process_valueskips segments with key 0 only for one-byte references. A two-byte key0x00 0x00would therefore be read as text. It does not occur in the test files or in the two private files checked withfmpdump, so I did not add a filter for it rather than guess at its meaning.