Skip to main content

cracode/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 = cracode::de::read::SliceReader::new(slice);
18/// use cracode::de::{DecoderImpl, Decode};
19/// let mut context = ();
20/// let mut decoder = DecoderImpl::new(some_reader, cracode::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.bytes_read.checked_add(n).ok_or(DecodeError::LimitExceeded)?;
75            if self.bytes_read > limit {
76                Err(DecodeError::LimitExceeded)
77            } else {
78                Ok(())
79            }
80        } else {
81            Ok(())
82        }
83    }
84
85    #[inline]
86    fn unclaim_bytes_read(&mut self, n: usize) {
87        // C::LIMIT is a const so this check should get compiled away
88        if C::LIMIT.is_some() {
89            // We should always be claiming more than we unclaim, so this should never underflow
90            self.bytes_read -= n;
91        }
92    }
93
94    fn context(&mut self) -> &mut Self::Context {
95        &mut self.context
96    }
97}
98
99pub struct WithContext<'a, D: ?Sized, C> {
100    pub(crate) decoder: &'a mut D,
101    pub(crate) context: C,
102}
103
104impl<C, D: Decoder + ?Sized> Sealed for WithContext<'_, D, C> {}
105
106impl<Context, D: Decoder + ?Sized> Decoder for WithContext<'_, D, Context> {
107    type R = D::R;
108
109    type C = D::C;
110
111    type Context = Context;
112
113    fn context(&mut self) -> &mut Self::Context {
114        &mut self.context
115    }
116
117    fn reader(&mut self) -> &mut Self::R {
118        self.decoder.reader()
119    }
120
121    fn config(&self) -> &Self::C {
122        self.decoder.config()
123    }
124
125    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
126        self.decoder.claim_bytes_read(n)
127    }
128
129    fn unclaim_bytes_read(&mut self, n: usize) {
130        self.decoder.unclaim_bytes_read(n)
131    }
132}
133
134impl<'de, C, D: BorrowDecoder<'de>> BorrowDecoder<'de> for WithContext<'_, D, C> {
135    type BR = D::BR;
136    fn borrow_reader(&mut self) -> &mut Self::BR {
137        self.decoder.borrow_reader()
138    }
139}