1 | use serde::de::{self, DeserializeSeed, VariantAccess, Visitor}; |
2 | use static_assertions::assert_impl_all; |
3 | |
4 | use std::{marker::PhantomData, str}; |
5 | |
6 | #[cfg (unix)] |
7 | use std::os::fd::{AsFd, AsRawFd}; |
8 | |
9 | #[cfg (feature = "gvariant" )] |
10 | use crate::gvariant::Deserializer as GVDeserializer; |
11 | use crate::{ |
12 | container_depths::ContainerDepths, dbus::Deserializer as DBusDeserializer, serialized::Context, |
13 | signature_parser::SignatureParser, utils::*, Basic, Error, ObjectPath, Result, Signature, |
14 | }; |
15 | |
16 | #[cfg (unix)] |
17 | use crate::Fd; |
18 | |
19 | /// Our deserialization implementation. |
20 | #[derive (Debug)] |
21 | pub(crate) struct DeserializerCommon<'de, 'sig, 'f, F> { |
22 | pub(crate) ctxt: Context, |
23 | pub(crate) bytes: &'de [u8], |
24 | |
25 | #[cfg (unix)] |
26 | pub(crate) fds: Option<&'f [F]>, |
27 | #[cfg (not(unix))] |
28 | pub(crate) fds: PhantomData<&'f F>, |
29 | |
30 | pub(crate) pos: usize, |
31 | |
32 | pub(crate) sig_parser: SignatureParser<'sig>, |
33 | |
34 | pub(crate) container_depths: ContainerDepths, |
35 | } |
36 | |
37 | /// Our deserialization implementation. |
38 | /// |
39 | /// Using this deserializer involves an redirection to the actual deserializer. It's best |
40 | /// to use the serialization functions, e.g [`crate::to_bytes`] or specific serializers, |
41 | /// [`crate::dbus::Deserializer`] or [`crate::zvariant::Deserializer`]. |
42 | pub(crate) enum Deserializer<'ser, 'sig, 'f, F> { |
43 | DBus(DBusDeserializer<'ser, 'sig, 'f, F>), |
44 | #[cfg (feature = "gvariant" )] |
45 | GVariant(GVDeserializer<'ser, 'sig, 'f, F>), |
46 | } |
47 | |
48 | assert_impl_all!(Deserializer<'_, '_, '_, ()>: Send, Sync, Unpin); |
49 | |
50 | #[cfg (unix)] |
51 | impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F> |
52 | where |
53 | F: AsFd, |
54 | { |
55 | pub fn get_fd(&self, idx: u32) -> Result<i32> { |
56 | self.fds |
57 | .and_then(|fds| fds.get(idx as usize).map(|fd| fd.as_fd().as_raw_fd())) |
58 | .ok_or(err:Error::UnknownFd) |
59 | } |
60 | } |
61 | |
62 | impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F> { |
63 | pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> { |
64 | let padding = padding_for_n_bytes(self.abs_pos(), alignment); |
65 | if padding > 0 { |
66 | if self.pos + padding > self.bytes.len() { |
67 | return Err(serde::de::Error::invalid_length( |
68 | self.bytes.len(), |
69 | &format!(">= {}" , self.pos + padding).as_str(), |
70 | )); |
71 | } |
72 | |
73 | for i in 0..padding { |
74 | let byte = self.bytes[self.pos + i]; |
75 | if byte != 0 { |
76 | return Err(Error::PaddingNot0(byte)); |
77 | } |
78 | } |
79 | self.pos += padding; |
80 | } |
81 | |
82 | Ok(padding) |
83 | } |
84 | |
85 | pub fn prep_deserialize_basic<T>(&mut self) -> Result<()> |
86 | where |
87 | T: Basic, |
88 | { |
89 | self.sig_parser.skip_char()?; |
90 | self.parse_padding(T::alignment(self.ctxt.format()))?; |
91 | |
92 | Ok(()) |
93 | } |
94 | |
95 | pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> { |
96 | if self.pos + len > self.bytes.len() { |
97 | return Err(serde::de::Error::invalid_length( |
98 | self.bytes.len(), |
99 | &format!(">= {}" , self.pos + len).as_str(), |
100 | )); |
101 | } |
102 | |
103 | let slice = &self.bytes[self.pos..self.pos + len]; |
104 | self.pos += len; |
105 | |
106 | Ok(slice) |
107 | } |
108 | |
109 | pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]> |
110 | where |
111 | T: Basic, |
112 | { |
113 | self.prep_deserialize_basic::<T>()?; |
114 | |
115 | self.next_slice(T::alignment(self.ctxt.format())) |
116 | } |
117 | |
118 | pub fn abs_pos(&self) -> usize { |
119 | self.ctxt.position() + self.pos |
120 | } |
121 | } |
122 | |
123 | macro_rules! deserialize_method { |
124 | ($method:ident($($arg:ident: $type:ty),*)) => { |
125 | #[inline] |
126 | fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value> |
127 | where |
128 | V: Visitor<'de>, |
129 | { |
130 | match self { |
131 | #[cfg(feature = "gvariant" )] |
132 | Deserializer::GVariant(de) => { |
133 | de.$method($($arg,)* visitor) |
134 | } |
135 | Deserializer::DBus(de) => { |
136 | de.$method($($arg,)* visitor) |
137 | } |
138 | } |
139 | } |
140 | } |
141 | } |
142 | |
143 | impl<'de, 'd, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> de::Deserializer<'de> |
144 | for &'d mut Deserializer<'de, 'sig, 'f, F> |
145 | { |
146 | type Error = Error; |
147 | |
148 | deserialize_method!(deserialize_any()); |
149 | deserialize_method!(deserialize_bool()); |
150 | deserialize_method!(deserialize_i8()); |
151 | deserialize_method!(deserialize_i16()); |
152 | deserialize_method!(deserialize_i32()); |
153 | deserialize_method!(deserialize_i64()); |
154 | deserialize_method!(deserialize_u8()); |
155 | deserialize_method!(deserialize_u16()); |
156 | deserialize_method!(deserialize_u32()); |
157 | deserialize_method!(deserialize_u64()); |
158 | deserialize_method!(deserialize_f32()); |
159 | deserialize_method!(deserialize_f64()); |
160 | deserialize_method!(deserialize_char()); |
161 | deserialize_method!(deserialize_str()); |
162 | deserialize_method!(deserialize_string()); |
163 | deserialize_method!(deserialize_bytes()); |
164 | deserialize_method!(deserialize_byte_buf()); |
165 | deserialize_method!(deserialize_option()); |
166 | deserialize_method!(deserialize_unit()); |
167 | deserialize_method!(deserialize_unit_struct(n: &'static str)); |
168 | deserialize_method!(deserialize_newtype_struct(n: &'static str)); |
169 | deserialize_method!(deserialize_seq()); |
170 | deserialize_method!(deserialize_map()); |
171 | deserialize_method!(deserialize_tuple(n: usize)); |
172 | deserialize_method!(deserialize_tuple_struct(n: &'static str, l: usize)); |
173 | deserialize_method!(deserialize_struct( |
174 | n: &'static str, |
175 | f: &'static [&'static str] |
176 | )); |
177 | deserialize_method!(deserialize_enum( |
178 | n: &'static str, |
179 | f: &'static [&'static str] |
180 | )); |
181 | deserialize_method!(deserialize_identifier()); |
182 | deserialize_method!(deserialize_ignored_any()); |
183 | |
184 | fn is_human_readable(&self) -> bool { |
185 | false |
186 | } |
187 | } |
188 | |
189 | #[derive (Debug)] |
190 | pub(crate) enum ValueParseStage { |
191 | Signature, |
192 | Value, |
193 | Done, |
194 | } |
195 | |
196 | pub(crate) fn deserialize_any<'de, 'sig, 'f, D, V>( |
197 | de: D, |
198 | next_char: char, |
199 | visitor: V, |
200 | ) -> Result<V::Value> |
201 | where |
202 | D: de::Deserializer<'de, Error = Error>, |
203 | V: Visitor<'de>, |
204 | { |
205 | match next_char { |
206 | u8::SIGNATURE_CHAR => de.deserialize_u8(visitor), |
207 | bool::SIGNATURE_CHAR => de.deserialize_bool(visitor), |
208 | i16::SIGNATURE_CHAR => de.deserialize_i16(visitor), |
209 | u16::SIGNATURE_CHAR => de.deserialize_u16(visitor), |
210 | i32::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
211 | #[cfg (unix)] |
212 | Fd::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
213 | u32::SIGNATURE_CHAR => de.deserialize_u32(visitor), |
214 | i64::SIGNATURE_CHAR => de.deserialize_i64(visitor), |
215 | u64::SIGNATURE_CHAR => de.deserialize_u64(visitor), |
216 | f64::SIGNATURE_CHAR => de.deserialize_f64(visitor), |
217 | <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR | Signature::SIGNATURE_CHAR => { |
218 | de.deserialize_str(visitor) |
219 | } |
220 | VARIANT_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
221 | ARRAY_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
222 | STRUCT_SIG_START_CHAR => de.deserialize_seq(visitor), |
223 | #[cfg (feature = "gvariant" )] |
224 | MAYBE_SIGNATURE_CHAR => de.deserialize_option(visitor), |
225 | c => Err(de::Error::invalid_value( |
226 | de::Unexpected::Char(c), |
227 | &"a valid signature character" , |
228 | )), |
229 | } |
230 | } |
231 | |
232 | // Enum handling is very generic so it can be here and specific deserializers can use this. |
233 | pub(crate) struct Enum<D, F> { |
234 | pub(crate) de: D, |
235 | pub(crate) name: &'static str, |
236 | pub(crate) _phantom: PhantomData<F>, |
237 | } |
238 | |
239 | impl<'de, D, F> VariantAccess<'de> for Enum<D, F> |
240 | where |
241 | D: de::Deserializer<'de, Error = Error>, |
242 | { |
243 | type Error = Error; |
244 | |
245 | fn unit_variant(self) -> std::result::Result<(), Self::Error> { |
246 | Ok(()) |
247 | } |
248 | |
249 | fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> |
250 | where |
251 | T: DeserializeSeed<'de>, |
252 | { |
253 | seed.deserialize(self.de) |
254 | } |
255 | |
256 | fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> |
257 | where |
258 | V: Visitor<'de>, |
259 | { |
260 | de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor) |
261 | } |
262 | |
263 | fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> |
264 | where |
265 | V: Visitor<'de>, |
266 | { |
267 | de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor) |
268 | } |
269 | } |
270 | |