| use anyhow::ensure; | |
| pub(crate) struct Parser<'a> { | |
| rest: &'a [u8], | |
| } | |
| impl<'a> Parser<'a> { | |
| pub(crate) fn new(input: &'a [u8]) -> Self { | |
| Self { rest: input } | |
| } | |
| pub(crate) fn ensure_empty(self) -> anyhow::Result<()> { | |
| ensure!(self.rest.is_empty(), "unparsed bytes: 0x{:02x?}", self.rest); | |
| Ok(()) | |
| } | |
| pub(crate) fn read_n_bytes(&mut self, n: usize) -> anyhow::Result<&'a [u8]> { | |
| ensure!(n <= self.rest.len()); | |
| let (bytes, rest) = self.rest.split_at(n); | |
| self.rest = rest; | |
| Ok(bytes) | |
| } | |
| pub(crate) fn read_uleb128_u32(&mut self) -> anyhow::Result<u32> { | |
| self.read_uleb128_u64_and_convert() | |
| } | |
| pub(crate) fn read_uleb128_usize(&mut self) -> anyhow::Result<usize> { | |
| self.read_uleb128_u64_and_convert() | |
| } | |
| fn read_uleb128_u64_and_convert<T>(&mut self) -> anyhow::Result<T> | |
| where | |
| T: TryFrom<u64> + 'static, | |
| T::Error: std::error::Error + Send + Sync, | |
| { | |
| let mut temp_rest = self.rest; | |
| let raw_value: u64 = leb128::read::unsigned(&mut temp_rest)?; | |
| let converted_value = T::try_from(raw_value)?; | |
| // Only update `self.rest` if the above steps succeeded, so that the | |
| // parser position can be used for error reporting if desired. | |
| self.rest = temp_rest; | |
| Ok(converted_value) | |
| } | |
| } |