urna_format/sections/blob/
span_overlay.rs1use crate::bytes::{le_u32, le_u64};
13use crate::error::UrnaError;
14use crate::layout::SECTION_BLOB_SPAN_OVERLAY;
15
16pub const BLOB_SPAN_OVERLAY_PAYLOAD_VERSION: u32 = 1;
17pub const BLOB_REF_NONE: u32 = 0xFFFF_FFFF;
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub struct BlobSpanEntry {
25 pub blob_ref_index: u32,
26 pub byte_start: u64,
27 pub byte_end: u64,
28}
29
30fn malformed(reason: impl Into<String>) -> UrnaError {
31 UrnaError::MalformedSectionPayload {
32 section_id: SECTION_BLOB_SPAN_OVERLAY,
33 reason: reason.into(),
34 }
35}
36
37pub fn encode_blob_span_overlay(entries: &[BlobSpanEntry]) -> Result<Vec<u8>, UrnaError> {
40 let mut out = Vec::with_capacity(12 + entries.len() * 16);
41 out.extend_from_slice(&BLOB_SPAN_OVERLAY_PAYLOAD_VERSION.to_le_bytes());
42 out.extend_from_slice(&(entries.len() as u64).to_le_bytes());
43 for e in entries {
44 out.extend_from_slice(&e.blob_ref_index.to_le_bytes());
45 out.extend_from_slice(&e.byte_start.to_le_bytes());
46 out.extend_from_slice(&e.byte_end.to_le_bytes());
47 }
48 Ok(out)
49}
50
51pub fn decode_blob_span_overlay(bytes: &[u8]) -> Result<Vec<BlobSpanEntry>, UrnaError> {
54 let mut cur = Cursor::new(bytes);
55 let version = cur.u32()?;
56 if version != BLOB_SPAN_OVERLAY_PAYLOAD_VERSION {
57 return Err(UrnaError::UnsupportedSectionVersion {
58 section_id: SECTION_BLOB_SPAN_OVERLAY,
59 version,
60 });
61 }
62 let n = cur.u64()? as usize;
63 if n > (bytes.len() - cur.pos) / 16 {
66 return Err(malformed("blob_span_overlay: entry count exceeds payload"));
67 }
68 let mut entries = Vec::with_capacity(n);
69 for _ in 0..n {
70 entries.push(BlobSpanEntry {
71 blob_ref_index: cur.u32()?,
72 byte_start: cur.u64()?,
73 byte_end: cur.u64()?,
74 });
75 }
76 if cur.pos != bytes.len() {
77 return Err(malformed("trailing bytes after entries"));
78 }
79 Ok(entries)
80}
81
82struct Cursor<'a> {
83 buf: &'a [u8],
84 pos: usize,
85}
86
87impl<'a> Cursor<'a> {
88 fn new(buf: &'a [u8]) -> Self {
89 Self { buf, pos: 0 }
90 }
91 fn take(&mut self, n: usize) -> Result<&'a [u8], UrnaError> {
92 if n > self.buf.len() - self.pos {
93 return Err(malformed("unexpected EOF"));
94 }
95 let s = &self.buf[self.pos..self.pos + n];
96 self.pos += n;
97 Ok(s)
98 }
99 fn u32(&mut self) -> Result<u32, UrnaError> {
100 le_u32(self.take(4)?)
101 }
102 fn u64(&mut self) -> Result<u64, UrnaError> {
103 le_u64(self.take(8)?)
104 }
105}