zvariant/dbus/
ser.rs

1use byteorder::WriteBytesExt;
2use serde::{ser, ser::SerializeSeq, Serialize};
3use static_assertions::assert_impl_all;
4use std::{
5    io::{Seek, Write},
6    marker::PhantomData,
7    str,
8};
9
10#[cfg(unix)]
11use std::os::unix::io::RawFd;
12
13use crate::{
14    container_depths::ContainerDepths, signature_parser::SignatureParser, utils::*, Basic,
15    EncodingContext, EncodingFormat, Error, ObjectPath, Result, Signature,
16};
17
18#[cfg(unix)]
19use crate::Fd;
20
21/// Our D-Bus serialization implementation.
22pub struct Serializer<'ser, 'sig, B, W>(pub(crate) crate::SerializerCommon<'ser, 'sig, B, W>);
23
24assert_impl_all!(Serializer<'_, '_, i32, i32>: Send, Sync, Unpin);
25
26impl<'ser, 'sig, B, W> Serializer<'ser, 'sig, B, W>
27where
28    B: byteorder::ByteOrder,
29    W: Write + Seek,
30{
31    /// Create a D-Bus Serializer struct instance.
32    ///
33    /// On Windows, there is no `fds` argument.
34    pub fn new<'w: 'ser, 'f: 'ser>(
35        signature: &Signature<'sig>,
36        writer: &'w mut W,
37        #[cfg(unix)] fds: &'f mut Vec<RawFd>,
38        ctxt: EncodingContext<B>,
39    ) -> Self {
40        assert_eq!(ctxt.format(), EncodingFormat::DBus);
41
42        let sig_parser = SignatureParser::new(signature.clone());
43        Self(crate::SerializerCommon {
44            ctxt,
45            sig_parser,
46            writer,
47            #[cfg(unix)]
48            fds,
49            bytes_written: 0,
50            value_sign: None,
51            container_depths: Default::default(),
52            b: PhantomData,
53        })
54    }
55}
56
57macro_rules! serialize_basic {
58    ($method:ident($type:ty) $write_method:ident) => {
59        serialize_basic!($method($type) $write_method($type));
60    };
61    ($method:ident($type:ty) $write_method:ident($as:ty)) => {
62        fn $method(self, v: $type) -> Result<()> {
63            self.0.prep_serialize_basic::<$type>()?;
64            self.0.$write_method::<B>(v as $as).map_err(|e| Error::InputOutput(e.into()))
65        }
66    };
67}
68
69impl<'ser, 'sig, 'b, B, W> ser::Serializer for &'b mut Serializer<'ser, 'sig, B, W>
70where
71    B: byteorder::ByteOrder,
72    W: Write + Seek,
73{
74    type Ok = ();
75    type Error = Error;
76
77    type SerializeSeq = SeqSerializer<'ser, 'sig, 'b, B, W>;
78    type SerializeTuple = StructSeqSerializer<'ser, 'sig, 'b, B, W>;
79    type SerializeTupleStruct = StructSeqSerializer<'ser, 'sig, 'b, B, W>;
80    type SerializeTupleVariant = StructSeqSerializer<'ser, 'sig, 'b, B, W>;
81    type SerializeMap = SeqSerializer<'ser, 'sig, 'b, B, W>;
82    type SerializeStruct = StructSeqSerializer<'ser, 'sig, 'b, B, W>;
83    type SerializeStructVariant = StructSeqSerializer<'ser, 'sig, 'b, B, W>;
84
85    serialize_basic!(serialize_bool(bool) write_u32(u32));
86    // No i8 type in D-Bus/GVariant, let's pretend it's i16
87    serialize_basic!(serialize_i8(i8) write_i16(i16));
88    serialize_basic!(serialize_i16(i16) write_i16);
89    serialize_basic!(serialize_i64(i64) write_i64);
90
91    fn serialize_i32(self, v: i32) -> Result<()> {
92        match self.0.sig_parser.next_char()? {
93            #[cfg(unix)]
94            Fd::SIGNATURE_CHAR => {
95                self.0.sig_parser.skip_char()?;
96                self.0.add_padding(u32::alignment(EncodingFormat::DBus))?;
97                let v = self.0.add_fd(v);
98                self.0
99                    .write_u32::<B>(v)
100                    .map_err(|e| Error::InputOutput(e.into()))
101            }
102            _ => {
103                self.0.prep_serialize_basic::<i32>()?;
104                self.0
105                    .write_i32::<B>(v)
106                    .map_err(|e| Error::InputOutput(e.into()))
107            }
108        }
109    }
110
111    fn serialize_u8(self, v: u8) -> Result<()> {
112        self.0.prep_serialize_basic::<u8>()?;
113        // Endianness is irrelevant for single bytes.
114        self.0.write_u8(v).map_err(|e| Error::InputOutput(e.into()))
115    }
116
117    serialize_basic!(serialize_u16(u16) write_u16);
118    serialize_basic!(serialize_u32(u32) write_u32);
119    serialize_basic!(serialize_u64(u64) write_u64);
120    // No f32 type in D-Bus/GVariant, let's pretend it's f64
121    serialize_basic!(serialize_f32(f32) write_f64(f64));
122    serialize_basic!(serialize_f64(f64) write_f64);
123
124    fn serialize_char(self, v: char) -> Result<()> {
125        // No char type in D-Bus, let's pretend it's a string
126        self.serialize_str(&v.to_string())
127    }
128
129    fn serialize_str(self, v: &str) -> Result<()> {
130        if v.contains('\0') {
131            return Err(serde::de::Error::invalid_value(
132                serde::de::Unexpected::Char('\0'),
133                &"D-Bus string type must not contain interior null bytes",
134            ));
135        }
136        let c = self.0.sig_parser.next_char()?;
137        if c == VARIANT_SIGNATURE_CHAR {
138            self.0.value_sign = Some(signature_string!(v));
139        }
140
141        match c {
142            ObjectPath::SIGNATURE_CHAR | <&str>::SIGNATURE_CHAR => {
143                self.0
144                    .add_padding(<&str>::alignment(EncodingFormat::DBus))?;
145                self.0
146                    .write_u32::<B>(usize_to_u32(v.len()))
147                    .map_err(|e| Error::InputOutput(e.into()))?;
148            }
149            Signature::SIGNATURE_CHAR | VARIANT_SIGNATURE_CHAR => {
150                self.0
151                    .write_u8(usize_to_u8(v.len()))
152                    .map_err(|e| Error::InputOutput(e.into()))?;
153            }
154            _ => {
155                let expected = format!(
156                    "`{}`, `{}`, `{}` or `{}`",
157                    <&str>::SIGNATURE_STR,
158                    Signature::SIGNATURE_STR,
159                    ObjectPath::SIGNATURE_STR,
160                    VARIANT_SIGNATURE_CHAR,
161                );
162                return Err(serde::de::Error::invalid_type(
163                    serde::de::Unexpected::Char(c),
164                    &expected.as_str(),
165                ));
166            }
167        }
168
169        self.0.sig_parser.skip_char()?;
170        self.0
171            .write_all(v.as_bytes())
172            .map_err(|e| Error::InputOutput(e.into()))?;
173        self.0
174            .write_all(&b"\0"[..])
175            .map_err(|e| Error::InputOutput(e.into()))?;
176
177        Ok(())
178    }
179
180    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
181        let seq = self.serialize_seq(Some(v.len()))?;
182        seq.ser
183            .0
184            .write(v)
185            .map_err(|e| Error::InputOutput(e.into()))?;
186        seq.end()
187    }
188
189    fn serialize_none(self) -> Result<()> {
190        unreachable!("Option<T> can not be encoded in D-Bus format");
191    }
192
193    fn serialize_some<T>(self, _value: &T) -> Result<()>
194    where
195        T: ?Sized + Serialize,
196    {
197        unreachable!("Option<T> can not be encoded in D-Bus format");
198    }
199
200    fn serialize_unit(self) -> Result<()> {
201        Ok(())
202    }
203
204    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
205        self.serialize_unit()
206    }
207
208    fn serialize_unit_variant(
209        self,
210        _name: &'static str,
211        variant_index: u32,
212        variant: &'static str,
213    ) -> Result<()> {
214        if self.0.sig_parser.next_char()? == <&str>::SIGNATURE_CHAR {
215            variant.serialize(self)
216        } else {
217            variant_index.serialize(self)
218        }
219    }
220
221    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
222    where
223        T: ?Sized + Serialize,
224    {
225        value.serialize(self)?;
226
227        Ok(())
228    }
229
230    fn serialize_newtype_variant<T>(
231        self,
232        _name: &'static str,
233        variant_index: u32,
234        _variant: &'static str,
235        value: &T,
236    ) -> Result<()>
237    where
238        T: ?Sized + Serialize,
239    {
240        self.0.prep_serialize_enum_variant(variant_index)?;
241        value.serialize(&mut *self)?;
242        // Skip the `)`.
243        self.0.sig_parser.skip_char()?;
244
245        Ok(())
246    }
247
248    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
249        self.0.sig_parser.skip_char()?;
250        self.0.add_padding(ARRAY_ALIGNMENT_DBUS)?;
251        // Length in bytes (unfortunately not the same as len passed to us here) which we
252        // initially set to 0.
253        self.0
254            .write_u32::<B>(0_u32)
255            .map_err(|e| Error::InputOutput(e.into()))?;
256
257        let element_signature = self.0.sig_parser.next_signature()?;
258        let element_signature_len = element_signature.len();
259        let element_alignment = alignment_for_signature(&element_signature, self.0.ctxt.format())?;
260
261        // D-Bus expects us to add padding for the first element even when there is no first
262        // element (i-e empty array) so we add padding already.
263        let first_padding = self.0.add_padding(element_alignment)?;
264        let start = self.0.bytes_written;
265        self.0.container_depths = self.0.container_depths.inc_array()?;
266
267        Ok(SeqSerializer {
268            ser: self,
269            start,
270            element_alignment,
271            element_signature_len,
272            first_padding,
273        })
274    }
275
276    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
277        self.serialize_struct("", len)
278    }
279
280    fn serialize_tuple_struct(
281        self,
282        name: &'static str,
283        len: usize,
284    ) -> Result<Self::SerializeTupleStruct> {
285        self.serialize_struct(name, len)
286    }
287
288    fn serialize_tuple_variant(
289        self,
290        _name: &'static str,
291        variant_index: u32,
292        _variant: &'static str,
293        _len: usize,
294    ) -> Result<Self::SerializeTupleVariant> {
295        self.0.prep_serialize_enum_variant(variant_index)?;
296
297        StructSerializer::enum_variant(self).map(StructSeqSerializer::Struct)
298    }
299
300    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
301        self.serialize_seq(len)
302    }
303
304    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
305        if len == 0 {
306            return StructSerializer::unit(self).map(StructSeqSerializer::Struct);
307        }
308
309        match self.0.sig_parser.next_char()? {
310            VARIANT_SIGNATURE_CHAR => {
311                StructSerializer::variant(self).map(StructSeqSerializer::Struct)
312            }
313            ARRAY_SIGNATURE_CHAR => self.serialize_seq(Some(len)).map(StructSeqSerializer::Seq),
314            _ => StructSerializer::structure(self).map(StructSeqSerializer::Struct),
315        }
316    }
317
318    fn serialize_struct_variant(
319        self,
320        _name: &'static str,
321        variant_index: u32,
322        _variant: &'static str,
323        _len: usize,
324    ) -> Result<Self::SerializeStructVariant> {
325        self.0.prep_serialize_enum_variant(variant_index)?;
326
327        StructSerializer::enum_variant(self).map(StructSeqSerializer::Struct)
328    }
329
330    fn is_human_readable(&self) -> bool {
331        false
332    }
333}
334
335#[doc(hidden)]
336pub struct SeqSerializer<'ser, 'sig, 'b, B, W> {
337    ser: &'b mut Serializer<'ser, 'sig, B, W>,
338    start: usize,
339    // alignment of element
340    element_alignment: usize,
341    // size of element signature
342    element_signature_len: usize,
343    // First element's padding
344    first_padding: usize,
345}
346
347impl<'ser, 'sig, 'b, B, W> SeqSerializer<'ser, 'sig, 'b, B, W>
348where
349    B: byteorder::ByteOrder,
350    W: Write + Seek,
351{
352    pub(self) fn end_seq(self) -> Result<()> {
353        self.ser
354            .0
355            .sig_parser
356            .skip_chars(self.element_signature_len)?;
357
358        // Set size of array in bytes
359        let array_len = self.ser.0.bytes_written - self.start;
360        let len = usize_to_u32(array_len);
361        let total_array_len = (array_len + self.first_padding + 4) as i64;
362        self.ser
363            .0
364            .writer
365            .seek(std::io::SeekFrom::Current(-total_array_len))
366            .map_err(|e| Error::InputOutput(e.into()))?;
367        self.ser
368            .0
369            .writer
370            .write_u32::<B>(len)
371            .map_err(|e| Error::InputOutput(e.into()))?;
372        self.ser
373            .0
374            .writer
375            .seek(std::io::SeekFrom::Current(total_array_len - 4))
376            .map_err(|e| Error::InputOutput(e.into()))?;
377
378        self.ser.0.container_depths = self.ser.0.container_depths.dec_array();
379
380        Ok(())
381    }
382}
383
384impl<'ser, 'sig, 'b, B, W> ser::SerializeSeq for SeqSerializer<'ser, 'sig, 'b, B, W>
385where
386    B: byteorder::ByteOrder,
387    W: Write + Seek,
388{
389    type Ok = ();
390    type Error = Error;
391
392    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
393    where
394        T: ?Sized + Serialize,
395    {
396        // We want to keep parsing the same signature repeatedly for each element so we use a
397        // disposable clone.
398        let sig_parser = self.ser.0.sig_parser.clone();
399        self.ser.0.sig_parser = sig_parser.clone();
400
401        value.serialize(&mut *self.ser)?;
402        self.ser.0.sig_parser = sig_parser;
403
404        Ok(())
405    }
406
407    fn end(self) -> Result<()> {
408        self.end_seq()
409    }
410}
411
412#[doc(hidden)]
413pub struct StructSerializer<'ser, 'sig, 'b, B, W> {
414    ser: &'b mut Serializer<'ser, 'sig, B, W>,
415    // The number of `)` in the signature to skip at the end.
416    end_parens: u8,
417    // The original container depths. We restore to that at the end.
418    container_depths: ContainerDepths,
419}
420
421impl<'ser, 'sig, 'b, B, W> StructSerializer<'ser, 'sig, 'b, B, W>
422where
423    B: byteorder::ByteOrder,
424    W: Write + Seek,
425{
426    fn variant(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> {
427        ser.0.add_padding(VARIANT_ALIGNMENT_DBUS)?;
428        let container_depths = ser.0.container_depths;
429        ser.0.container_depths = ser.0.container_depths.inc_variant()?;
430
431        Ok(Self {
432            ser,
433            end_parens: 0,
434            container_depths,
435        })
436    }
437
438    fn structure(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> {
439        let c = ser.0.sig_parser.next_char()?;
440        if c != STRUCT_SIG_START_CHAR && c != DICT_ENTRY_SIG_START_CHAR {
441            let expected = format!("`{STRUCT_SIG_START_STR}` or `{DICT_ENTRY_SIG_START_STR}`",);
442
443            return Err(serde::de::Error::invalid_type(
444                serde::de::Unexpected::Char(c),
445                &expected.as_str(),
446            ));
447        }
448
449        let signature = ser.0.sig_parser.next_signature()?;
450        let alignment = alignment_for_signature(&signature, EncodingFormat::DBus)?;
451        ser.0.add_padding(alignment)?;
452
453        ser.0.sig_parser.skip_char()?;
454        let container_depths = ser.0.container_depths;
455        ser.0.container_depths = ser.0.container_depths.inc_structure()?;
456
457        Ok(Self {
458            ser,
459            end_parens: 1,
460            container_depths,
461        })
462    }
463
464    fn unit(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> {
465        // serialize as a `0u8`
466        serde::Serializer::serialize_u8(&mut *ser, 0)?;
467
468        let container_depths = ser.0.container_depths;
469        Ok(Self {
470            ser,
471            end_parens: 0,
472            container_depths,
473        })
474    }
475
476    fn enum_variant(ser: &'b mut Serializer<'ser, 'sig, B, W>) -> Result<Self> {
477        let mut ser = Self::structure(ser)?;
478        ser.end_parens += 1;
479
480        Ok(ser)
481    }
482
483    fn serialize_struct_element<T>(&mut self, name: Option<&'static str>, value: &T) -> Result<()>
484    where
485        T: ?Sized + Serialize,
486    {
487        match name {
488            Some("zvariant::Value::Value") => {
489                // Serializing the value of a Value, which means signature was serialized
490                // already, and also put aside for us to be picked here.
491                let signature = self
492                    .ser
493                    .0
494                    .value_sign
495                    .take()
496                    .expect("Incorrect Value encoding");
497
498                let sig_parser = SignatureParser::new(signature);
499                let bytes_written = self.ser.0.bytes_written;
500                let mut ser = Serializer(crate::SerializerCommon::<B, W> {
501                    ctxt: self.ser.0.ctxt,
502                    sig_parser,
503                    writer: self.ser.0.writer,
504                    #[cfg(unix)]
505                    fds: self.ser.0.fds,
506                    bytes_written,
507                    value_sign: None,
508                    container_depths: self.ser.0.container_depths,
509                    b: PhantomData,
510                });
511                value.serialize(&mut ser)?;
512                self.ser.0.bytes_written = ser.0.bytes_written;
513
514                Ok(())
515            }
516            _ => value.serialize(&mut *self.ser),
517        }
518    }
519
520    fn end_struct(self) -> Result<()> {
521        if self.end_parens > 0 {
522            self.ser.0.sig_parser.skip_chars(self.end_parens as usize)?;
523        }
524        // Restore the original container depths.
525        self.ser.0.container_depths = self.container_depths;
526
527        Ok(())
528    }
529}
530
531#[doc(hidden)]
532/// Allows us to serialize a struct as an ARRAY.
533pub enum StructSeqSerializer<'ser, 'sig, 'b, B, W> {
534    Struct(StructSerializer<'ser, 'sig, 'b, B, W>),
535    Seq(SeqSerializer<'ser, 'sig, 'b, B, W>),
536}
537
538macro_rules! serialize_struct_anon_fields {
539    ($trait:ident $method:ident) => {
540        impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W>
541        where
542            B: byteorder::ByteOrder,
543            W: Write + Seek,
544        {
545            type Ok = ();
546            type Error = Error;
547
548            fn $method<T>(&mut self, value: &T) -> Result<()>
549            where
550                T: ?Sized + Serialize,
551            {
552                self.serialize_struct_element(None, value)
553            }
554
555            fn end(self) -> Result<()> {
556                self.end_struct()
557            }
558        }
559
560        impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSeqSerializer<'ser, 'sig, 'b, B, W>
561        where
562            B: byteorder::ByteOrder,
563            W: Write + Seek,
564        {
565            type Ok = ();
566            type Error = Error;
567
568            fn $method<T>(&mut self, value: &T) -> Result<()>
569            where
570                T: ?Sized + Serialize,
571            {
572                match self {
573                    StructSeqSerializer::Struct(ser) => ser.$method(value),
574                    StructSeqSerializer::Seq(ser) => ser.serialize_element(value),
575                }
576            }
577
578            fn end(self) -> Result<()> {
579                match self {
580                    StructSeqSerializer::Struct(ser) => ser.end_struct(),
581                    StructSeqSerializer::Seq(ser) => ser.end_seq(),
582                }
583            }
584        }
585    };
586}
587serialize_struct_anon_fields!(SerializeTuple serialize_element);
588serialize_struct_anon_fields!(SerializeTupleStruct serialize_field);
589serialize_struct_anon_fields!(SerializeTupleVariant serialize_field);
590
591impl<'ser, 'sig, 'b, B, W> ser::SerializeMap for SeqSerializer<'ser, 'sig, 'b, B, W>
592where
593    B: byteorder::ByteOrder,
594    W: Write + Seek,
595{
596    type Ok = ();
597    type Error = Error;
598
599    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
600    where
601        T: ?Sized + Serialize,
602    {
603        self.ser.0.add_padding(self.element_alignment)?;
604
605        // We want to keep parsing the same signature repeatedly for each key so we use a
606        // disposable clone.
607        let sig_parser = self.ser.0.sig_parser.clone();
608        self.ser.0.sig_parser = sig_parser.clone();
609
610        // skip `{`
611        self.ser.0.sig_parser.skip_char()?;
612
613        key.serialize(&mut *self.ser)?;
614        self.ser.0.sig_parser = sig_parser;
615
616        Ok(())
617    }
618
619    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
620    where
621        T: ?Sized + Serialize,
622    {
623        // We want to keep parsing the same signature repeatedly for each key so we use a
624        // disposable clone.
625        let sig_parser = self.ser.0.sig_parser.clone();
626        self.ser.0.sig_parser = sig_parser.clone();
627
628        // skip `{` and key char
629        self.ser.0.sig_parser.skip_chars(2)?;
630
631        value.serialize(&mut *self.ser)?;
632        // Restore the original parser
633        self.ser.0.sig_parser = sig_parser;
634
635        Ok(())
636    }
637
638    fn end(self) -> Result<()> {
639        self.end_seq()
640    }
641}
642
643macro_rules! serialize_struct_named_fields {
644    ($trait:ident) => {
645        impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSerializer<'ser, 'sig, 'b, B, W>
646        where
647            B: byteorder::ByteOrder,
648            W: Write + Seek,
649        {
650            type Ok = ();
651            type Error = Error;
652
653            fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
654            where
655                T: ?Sized + Serialize,
656            {
657                self.serialize_struct_element(Some(key), value)
658            }
659
660            fn end(self) -> Result<()> {
661                self.end_struct()
662            }
663        }
664
665        impl<'ser, 'sig, 'b, B, W> ser::$trait for StructSeqSerializer<'ser, 'sig, 'b, B, W>
666        where
667            B: byteorder::ByteOrder,
668            W: Write + Seek,
669        {
670            type Ok = ();
671            type Error = Error;
672
673            fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
674            where
675                T: ?Sized + Serialize,
676            {
677                match self {
678                    StructSeqSerializer::Struct(ser) => ser.serialize_field(key, value),
679                    StructSeqSerializer::Seq(ser) => ser.serialize_element(value),
680                }
681            }
682
683            fn end(self) -> Result<()> {
684                match self {
685                    StructSeqSerializer::Struct(ser) => ser.end_struct(),
686                    StructSeqSerializer::Seq(ser) => ser.end_seq(),
687                }
688            }
689        }
690    };
691}
692serialize_struct_named_fields!(SerializeStruct);
693serialize_struct_named_fields!(SerializeStructVariant);