pub trait Decoder: Sealed {
type R: Reader;
type C: Config;
fn reader(&mut self) -> &mut Self::R;
fn config(&self) -> &Self::C;
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError>;
fn unclaim_bytes_read(&mut self, n: usize);
fn claim_container_read<T>(&mut self, len: usize) -> Result<(), DecodeError> { ... }
}
Expand description
Any source that can decode basic types. This type is most notably implemented for Decoder.
Associated Types
Required methods
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError>
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError>
Claim that n
bytes are going to be read from the decoder.
This can be used to validate Configuration::Limit<N>()
.
fn unclaim_bytes_read(&mut self, n: usize)
fn unclaim_bytes_read(&mut self, n: usize)
Notify the decoder that n
bytes are being reclaimed.
When decoding container types, a typical implementation would claim to read len * size_of::<T>()
bytes.
This is to ensure that bincode won’t allocate several GB of memory while constructing the container.
Because the implementation claims len * size_of::<T>()
, but then has to decode each T
, this would be marked
as double. This function allows us to un-claim each T
that gets decoded.
We cannot check if len * size_of::<T>()
is valid without claiming it, because this would mean that if you have
a nested container (e.g. Vec<Vec<T>>
), it does not know how much memory is already claimed, and could easily
allocate much more than the user intends.
impl<T: Decode> Decode for Container<T> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let len = u64::decode(decoder)? as usize;
// Make sure we don't allocate too much memory
decoder.claim_bytes_read(len * core::mem::size_of::<T>());
let mut result = Container::with_capacity(len);
for _ in 0..len {
// un-claim the memory
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
result.push(T::decode(decoder)?)
}
Ok(result)
}
}
Provided methods
fn claim_container_read<T>(&mut self, len: usize) -> Result<(), DecodeError>
fn claim_container_read<T>(&mut self, len: usize) -> Result<(), DecodeError>
Claim that we’re going to read a container which contains len
entries of T
.
This will correctly handle overflowing if len * size_of::<T>() > usize::max_value