1 use crate::{Handle, TipcError};
2 use core::fmt::Debug;
3 use core::{mem, slice};
4 
5 /// A helper provided by the transport handle for the message type to serialize
6 /// into.
7 ///
8 /// Borrows the serialized bytes with the `'s` lifetime, so data does not need
9 /// to be copied when sending a message.
10 ///
11 /// The serialization methods may be called multiple times, and the final
12 /// serialized data will be the concatenation of the sequences of bytes and
13 /// sequences of handles from these calls.
14 pub trait Serializer<'s> {
15     type Ok;
16     type Error: Debug;
17 
18     /// Serialize a sequence of bytes.
serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error>19     fn serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error>;
20 
21     /// Serialize a structure directly as raw bytes.
22     ///
23     /// Safety: The structure must have a well-defined layout (`repr(C,
24     /// packed)`) which exactly matches what the receiver expects. This may
25     /// serialize uninitialized memory if the structure contains padding, so a
26     /// packed structure without any padding is required to prevent accidental
27     /// disclosure of previous data.
serialize_as_bytes<T: Sized>(&mut self, obj: &'s T) -> Result<Self::Ok, Self::Error>28     unsafe fn serialize_as_bytes<T: Sized>(&mut self, obj: &'s T) -> Result<Self::Ok, Self::Error> {
29         let ptr = obj as *const _ as *const u8;
30         // SAFETY: Converting a repr(C) struct to a slice of bytes. obj is a
31         // reference of our serializer liftime, so explicitly assigning that
32         // lifetime to the resulting slice is safe.
33         let bytes: &'s [u8] = slice::from_raw_parts(&*ptr, mem::size_of::<T>());
34         self.serialize_bytes(bytes)
35     }
36 
37     /// Serialize a handle to be sent along with the message bytes.
38     ///
39     /// The handle is copied, and should remain open and valid until
40     /// serialization is complete and the message has been sent.
serialize_handle(&mut self, handle: &'s Handle) -> Result<Self::Ok, Self::Error>41     fn serialize_handle(&mut self, handle: &'s Handle) -> Result<Self::Ok, Self::Error>;
42 }
43 
44 /// A type that can serialize itself into a sequence of bytes and handles.
45 ///
46 /// Serialization is done using callbacks in the [`Serializer`] type to avoid
47 /// unnecessarily copying data.
48 pub trait Serialize<'s> {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>49     fn serialize<'a: 's, S: Serializer<'s>>(
50         &'a self,
51         serializer: &mut S,
52     ) -> Result<S::Ok, S::Error>;
53 }
54 
55 impl<'s> Serialize<'s> for u32 {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>56     fn serialize<'a: 's, S: Serializer<'s>>(
57         &'a self,
58         serializer: &mut S,
59     ) -> Result<S::Ok, S::Error> {
60         // SAFETY:
61         //  u32 is a trivial type with a
62         //  corresponding C representation
63         unsafe { serializer.serialize_as_bytes(self) }
64     }
65 }
66 
67 /// A type that can deserialize itself from a sequence of bytes and handles.
68 pub trait Deserialize: Sized {
69     type Error: From<TipcError> + Debug;
70 
71     /// The maximum amount of data that can be deserialized into this type.
72     ///
73     /// Buffering clients use this value to determine how large of a buffer
74     /// is required to receive a message that deserializes into this type.
75     ///
76     /// # Examples
77     ///
78     /// Allocate a stack buffer and receive a response type into it:
79     ///
80     /// ```
81     /// let mut buf = [0; Response::MAX_SERIALIZED_SIZE];
82     /// let response: Response = handle.recv(&mut buf)
83     ///                              .expect("Could not deserialize response");
84     /// ```
85     const MAX_SERIALIZED_SIZE: usize;
86 
87     /// Construct a new instance of this type from the provided bytes and
88     /// handles.
89     ///
90     /// The resulting value must be a copy of the data, if needed.
91     ///
92     /// The list of received handles is passed as a `&mut [Option<Handle>]` so
93     /// that you can use [`Option::take`] to take ownership of the handles. As
94     /// such, all values in `handles` will be `Some` when `deserialize` is
95     /// called.
deserialize(bytes: &[u8], handles: &mut [Option<Handle>]) -> Result<Self, Self::Error>96     fn deserialize(bytes: &[u8], handles: &mut [Option<Handle>]) -> Result<Self, Self::Error>;
97 }
98 
99 impl Deserialize for () {
100     type Error = TipcError;
101 
102     const MAX_SERIALIZED_SIZE: usize = 0;
103 
deserialize(_bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error>104     fn deserialize(_bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error> {
105         Ok(())
106     }
107 }
108