Created
November 3, 2024 09:42
-
-
Save Alxandr/8c0f8a651d2dfc41bea8fcf0e2eb0d44 to your computer and use it in GitHub Desktop.
This file contains 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
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