Skip to content

Instantly share code, notes, and snippets.

@Alxandr
Created November 3, 2024 09:42
Show Gist options
  • Save Alxandr/8c0f8a651d2dfc41bea8fcf0e2eb0d44 to your computer and use it in GitHub Desktop.
Save Alxandr/8c0f8a651d2dfc41bea8fcf0e2eb0d44 to your computer and use it in GitHub Desktop.
const HIGHEST_BIT_MASK: u32 = 1 << 31;
#[repr(C)]
#[derive(Portable)]
pub struct ArchivedHeaderName {
// if the highest bit is unset, this is a known header index
// else this is 10 bits of length followed by 21 bits of relative pointer
inner: u32_le,
}
impl ArchivedHeaderName {
pub fn serialize<S>(
header: &HeaderName,
serializer: &mut S,
) -> Result<HeaderNameResolver, S::Error>
where
S: Writer + Fallible,
S::Error: Source,
{
let value = match find_known_header_index(header) {
Some(index) => index as u32,
None => {
let pos = serializer.pos();
let bytes = header.as_str().as_bytes();
let len = bytes.len();
serializer.write(bytes)?;
assert!(len < (1 << 10), "header name too long");
pos as u32 | HIGHEST_BIT_MASK
}
};
Ok(HeaderNameResolver { value })
}
pub fn resolve(
header: &HeaderName,
resolver: HeaderNameResolver,
out: rkyv::Place<ArchivedHeaderName>,
) {
munge!(let ArchivedHeaderName { inner } = out);
let value = resolver.value;
if value & HIGHEST_BIT_MASK == 0 {
// known header
Archive::resolve(&u32_le::from_native(value), (), inner);
} else {
// custom header
let pos = value & !HIGHEST_BIT_MASK;
let offset = rkyv::rel_ptr::signed_offset::<Panic>(out.pos(), pos as usize).always_ok();
let offset = u32_le::from_isize::<Panic>(offset).always_ok();
let offset = offset.to_native();
assert!(offset < (1 << 21), "header name offset too large");
let len = header.as_str().as_bytes().len() as u32;
let value = HIGHEST_BIT_MASK | (len << 21) | offset;
inner.write(u32_le::from_native(value));
}
}
}
pub struct HeaderNameResolver {
// if the highest bit is unset ,this is a known header index
// else this is the position of the start of the string
value: u32,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment