diff --git a/src/syntatic/header.rs b/src/syntatic/header.rs index 7fe01fa..02841fa 100644 --- a/src/syntatic/header.rs +++ b/src/syntatic/header.rs @@ -1,11 +1,11 @@ +use std::mem::size_of; use super::Data; pub type HeaderDataSize = u32; pub type HeaderDataType = u16; pub type HeaderQueue = u8; -#[repr(packed)] // required for network exchange -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] /// The Header part of the Box. /// /// It can be copied or cloned cheaply. @@ -14,14 +14,14 @@ pub type HeaderQueue = u8; /// - data_type - unsigned 16 bit value used to inform the reader about the type of incoming Data /// - queue - unsigned 8 bit value used to inform the server to which queue use to handle the Box pub struct Header { - data_size: HeaderDataSize, // cannot access due to packed representation + data_size: HeaderDataSize, data_type: HeaderDataType, queue: HeaderQueue, } impl Header { /// Size of the Header in bytes. - pub const SIZE: usize = std::mem::size_of::
(); + pub const SIZE: usize = size_of::() + size_of::() + size_of::(); // getters needed due to packed representation of the struct @@ -75,13 +75,114 @@ impl Header { /// Same as `Header::into_array` impl Into<[u8; Header::SIZE]> for Header { fn into(self) -> [u8; Header::SIZE] { - unsafe { std::mem::transmute(self) } + let mut buffer = [0x00_u8; Header::SIZE]; + let buffer_ptr = buffer.as_mut_ptr(); + + let data_size_ptr = self.data_size.to_le_bytes().as_ptr(); + let data_type_ptr = self.data_type.to_le_bytes().as_ptr(); + let queue_ptr = self.queue.to_le_bytes().as_ptr(); + + let mut cursor = 0; + + unsafe { + copy_bytes_to( + data_size_ptr, + buffer_ptr, + size_of::(), + &mut cursor, + ); + + copy_bytes_to( + data_type_ptr, + buffer_ptr, + size_of::(), + &mut cursor, + ); + + copy_bytes_to( + queue_ptr, + buffer_ptr, + size_of::(), + &mut cursor, + ); + } + + buffer } } /// Same as `Header::from_array` impl From<[u8; Header::SIZE]> for Header { fn from(bytes: [u8; Header::SIZE]) -> Self { - unsafe { std::mem::transmute(bytes) } + let mut buffer_data_size = [0x00_u8; size_of::()]; + let mut buffer_data_type = [0x00_u8; size_of::()]; + let mut buffer_queue = [0x00_u8; size_of::()]; + + let bytes_ptr = bytes.as_ptr(); + + let mut cursor = 0; + + unsafe { + copy_bytes_from( + bytes_ptr, + buffer_data_size.as_mut_ptr(), + size_of::(), + &mut cursor, + ); + + copy_bytes_from( + bytes_ptr, + buffer_data_type.as_mut_ptr(), + size_of::(), + &mut cursor, + ); + + copy_bytes_from( + bytes_ptr, + buffer_queue.as_mut_ptr(), + size_of::(), + &mut cursor, + ); + } + + Self { + data_size: HeaderDataSize::from_le_bytes(buffer_data_size), + data_type: HeaderDataType::from_le_bytes(buffer_data_type), + queue: HeaderQueue::from_le_bytes(buffer_queue), + } } } + +/// Copies bytes into one specific buffer. +/// +/// # Args +/// - src - pointer to a byte array from which bytes will be copied +/// - dst - pointer to a buffer +/// - count - amount of bytes to copy from src (should be size_of src) +/// - cursor - cursor over the buffer +unsafe fn copy_bytes_to(src: *const u8, dst: *mut u8, count: usize, cursor: &mut usize) { + std::ptr::copy( + src, + dst.add(*cursor), + count + ); + + *cursor += count; +} + +/// Copies bytes from one specific array. +/// +/// # Args +/// - src - pointer to an array +/// - dst - pointer to a buffer into which bytes will be copied to +/// - count - amount of bytes to copy from src (should be size_of dst) +/// - cursor - cursor over the array +unsafe fn copy_bytes_from(src: *const u8, dst: *mut u8, count: usize, cursor: &mut usize) { + std::ptr::copy( + src.add(*cursor), + dst, + count + ); + + *cursor += count; +}