Repository navigation
Read content-stream operands through ArrayContext instead of Operands - #585
Merged
Merged
Conversation
Operators now decode their operands with the pdf-object-reader decoders, reading in place from the parser's reused operand buffer through ArrayContext::new, so the Operands type and its parallel accessors are gone. To keep this path faster than before, ReadSession::read decodes direct values without copying them into a PdfObject or cloning the traversal state, and ObjectContext borrows the value. ArrayContext gains read_array for fixed numeric runs, and read_all presizes its vector. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
Removes the
Operandstype frompdf-content-stream-operators. Operators now decode their operands with the existingpdf-object-readerdecoders, reading in place from the parser's reused operand buffer.PdfOperator::readtakes&mut OperandContext(anArrayContextover aReadSession) and returnsReadResult.Self::new(operands.read_array()?), numbersoperands.at(i)?, and names/stringsoperands.at::<PdfString>(i)?.bytes, which shares the parsed bytes.TJuses theVec<PdfTextItem>decoder andsc/SCuseread_all.Vec<ObjectVariant>per stream and passes it asArrayContext::new(&operands, session). No per-operatorVec,Arcor byte copies.pdf-object-readerchanges that make this faster than beforeReadSession::readdecodes direct values in place instead of copying each one into a newPdfObject(Arc) and cloning the traversal state. Following references moved intoread_reference.ObjectContextborrows&ObjectVariant, socontext.object().value()becomescontext.object()across the decoder crates.ObjectVariant::kind()andObjectVariant::dictionary()now hold the logic;PdfObjectandResolvedObjectdelegate to them.ArrayContextborrows any slice (newArrayContext::new) and gainsread_array::<T, N>().read_allpresizes itsVec.#[inline]on the small hot decoders. The release profile (opt-level = "z", fat LTO), which benches inherit, barely inlines without it.Benchmark
crates/pdf-content-stream/benches/operator_parsing.rs, release profile. Each of 5 interleaved rounds ran agit archiveexport ofmainand this branch back to back.dispatch_heavymixednumeric_heavyTest plan
cargo fmt --checkcargo clippy --all --workspacecargo test --workspace --exclude pdf-graphics-skia --exclude pdf-conformance: 1,110 passed. Skia crates not built locally; CI covers them.🤖 Generated with Claude Code