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: SignatureParser<'_> = 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);
694