1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use crate::Error;
use minicbor::Decode;
use std::io;
/// Wraps a [`std::io::Read`] and reads length-delimited CBOR values.
#[derive(Debug)]
pub struct Reader<R> {
reader: R,
buffer: Vec<u8>,
max_len: usize
}
impl<R> Reader<R> {
/// Create a new reader with a max. buffer size of 512KiB.
pub fn new(reader: R) -> Self {
Self::with_buffer(reader, Vec::new())
}
/// Create a new reader with a max. buffer size of 512KiB.
pub fn with_buffer(reader: R, buffer: Vec<u8>) -> Self {
Self { reader, buffer, max_len: 512 * 1024 }
}
/// Set the max. buffer size in bytes.
///
/// If length values greater than this are decoded, an
/// [`Error::InvalidLen`] will be returned.
pub fn set_max_len(&mut self, val: u32) {
self.max_len = val as usize
}
/// Get a reference to the inner reader.
pub fn reader(&self) -> &R {
&self.reader
}
/// Get a mutable reference to the inner reader.
pub fn reader_mut(&mut self) -> &mut R {
&mut self.reader
}
/// Deconstruct this reader into the inner reader and the buffer.
pub fn into_parts(self) -> (R, Vec<u8>) {
(self.reader, self.buffer)
}
}
impl<R: io::Read> Reader<R> {
/// Read the next CBOR value and decode it.
///
/// The value is assumed to be preceded by a `u32` (4 bytes in network
/// byte order) denoting the length of the CBOR item in bytes.
///
/// Reading 0 bytes when decoding the length prefix results in `Ok(None)`,
/// otherwise either `Some` value or an error is returned.
pub fn read<'a, T: Decode<'a, ()>>(&'a mut self) -> Result<Option<T>, Error> {
self.read_with(&mut ())
}
/// Like [`Reader::read`] but accepting a user provided decoding context.
pub fn read_with<'a, C, T: Decode<'a, C>>(&'a mut self, ctx: &mut C) -> Result<Option<T>, Error> {
let mut buf = [0; 4];
let mut len = 0;
while len < 4 {
match self.reader.read(&mut buf[len ..]) {
Ok(0) if len == 0 =>
return Ok(None),
Ok(0) =>
return Err(Error::Io(io::ErrorKind::UnexpectedEof.into())),
Ok(n) =>
len += n,
Err(e) if e.kind() == io::ErrorKind::Interrupted =>
continue,
Err(e) =>
return Err(Error::Io(e))
}
}
let len = u32::from_be_bytes(buf) as usize;
if len > self.max_len {
return Err(Error::InvalidLen)
}
self.buffer.clear();
self.buffer.resize(len, 0u8);
self.reader.read_exact(&mut self.buffer)?;
minicbor::decode_with(&self.buffer, ctx).map_err(Error::Decode).map(Some)
}
}