Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ impl Chunk {
self.offsets.iter().map(|&(id, _)| id)
}

/// The byte offsets of the top-level indirect objects in this chunk.
///
/// Each entry is `(object_ref, byte_offset_in_chunk)`, in the order the
/// objects appear in the chunk. This mirrors [`refs()`](Self::refs) but
/// also exposes where each object starts inside the chunk's buffer —
/// useful for callers that want to index into [`as_bytes()`](Self::as_bytes)
/// directly, e.g. to serialize a chunk piecewise or to record the offsets
/// alongside the bytes in an external store.
pub fn object_offsets(&self) -> &[(Ref, usize)] {
&self.offsets
}

/// Returns the limits of data written into the chunk.
pub fn limits(&self) -> &Limits {
self.buf.limits()
Expand Down Expand Up @@ -521,4 +533,29 @@ mod tests {
b"startxref\n160\n%%EOF",
);
}

#[test]
fn test_chunk_object_offsets() {
let mut c = Chunk::new();
c.font_descriptor(Ref::new(5)).name(Name(b"A"));
let start_b = c.len();
c.font_descriptor(Ref::new(9)).name(Name(b"B"));

// object_offsets() and refs() must report the same references in the
// same order, and the offsets must land at real indirect-object
// starts inside the chunk's byte buffer.
let offsets = c.object_offsets();
let refs: Vec<Ref> = c.refs().collect();
assert_eq!(offsets.len(), refs.len());
assert_eq!(offsets.len(), 2);
assert_eq!(offsets[0], (Ref::new(5), 0));
assert_eq!(offsets[1].0, Ref::new(9));
assert_eq!(offsets[1].1, start_b);

let bytes = c.as_bytes();
for (r, off) in offsets {
let header = format!("{} 0 obj", r.get());
assert!(bytes[*off..].starts_with(header.as_bytes()));
}
}
}
Loading