#[inline]
pub(crate) fn u16_at(b: &[u8], at: usize) -> Option<u16> {
match b.get(at..at.checked_add(2)?)? {
&[x0, x1] => Some(u16::from_le_bytes([x0, x1])),
_ => None,
}
}
#[inline]
pub(crate) fn u32_at(b: &[u8], at: usize) -> Option<u32> {
match b.get(at..at.checked_add(4)?)? {
&[x0, x1, x2, x3] => Some(u32::from_le_bytes([x0, x1, x2, x3])),
_ => None,
}
}
#[inline]
pub(crate) fn u64_at(b: &[u8], at: usize) -> Option<u64> {
match b.get(at..at.checked_add(8)?)? {
&[x0, x1, x2, x3, x4, x5, x6, x7] => {
Some(u64::from_le_bytes([x0, x1, x2, x3, x4, x5, x6, x7]))
}
_ => None,
}
}
#[derive(Clone, Copy)]
pub(crate) struct Cur<'a> {
b: &'a [u8],
pos: usize,
}
impl<'a> Cur<'a> {
#[inline]
pub(crate) const fn new(b: &'a [u8], pos: usize) -> Self {
Cur { b, pos }
}
#[inline]
pub(crate) const fn pos(&self) -> usize {
self.pos
}
#[inline]
pub(crate) const fn bytes(&self) -> &'a [u8] {
self.b
}
#[inline]
pub(crate) fn at_end(&self) -> bool {
self.pos >= self.b.len()
}
#[inline]
pub(crate) fn remaining(&self) -> usize {
self.b.len().saturating_sub(self.pos)
}
#[inline]
pub(crate) fn u8(&mut self) -> Option<u8> {
let v = *self.b.get(self.pos)?;
self.pos = self.pos.checked_add(1)?;
Some(v)
}
#[inline]
pub(crate) fn u32(&mut self) -> Option<u32> {
let v = u32_at(self.b, self.pos)?;
self.pos = self.pos.checked_add(4)?;
Some(v)
}
#[inline]
pub(crate) fn varint(&mut self) -> Option<u32> {
let first = self.u8()?;
if first & 0x80 == 0 {
return Some(u32::from(first));
}
let mut value = u32::from(first & 0x7f);
let mut shift = 7u32;
loop {
let b = self.u8()?;
let low = u32::from(b & 0x7f);
if shift == 28 && (b & 0x80 != 0 || low > 0x0f) {
return None;
}
value |= low << shift;
if b & 0x80 == 0 {
return if b == 0 { None } else { Some(value) };
}
shift += 7;
}
}
#[inline]
pub(crate) fn len(&mut self) -> Option<usize> {
self.varint().map(|v| v as usize)
}
#[inline]
pub(crate) fn skip(&mut self, n: usize) -> Option<()> {
let end = self.pos.checked_add(n)?;
if end > self.b.len() {
return None;
}
self.pos = end;
Some(())
}
#[inline]
pub(crate) fn take(&mut self, n: usize) -> Option<&'a [u8]> {
let end = self.pos.checked_add(n)?;
let s = self.b.get(self.pos..end)?;
self.pos = end;
Some(s)
}
}
pub(crate) fn varint64(c: &mut Cur<'_>) -> Option<u64> {
let mut value = 0u64;
let mut shift = 0u32;
loop {
let b = c.u8()?;
let low = u64::from(b & 0x7f);
if shift == 63 && (b & 0x80 != 0 || low > 1) {
return None;
}
value |= low << shift;
if b & 0x80 == 0 {
return if b == 0 && shift > 0 {
None
} else {
Some(value)
};
}
shift += 7;
}
}
#[inline]
pub(crate) fn nul_pos(b: &[u8]) -> Option<usize> {
const LO: u64 = 0x0101_0101_0101_0101;
const HI: u64 = 0x8080_8080_8080_8080;
let (chunks, rest) = b.as_chunks::<8>();
let mut base = 0usize;
for c in chunks {
let v = u64::from_le_bytes(*c);
let z = v.wrapping_sub(LO) & !v & HI;
if z != 0 {
return base.checked_add((z.trailing_zeros() / 8) as usize);
}
base = base.wrapping_add(8);
}
let mut i = base;
for &x in rest {
if x == 0 {
return Some(i);
}
i = i.wrapping_add(1);
}
None
}
#[inline]
pub(crate) fn plane_entry(index: &[u8], n: usize, i: usize) -> Option<u32> {
let b0 = *index.get(i)?;
let b1 = *index.get(n.checked_add(i)?)?;
let b2 = *index.get(n.checked_mul(2)?.checked_add(i)?)?;
let b3 = *index.get(n.checked_mul(3)?.checked_add(i)?)?;
Some(u32::from_le_bytes([b0, b1, b2, b3]))
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::indexing_slicing)]
mod tests {
use alloc::vec;
use super::{Cur, nul_pos, varint64};
fn v(b: &[u8]) -> Option<u32> {
let mut c = Cur::new(b, 0);
let r = c.varint()?;
c.at_end().then_some(r)
}
#[test]
fn varints() {
assert_eq!(v(&[0]), Some(0));
assert_eq!(v(&[0x7f]), Some(127));
assert_eq!(v(&[0x80, 0x01]), Some(128));
assert_eq!(v(&[0xff, 0xff, 0xff, 0xff, 0x0f]), Some(u32::MAX));
assert_eq!(v(&[0x80, 0x00]), None);
assert_eq!(v(&[0xff, 0xff, 0xff, 0xff, 0x1f]), None);
assert_eq!(v(&[0x80, 0x80, 0x80, 0x80, 0x80, 0x01]), None);
assert_eq!(v(&[0x80]), None);
let mut c = Cur::new(&[0xff; 10], 0);
assert_eq!(varint64(&mut c), None);
let mut c = Cur::new(
&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01],
0,
);
assert_eq!(varint64(&mut c), Some(u64::MAX));
}
#[test]
fn nul() {
for len in 0..40 {
let mut b = vec![b'a'; len];
assert_eq!(nul_pos(&b), None);
for at in 0..len {
b[at] = 0;
assert_eq!(nul_pos(&b), Some(at));
b[at] = 0x80;
}
}
}
}