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