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