bincode_thin/
internal.rs

1use serde;
2use std::io::{Read, Write};
3
4use config::{Options, OptionsExt};
5use de::read::BincodeRead;
6use {ErrorKind, Result};
7
8#[derive(Clone)]
9struct CountSize<L: SizeLimit> {
10    total: u64,
11    other_limit: L,
12}
13
14pub(crate) fn serialize_into<W, T: ?Sized, O>(writer: W, value: &T, mut options: O) -> Result<()>
15where
16    W: Write,
17    T: serde::Serialize,
18    O: Options,
19{
20    if options.limit().limit().is_some() {
21        // "compute" the size for the side-effect
22        // of returning Err if the bound was reached.
23        serialized_size(value, &mut options)?;
24    }
25
26    let mut serializer = ::ser::Serializer::<_, O>::new(writer, options);
27    serde::Serialize::serialize(value, &mut serializer)
28}
29
30pub(crate) fn serialize<T: ?Sized, O>(value: &T, mut options: O) -> Result<Vec<u8>>
31where
32    T: serde::Serialize,
33    O: Options,
34{
35    let mut writer = {
36        let actual_size = serialized_size(value, &mut options)?;
37        Vec::with_capacity(actual_size as usize)
38    };
39
40    serialize_into(&mut writer, value, options.with_no_limit())?;
41    Ok(writer)
42}
43
44impl<L: SizeLimit> SizeLimit for CountSize<L> {
45    fn add(&mut self, c: u64) -> Result<()> {
46        self.other_limit.add(c)?;
47        self.total += c;
48        Ok(())
49    }
50
51    fn limit(&self) -> Option<u64> {
52        unreachable!();
53    }
54}
55
56pub(crate) fn serialized_size<T: ?Sized, O: Options>(value: &T, mut options: O) -> Result<u64>
57where
58    T: serde::Serialize,
59{
60    let old_limiter = options.limit().clone();
61    let mut size_counter = ::ser::SizeChecker {
62        options: ::config::WithOtherLimit::new(
63            options,
64            CountSize {
65                total: 0,
66                other_limit: old_limiter,
67            },
68        ),
69    };
70
71    let result = value.serialize(&mut size_counter);
72    result.map(|_| size_counter.options.new_limit.total)
73}
74
75pub(crate) fn deserialize_from<R, T, O>(reader: R, options: O) -> Result<T>
76where
77    R: Read,
78    T: serde::de::DeserializeOwned,
79    O: Options,
80{
81    let reader = ::de::read::IoReader::new(reader);
82    let mut deserializer = ::de::Deserializer::<_, O>::new(reader, options);
83    serde::Deserialize::deserialize(&mut deserializer)
84}
85
86pub(crate) fn deserialize_from_custom<'a, R, T, O>(reader: R, options: O) -> Result<T>
87where
88    R: BincodeRead<'a>,
89    T: serde::de::DeserializeOwned,
90    O: Options,
91{
92    let mut deserializer = ::de::Deserializer::<_, O>::new(reader, options);
93    serde::Deserialize::deserialize(&mut deserializer)
94}
95
96pub(crate) fn deserialize_in_place<'a, R, T, O>(reader: R, options: O, place: &mut T) -> Result<()>
97where
98    R: BincodeRead<'a>,
99    T: serde::de::Deserialize<'a>,
100    O: Options,
101{
102    let mut deserializer = ::de::Deserializer::<_, _>::new(reader, options);
103    serde::Deserialize::deserialize_in_place(&mut deserializer, place)
104}
105
106pub(crate) fn deserialize<'a, T, O>(bytes: &'a [u8], options: O) -> Result<T>
107where
108    T: serde::de::Deserialize<'a>,
109    O: Options,
110{
111    let reader = ::de::read::SliceReader::new(bytes);
112    let options = ::config::WithOtherLimit::new(options, Infinite);
113    let mut deserializer = ::de::Deserializer::new(reader, options);
114    serde::Deserialize::deserialize(&mut deserializer)
115}
116
117pub(crate) fn deserialize_seed<'a, T, O>(seed: T, bytes: &'a [u8], options: O) -> Result<T::Value>
118where
119    T: serde::de::DeserializeSeed<'a>,
120    O: Options,
121{
122    let reader = ::de::read::SliceReader::new(bytes);
123    let options = ::config::WithOtherLimit::new(options, Infinite);
124    let mut deserializer = ::de::Deserializer::new(reader, options);
125    seed.deserialize(&mut deserializer)
126}
127
128pub(crate) trait SizeLimit: Clone {
129    /// Tells the SizeLimit that a certain number of bytes has been
130    /// read or written.  Returns Err if the limit has been exceeded.
131    fn add(&mut self, n: u64) -> Result<()>;
132    /// Returns the hard limit (if one exists)
133    fn limit(&self) -> Option<u64>;
134}
135
136/// A SizeLimit that restricts serialized or deserialized messages from
137/// exceeding a certain byte length.
138#[derive(Copy, Clone)]
139pub struct Bounded(pub u64);
140
141/// A SizeLimit without a limit!
142/// Use this if you don't care about the size of encoded or decoded messages.
143#[derive(Copy, Clone)]
144pub struct Infinite;
145
146impl SizeLimit for Bounded {
147    #[inline(always)]
148    fn add(&mut self, n: u64) -> Result<()> {
149        if self.0 >= n {
150            self.0 -= n;
151            Ok(())
152        } else {
153            Err(Box::new(ErrorKind::SizeLimit))
154        }
155    }
156
157    #[inline(always)]
158    fn limit(&self) -> Option<u64> {
159        Some(self.0)
160    }
161}
162
163impl SizeLimit for Infinite {
164    #[inline(always)]
165    fn add(&mut self, _: u64) -> Result<()> {
166        Ok(())
167    }
168
169    #[inline(always)]
170    fn limit(&self) -> Option<u64> {
171        None
172    }
173}