bincode/de/
decoder.rs

1use super::{
2    read::{BorrowReader, Reader},
3    BorrowDecoder, Decoder,
4};
5use crate::{config::Config, error::DecodeError, utils::Sealed};
6
7/// A Decoder that reads bytes from a given reader `R`.
8///
9/// This struct should rarely be used.
10/// In most cases, prefer any of the `decode` functions.
11///
12/// The ByteOrder that is chosen will impact the endianness that
13/// is used to read integers out of the reader.
14///
15/// ```
16/// # let slice: &[u8] = &[0, 0, 0, 0];
17/// # let some_reader = bincode::de::read::SliceReader::new(slice);
18/// use bincode::de::{DecoderImpl, Decode};
19/// let mut context = ();
20/// let mut decoder = DecoderImpl::new(some_reader, bincode::config::standard(), &mut context);
21/// // this u32 can be any Decode
22/// let value = u32::decode(&mut decoder).unwrap();
23/// ```
24pub struct DecoderImpl<R, C: Config, Context> {
25    reader: R,
26    config: C,
27    bytes_read: usize,
28    context: Context,
29}
30
31impl<R: Reader, C: Config, Context> DecoderImpl<R, C, Context> {
32    /// Construct a new Decoder
33    pub fn new(reader: R, config: C, context: Context) -> DecoderImpl<R, C, Context> {
34        DecoderImpl {
35            reader,
36            config,
37            bytes_read: 0,
38            context,
39        }
40    }
41}
42
43impl<R, C: Config, Context> Sealed for DecoderImpl<R, C, Context> {}
44
45impl<'de, R: BorrowReader<'de>, C: Config, Context> BorrowDecoder<'de>
46    for DecoderImpl<R, C, Context>
47{
48    type BR = R;
49
50    fn borrow_reader(&mut self) -> &mut Self::BR {
51        &mut self.reader
52    }
53}
54
55impl<R: Reader, C: Config, Context> Decoder for DecoderImpl<R, C, Context> {
56    type R = R;
57
58    type C = C;
59    type Context = Context;
60
61    fn reader(&mut self) -> &mut Self::R {
62        &mut self.reader
63    }
64
65    fn config(&self) -> &Self::C {
66        &self.config
67    }
68
69    #[inline]
70    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
71        // C::LIMIT is a const so this check should get compiled away
72        if let Some(limit) = C::LIMIT {
73            // Make sure we don't accidentally overflow `bytes_read`
74            self.bytes_read = self
75                .bytes_read
76                .checked_add(n)
77                .ok_or(DecodeError::LimitExceeded)?;
78            if self.bytes_read > limit {
79                Err(DecodeError::LimitExceeded)
80            } else {
81                Ok(())
82            }
83        } else {
84            Ok(())
85        }
86    }
87
88    #[inline]
89    fn unclaim_bytes_read(&mut self, n: usize) {
90        // C::LIMIT is a const so this check should get compiled away
91        if C::LIMIT.is_some() {
92            // We should always be claiming more than we unclaim, so this should never underflow
93            self.bytes_read -= n;
94        }
95    }
96
97    fn context(&mut self) -> &mut Self::Context {
98        &mut self.context
99    }
100}
101
102pub struct WithContext<'a, D: ?Sized, C> {
103    pub(crate) decoder: &'a mut D,
104    pub(crate) context: C,
105}
106
107impl<C, D: Decoder + ?Sized> Sealed for WithContext<'_, D, C> {}
108
109impl<Context, D: Decoder + ?Sized> Decoder for WithContext<'_, D, Context> {
110    type R = D::R;
111
112    type C = D::C;
113
114    type Context = Context;
115
116    fn context(&mut self) -> &mut Self::Context {
117        &mut self.context
118    }
119
120    fn reader(&mut self) -> &mut Self::R {
121        self.decoder.reader()
122    }
123
124    fn config(&self) -> &Self::C {
125        self.decoder.config()
126    }
127
128    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
129        self.decoder.claim_bytes_read(n)
130    }
131
132    fn unclaim_bytes_read(&mut self, n: usize) {
133        self.decoder.unclaim_bytes_read(n)
134    }
135}
136
137impl<'de, C, D: BorrowDecoder<'de>> BorrowDecoder<'de> for WithContext<'_, D, C> {
138    type BR = D::BR;
139    fn borrow_reader(&mut self) -> &mut Self::BR {
140        self.decoder.borrow_reader()
141    }
142}