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 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 fn add(&mut self, n: u64) -> Result<()>;
132 fn limit(&self) -> Option<u64>;
134}
135
136#[derive(Copy, Clone)]
139pub struct Bounded(pub u64);
140
141#[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}