Skip to main content

libvirt_xdr/
de.rs

1//! XDR Deserializer implementation.
2
3use crate::error::{Error, Result};
4use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
5
6/// XDR Deserializer.
7pub struct XdrDeserializer<'de> {
8    input: &'de [u8],
9    pos: usize,
10}
11
12impl<'de> XdrDeserializer<'de> {
13    /// Create a new XDR deserializer.
14    pub fn new(input: &'de [u8]) -> Self {
15        Self { input, pos: 0 }
16    }
17
18    /// Get remaining bytes.
19    pub fn remaining(&self) -> usize {
20        self.input.len() - self.pos
21    }
22
23    /// Read exactly `n` bytes.
24    fn read_bytes(&mut self, n: usize) -> Result<&'de [u8]> {
25        if self.pos + n > self.input.len() {
26            return Err(Error::Eof);
27        }
28        let bytes = &self.input[self.pos..self.pos + n];
29        self.pos += n;
30        Ok(bytes)
31    }
32
33    /// Skip padding bytes for 4-byte alignment.
34    fn skip_padding(&mut self, len: usize) -> Result<()> {
35        let padding = (4 - (len % 4)) % 4;
36        if padding > 0 {
37            self.read_bytes(padding)?;
38        }
39        Ok(())
40    }
41
42    fn read_i32(&mut self) -> Result<i32> {
43        let bytes = self.read_bytes(4)?;
44        Ok(i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
45    }
46
47    fn read_u32(&mut self) -> Result<u32> {
48        let bytes = self.read_bytes(4)?;
49        Ok(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
50    }
51
52    fn read_i64(&mut self) -> Result<i64> {
53        let bytes = self.read_bytes(8)?;
54        Ok(i64::from_be_bytes([
55            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
56        ]))
57    }
58
59    fn read_u64(&mut self) -> Result<u64> {
60        let bytes = self.read_bytes(8)?;
61        Ok(u64::from_be_bytes([
62            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
63        ]))
64    }
65}
66
67impl<'de, 'a> de::Deserializer<'de> for &'a mut XdrDeserializer<'de> {
68    type Error = Error;
69
70    fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
71        Err(Error::Message(
72            "XDR does not support deserialize_any".to_string(),
73        ))
74    }
75
76    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
77        let v = self.read_u32()?;
78        match v {
79            0 => visitor.visit_bool(false),
80            1 => visitor.visit_bool(true),
81            _ => Err(Error::InvalidBool(v)),
82        }
83    }
84
85    fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
86        visitor.visit_i8(self.read_i32()? as i8)
87    }
88
89    fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
90        visitor.visit_i16(self.read_i32()? as i16)
91    }
92
93    fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
94        visitor.visit_i32(self.read_i32()?)
95    }
96
97    fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
98        visitor.visit_i64(self.read_i64()?)
99    }
100
101    fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
102        visitor.visit_u8(self.read_u32()? as u8)
103    }
104
105    fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
106        visitor.visit_u16(self.read_u32()? as u16)
107    }
108
109    fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
110        visitor.visit_u32(self.read_u32()?)
111    }
112
113    fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
114        visitor.visit_u64(self.read_u64()?)
115    }
116
117    fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
118        let bytes = self.read_bytes(4)?;
119        let v = f32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
120        visitor.visit_f32(v)
121    }
122
123    fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
124        let bytes = self.read_bytes(8)?;
125        let v = f64::from_be_bytes([
126            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
127        ]);
128        visitor.visit_f64(v)
129    }
130
131    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
132        let v = self.read_u32()?;
133        match char::from_u32(v) {
134            Some(c) => visitor.visit_char(c),
135            None => Err(Error::Message(format!("invalid char: {}", v))),
136        }
137    }
138
139    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
140        let len = self.read_u32()? as usize;
141        let bytes = self.read_bytes(len)?;
142        self.skip_padding(len)?;
143        let s = std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
144        visitor.visit_borrowed_str(s)
145    }
146
147    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
148        let len = self.read_u32()? as usize;
149        let bytes = self.read_bytes(len)?;
150        self.skip_padding(len)?;
151        let s = std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
152        visitor.visit_string(s.to_string())
153    }
154
155    fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
156        let len = self.read_u32()? as usize;
157        let bytes = self.read_bytes(len)?;
158        self.skip_padding(len)?;
159        visitor.visit_borrowed_bytes(bytes)
160    }
161
162    fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
163        let len = self.read_u32()? as usize;
164        let bytes = self.read_bytes(len)?;
165        self.skip_padding(len)?;
166        visitor.visit_byte_buf(bytes.to_vec())
167    }
168
169    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
170        let present = self.read_u32()?;
171        match present {
172            0 => visitor.visit_none(),
173            1 => visitor.visit_some(self),
174            _ => Err(Error::Message(format!(
175                "invalid option discriminant: {}",
176                present
177            ))),
178        }
179    }
180
181    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
182        visitor.visit_unit()
183    }
184
185    fn deserialize_unit_struct<V: Visitor<'de>>(
186        self,
187        _name: &'static str,
188        visitor: V,
189    ) -> Result<V::Value> {
190        visitor.visit_unit()
191    }
192
193    fn deserialize_newtype_struct<V: Visitor<'de>>(
194        self,
195        name: &'static str,
196        visitor: V,
197    ) -> Result<V::Value> {
198        // Special handling for FixedOpaque16 (UUID) - read 16 raw bytes without length prefix
199        if name == "FixedOpaque16" {
200            let bytes = self.read_bytes(16)?;
201            // No padding needed for 16 bytes (already 4-byte aligned)
202            return visitor.visit_bytes(bytes);
203        }
204        visitor.visit_newtype_struct(self)
205    }
206
207    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
208        let len = self.read_u32()? as usize;
209        visitor.visit_seq(SeqAccessor::new(self, len))
210    }
211
212    fn deserialize_tuple<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
213        visitor.visit_seq(SeqAccessor::new(self, len))
214    }
215
216    fn deserialize_tuple_struct<V: Visitor<'de>>(
217        self,
218        _name: &'static str,
219        len: usize,
220        visitor: V,
221    ) -> Result<V::Value> {
222        visitor.visit_seq(SeqAccessor::new(self, len))
223    }
224
225    fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
226        let len = self.read_u32()? as usize;
227        visitor.visit_map(MapAccessor::new(self, len))
228    }
229
230    fn deserialize_struct<V: Visitor<'de>>(
231        self,
232        _name: &'static str,
233        fields: &'static [&'static str],
234        visitor: V,
235    ) -> Result<V::Value> {
236        visitor.visit_seq(SeqAccessor::new(self, fields.len()))
237    }
238
239    fn deserialize_enum<V: Visitor<'de>>(
240        self,
241        _name: &'static str,
242        _variants: &'static [&'static str],
243        visitor: V,
244    ) -> Result<V::Value> {
245        visitor.visit_enum(EnumAccessor::new(self))
246    }
247
248    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
249        let variant_index = self.read_i32()?;
250        visitor.visit_u32(variant_index as u32)
251    }
252
253    fn deserialize_ignored_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
254        Err(Error::Message(
255            "XDR does not support deserialize_ignored_any".to_string(),
256        ))
257    }
258}
259
260struct SeqAccessor<'a, 'de: 'a> {
261    de: &'a mut XdrDeserializer<'de>,
262    remaining: usize,
263}
264
265impl<'a, 'de> SeqAccessor<'a, 'de> {
266    fn new(de: &'a mut XdrDeserializer<'de>, len: usize) -> Self {
267        Self { de, remaining: len }
268    }
269}
270
271impl<'de, 'a> SeqAccess<'de> for SeqAccessor<'a, 'de> {
272    type Error = Error;
273
274    fn next_element_seed<T: DeserializeSeed<'de>>(
275        &mut self,
276        seed: T,
277    ) -> Result<Option<T::Value>> {
278        if self.remaining == 0 {
279            return Ok(None);
280        }
281        self.remaining -= 1;
282        seed.deserialize(&mut *self.de).map(Some)
283    }
284}
285
286struct MapAccessor<'a, 'de: 'a> {
287    de: &'a mut XdrDeserializer<'de>,
288    remaining: usize,
289}
290
291impl<'a, 'de> MapAccessor<'a, 'de> {
292    fn new(de: &'a mut XdrDeserializer<'de>, len: usize) -> Self {
293        Self { de, remaining: len }
294    }
295}
296
297impl<'de, 'a> MapAccess<'de> for MapAccessor<'a, 'de> {
298    type Error = Error;
299
300    fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
301        if self.remaining == 0 {
302            return Ok(None);
303        }
304        self.remaining -= 1;
305        seed.deserialize(&mut *self.de).map(Some)
306    }
307
308    fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
309        seed.deserialize(&mut *self.de)
310    }
311}
312
313struct EnumAccessor<'a, 'de: 'a> {
314    de: &'a mut XdrDeserializer<'de>,
315}
316
317impl<'a, 'de> EnumAccessor<'a, 'de> {
318    fn new(de: &'a mut XdrDeserializer<'de>) -> Self {
319        Self { de }
320    }
321}
322
323impl<'de, 'a> de::EnumAccess<'de> for EnumAccessor<'a, 'de> {
324    type Error = Error;
325    type Variant = Self;
326
327    fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
328        let val = seed.deserialize(&mut *self.de)?;
329        Ok((val, self))
330    }
331}
332
333impl<'de, 'a> de::VariantAccess<'de> for EnumAccessor<'a, 'de> {
334    type Error = Error;
335
336    fn unit_variant(self) -> Result<()> {
337        Ok(())
338    }
339
340    fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
341        seed.deserialize(&mut *self.de)
342    }
343
344    fn tuple_variant<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
345        de::Deserializer::deserialize_tuple(&mut *self.de, len, visitor)
346    }
347
348    fn struct_variant<V: Visitor<'de>>(
349        self,
350        fields: &'static [&'static str],
351        visitor: V,
352    ) -> Result<V::Value> {
353        de::Deserializer::deserialize_struct(&mut *self.de, "", fields, visitor)
354    }
355}
356
357#[cfg(test)]
358mod tests {
359    use super::*;
360    use serde::Deserialize;
361
362    fn from_bytes<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
363        crate::from_bytes(bytes)
364    }
365
366    #[test]
367    fn test_deserialize_i32() {
368        assert_eq!(from_bytes::<i32>(&[0, 0, 0, 42]).unwrap(), 42);
369        assert_eq!(from_bytes::<i32>(&[255, 255, 255, 255]).unwrap(), -1);
370    }
371
372    #[test]
373    fn test_deserialize_u32() {
374        assert_eq!(from_bytes::<u32>(&[0, 0, 0, 42]).unwrap(), 42);
375        assert_eq!(
376            from_bytes::<u32>(&[255, 255, 255, 255]).unwrap(),
377            0xFFFFFFFF
378        );
379    }
380
381    #[test]
382    fn test_deserialize_i64() {
383        assert_eq!(
384            from_bytes::<i64>(&[0, 0, 0, 0, 0, 0, 0, 42]).unwrap(),
385            42
386        );
387    }
388
389    #[test]
390    fn test_deserialize_bool() {
391        assert!(from_bytes::<bool>(&[0, 0, 0, 1]).unwrap());
392        assert!(!from_bytes::<bool>(&[0, 0, 0, 0]).unwrap());
393        assert!(from_bytes::<bool>(&[0, 0, 0, 2]).is_err());
394    }
395
396    #[test]
397    fn test_deserialize_string() {
398        assert_eq!(
399            from_bytes::<String>(&[0, 0, 0, 2, b'h', b'i', 0, 0]).unwrap(),
400            "hi"
401        );
402        assert_eq!(
403            from_bytes::<String>(&[0, 0, 0, 4, b't', b'e', b's', b't']).unwrap(),
404            "test"
405        );
406    }
407
408    #[test]
409    fn test_deserialize_vec() {
410        let bytes = [
411            0, 0, 0, 3, // length
412            0, 0, 0, 1, // 1
413            0, 0, 0, 2, // 2
414            0, 0, 0, 3, // 3
415        ];
416        assert_eq!(from_bytes::<Vec<i32>>(&bytes).unwrap(), vec![1, 2, 3]);
417    }
418
419    #[test]
420    fn test_deserialize_option() {
421        assert_eq!(
422            from_bytes::<Option<i32>>(&[0, 0, 0, 1, 0, 0, 0, 42]).unwrap(),
423            Some(42)
424        );
425        assert_eq!(
426            from_bytes::<Option<i32>>(&[0, 0, 0, 0]).unwrap(),
427            None
428        );
429    }
430
431    #[test]
432    fn test_deserialize_struct() {
433        #[derive(Debug, PartialEq, Deserialize)]
434        struct Point {
435            x: i32,
436            y: i32,
437        }
438
439        let bytes = [0, 0, 0, 10, 0, 0, 0, 20];
440        assert_eq!(
441            from_bytes::<Point>(&bytes).unwrap(),
442            Point { x: 10, y: 20 }
443        );
444    }
445
446    #[test]
447    fn test_roundtrip() {
448        use serde::Serialize;
449
450        #[derive(Debug, PartialEq, Serialize, Deserialize)]
451        struct TestStruct {
452            name: String,
453            value: i32,
454            items: Vec<u32>,
455            optional: Option<i64>,
456        }
457
458        let original = TestStruct {
459            name: "test".to_string(),
460            value: -42,
461            items: vec![1, 2, 3],
462            optional: Some(12345),
463        };
464
465        let bytes = crate::to_bytes(&original).unwrap();
466        let decoded: TestStruct = crate::from_bytes(&bytes).unwrap();
467
468        assert_eq!(original, decoded);
469    }
470}