Skip to main content

bincode/de/
decoder.rs

1use super::{
2    read::{BorrowReader, Reader},
3    BorrowDecoder, Decoder, UntrustedDecoder,
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/// Use [`Self::new_untrusted`] to construct a decoder accepted by the explicit
13/// untrusted traits. Allocation behavior belongs to the trait being called:
14/// `Decode` retains ordinary behavior even on this decoder; call
15/// [`super::DecodeUntrusted::decode_untrusted`] for collection safeguards.
16///
17/// The ByteOrder that is chosen will impact the endianness that
18/// is used to read integers out of the reader.
19///
20/// ```
21/// # let slice: &[u8] = &[0, 0, 0, 0];
22/// # let some_reader = bincode::de::read::SliceReader::new(slice);
23/// use bincode::de::{DecoderImpl, Decode};
24/// let mut context = ();
25/// let mut decoder = DecoderImpl::new(some_reader, bincode::config::standard(), &mut context);
26/// // this u32 can be any Decode
27/// let value = u32::decode(&mut decoder).unwrap();
28/// ```
29pub struct DecoderImpl<R, C: Config, Context, const UNTRUSTED: bool = false> {
30    reader: R,
31    config: C,
32    bytes_read: usize,
33    context: Context,
34}
35
36impl<R: Reader, C: Config, Context> DecoderImpl<R, C, Context> {
37    /// Construct a new Decoder
38    pub fn new(reader: R, config: C, context: Context) -> DecoderImpl<R, C, Context> {
39        DecoderImpl {
40            reader,
41            config,
42            bytes_read: 0,
43            context,
44        }
45    }
46
47    /// Construct a decoder accepted by [`super::DecodeUntrusted`].
48    ///
49    /// Call the untrusted traits to use their [collection safeguards](crate#untrusted-input).
50    /// The capability is preserved by [`Decoder::with_context`] and mutable references.
51    pub fn new_untrusted(
52        reader: R,
53        config: C,
54        context: Context,
55    ) -> DecoderImpl<R, C, Context, true> {
56        DecoderImpl {
57            reader,
58            config,
59            bytes_read: 0,
60            context,
61        }
62    }
63}
64
65impl<R, C: Config, Context, const UNTRUSTED: bool> Sealed
66    for DecoderImpl<R, C, Context, UNTRUSTED>
67{
68}
69
70impl<R: Reader, C: Config, Context> UntrustedDecoder for DecoderImpl<R, C, Context, true> {}
71
72impl<'de, R: BorrowReader<'de>, C: Config, Context, const UNTRUSTED: bool> BorrowDecoder<'de>
73    for DecoderImpl<R, C, Context, UNTRUSTED>
74{
75    type BR = R;
76
77    fn borrow_reader(&mut self) -> &mut Self::BR {
78        &mut self.reader
79    }
80}
81
82impl<R: Reader, C: Config, Context, const UNTRUSTED: bool> Decoder
83    for DecoderImpl<R, C, Context, UNTRUSTED>
84{
85    type R = R;
86
87    type C = C;
88    type Context = Context;
89
90    fn reader(&mut self) -> &mut Self::R {
91        &mut self.reader
92    }
93
94    fn config(&self) -> &Self::C {
95        &self.config
96    }
97
98    #[inline]
99    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
100        // C::LIMIT is a const so this check should get compiled away
101        if let Some(limit) = C::LIMIT {
102            // Make sure we don't accidentally overflow `bytes_read`
103            self.bytes_read = self
104                .bytes_read
105                .checked_add(n)
106                .ok_or(DecodeError::LimitExceeded)?;
107            if self.bytes_read > limit {
108                Err(DecodeError::LimitExceeded)
109            } else {
110                Ok(())
111            }
112        } else {
113            Ok(())
114        }
115    }
116
117    #[inline]
118    fn unclaim_bytes_read(&mut self, n: usize) {
119        // C::LIMIT is a const so this check should get compiled away
120        if C::LIMIT.is_some() {
121            // We should always be claiming more than we unclaim, so this should never underflow
122            self.bytes_read -= n;
123        }
124    }
125
126    fn context(&mut self) -> &mut Self::Context {
127        &mut self.context
128    }
129}
130
131pub struct WithContext<'a, D: ?Sized, C> {
132    pub(crate) decoder: &'a mut D,
133    pub(crate) context: C,
134}
135
136impl<C, D: Decoder + ?Sized> Sealed for WithContext<'_, D, C> {}
137
138impl<C, D: UntrustedDecoder + ?Sized> UntrustedDecoder for WithContext<'_, D, C> {}
139
140impl<Context, D: Decoder + ?Sized> Decoder for WithContext<'_, D, Context> {
141    type R = D::R;
142
143    type C = D::C;
144
145    type Context = Context;
146
147    fn context(&mut self) -> &mut Self::Context {
148        &mut self.context
149    }
150
151    fn reader(&mut self) -> &mut Self::R {
152        self.decoder.reader()
153    }
154
155    fn config(&self) -> &Self::C {
156        self.decoder.config()
157    }
158
159    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
160        self.decoder.claim_bytes_read(n)
161    }
162
163    fn unclaim_bytes_read(&mut self, n: usize) {
164        self.decoder.unclaim_bytes_read(n)
165    }
166}
167
168impl<'de, C, D: BorrowDecoder<'de>> BorrowDecoder<'de> for WithContext<'_, D, C> {
169    type BR = D::BR;
170    fn borrow_reader(&mut self) -> &mut Self::BR {
171        self.decoder.borrow_reader()
172    }
173}