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