• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::cmp;
2 use std::mem::MaybeUninit;
3 
4 use crate::misc::maybe_uninit_write_slice;
5 
6 #[derive(Debug)]
7 pub(crate) struct InputBuf<'a> {
8     // Invariants: `0 <= pos_within_buf <= limit_within_buf <= buf.len()`.
9     buf: &'a [u8],
10     pos_within_buf: usize,
11     limit_within_buf: usize,
12 }
13 
14 impl<'a> InputBuf<'a> {
15     #[inline]
assertions(&self)16     pub(crate) fn assertions(&self) {
17         debug_assert!(self.pos_within_buf <= self.limit_within_buf);
18         debug_assert!(self.limit_within_buf <= self.buf.len());
19     }
20 
empty() -> InputBuf<'a>21     pub(crate) fn empty() -> InputBuf<'a> {
22         InputBuf {
23             buf: &[],
24             pos_within_buf: 0,
25             limit_within_buf: 0,
26         }
27     }
28 
from_bytes(buf: &'a [u8]) -> InputBuf<'a>29     pub(crate) fn from_bytes(buf: &'a [u8]) -> InputBuf<'a> {
30         InputBuf {
31             buf,
32             pos_within_buf: 0,
33             limit_within_buf: buf.len(),
34         }
35     }
36 
from_bytes_ignore_lifetime(buf: &[u8]) -> InputBuf<'a>37     pub(crate) unsafe fn from_bytes_ignore_lifetime(buf: &[u8]) -> InputBuf<'a> {
38         let buf = &*(buf as *const [u8]);
39         Self::from_bytes(buf)
40     }
41 
update_limit(&mut self, limit: u64)42     pub(crate) fn update_limit(&mut self, limit: u64) {
43         let limit_within_buf = cmp::min(self.buf.len() as u64, limit);
44         assert!(limit_within_buf >= self.pos_within_buf as u64);
45         self.limit_within_buf = limit_within_buf as usize;
46     }
47 
pos_within_buf(&self) -> usize48     pub(crate) fn pos_within_buf(&self) -> usize {
49         self.pos_within_buf
50     }
51 
52     #[inline(always)]
remaining_in_buf(&self) -> &'a [u8]53     pub(crate) fn remaining_in_buf(&self) -> &'a [u8] {
54         // SAFETY: Invariants.
55         unsafe {
56             self.buf
57                 .get_unchecked(self.pos_within_buf..self.limit_within_buf)
58         }
59     }
60 
61     #[inline(always)]
consume(&mut self, amt: usize)62     pub(crate) fn consume(&mut self, amt: usize) {
63         assert!(amt <= self.remaining_in_buf().len());
64         self.pos_within_buf += amt;
65     }
66 
67     #[inline(always)]
read_byte(&mut self) -> Option<u8>68     pub(crate) fn read_byte(&mut self) -> Option<u8> {
69         let r = self.remaining_in_buf().first().copied();
70         if let Some(..) = r {
71             self.pos_within_buf += 1;
72         }
73         r
74     }
75 
read_bytes<'b>(&mut self, dest: &'b mut [MaybeUninit<u8>]) -> &'b mut [u8]76     pub(crate) fn read_bytes<'b>(&mut self, dest: &'b mut [MaybeUninit<u8>]) -> &'b mut [u8] {
77         // This panics if this has not enough data.
78         let r = maybe_uninit_write_slice(dest, &self.remaining_in_buf()[..dest.len()]);
79         self.pos_within_buf += r.len();
80         r
81     }
82 }
83