Repository navigation
Release v5.5.0: move BOM handling into the parse orchestrator - #339
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g-refactor-plan-f82997
CSVParseOrchestrator now scans the first source window for a Unicode BOM, rejects UTF-16/UTF-32 before any serial or speculative parser runs, and hands parsers a BOM-free view. The skipped bytes are reported back through CSVParseWindowResult so source adapters keep speaking in source offsets. Format guessing strips the BOM itself once per guess. This fixes: - utf8_bom() returning false for stream input whose first window went through the speculative parser (only a worker core saw the BOM). - The first row's raw_str() including the BOM bytes and byte_offset() pointing at the BOM instead of the row. - The BOM leaking into the first column name when the mmap head window completes no row and is re-read from offset 0 (exposed by #337). MmapParser now asks the parse result whether the head completed a row instead of comparing positions, since a skipped BOM advances mmap_pos. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CSVParseOrchestrator and format guessing now own BOM handling, so the core no longer needs per-instance scan state. Remove ParserChunkOptions::scan_bom, the core's utf8_bom()/strip_unicode_bom() and their state, and the scan_bom flags on speculative chunks. ParserChunkOptions is now (initial_state, source_start). Stale two-argument ParserChunkOptions(state, false) calls in tests would otherwise have compiled silently as source_start = 0; they were found by temporarily deleting the bool overloads. Update ARCHITECTURE.md, JOURNEY_OF_A_CSV_FIELD.md, and the refactor page to reflect that the orchestrator owns BOM handling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #339 +/- ##
==========================================
+ Coverage 91.61% 91.79% +0.18%
==========================================
Files 61 61
Lines 3780 3780
Branches 1101 1100 -1
==========================================
+ Hits 3463 3470 +7
+ Misses 110 104 -6
+ Partials 207 206 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Release PR for v5.5.0. It contains the BOM stripping refactor and the version bump. The other changes since v5.4.0 are already on
masterand are listed below for the release notes.BOM stripping refactor
Unicode BOM handling moves out of
CSVParserCoreand intoCSVParseOrchestrator, where it runs once at the source-window boundary. The BOM ownership and source-offset invariants are documented in the Unicode BOM handling and source offsets section ofinclude/internal/ARCHITECTURE.md.CSVParseWindowResult, so source adapters keep working in source-byte offsets.guess_format()call instead of once per candidate delimiter.ParserChunkOptionsis now(initial_state, source_start).Bugs fixed
CSVReader::utf8_bom()returnedfalsewhen the first stream window was parsed speculativelyraw_str()began withEF BB BF, and itsbyte_offset()was 0 instead of 3User-visible behavior changes
CSVRow::raw_str()for the first row of a UTF-8 BOM file no longer includes the BOM.CSVRow::byte_offset()for that row is now 3, which is where the row starts in the source. Offsets of later rows are unchanged.utf8_bom()is now correct for speculative stream input.Field values were already correct before this change and are unchanged.
Note on #337 interaction
MmapParser::next()used to decide whether the head window "completed a row" by comparing positions. A skipped BOM now advances the position without completing a row, so the check uses the newCSVParseWindowResult::completed_row()instead.Other changes since v5.4.0 (already on master)
CSVWriterCSVRow::to_jsonVersion bump
include/csv.hppandpyproject.tomlmove from 5.4.0 to 5.5.0.Testing
New
[read_unicode_bom]tests cover the mmap and stream paths:raw_str()andbyte_offset()guess_format()on BOM and UTF-16 filesThere is also a BOM variant of the
[issue_337]long-header test.Before the refactor, these tests failed on the three bugs listed above. Now they pass.
Local runs on Windows with MSVC (VS 2026, x64, Release):
ctestpasses for all 3 targetsctestpasses for all 3 targets. I compiled and linked the twosingle_include_testtranslation units against the freshly generated v5.5.0 single header in a standalone project. The in-treesingle_include_testtarget hits the known MSBuild project-discovery issue on Windows, which is why CI skips it there.CSV_ENABLE_THREADS=OFF:ctestpasses for all 3 targetsTo catch stale call sites when removing the
scan_bomparameter, I temporarily deleted theParserChunkOptions(ParserDFAState, bool)overloads. That surfaced seven test calls likeParserChunkOptions(state, false), which would otherwise have compiled silently assource_start = 0.🤖 Generated with Claude Code
Review validation
An Astra review found no runtime correctness or regression issues. Two inaccurate window/reread comments were corrected, and the standalone BOM refactor history was consolidated into the internal architecture document.
MSVC Release validation after the cleanup:
[read_unicode_bom],[issue_337]regressions: 8 test cases and 9,620,127 assertions pass.