44//! by the blocks structure. There are 5 block types:
55//! - `BlockType::Heartbeat` lets know the receiver that transfer can happen,
66//! - `BlockType::Start` informs the receiver that the sent data chunk represents the beginning of
7- //! a new transfer,
7+ //! a new transfer, including as data the encoded `EndpointId`,
88//! - `BlockType::Data` is used to send a data chunk that is not the beginning nor the ending of
99//! a transfer,
1010//! - `BlockType::Abort` informs the receiver that the current transfer has been aborted on the
1616//!
1717//! ```text
1818//!
19- //! <-- 4 bytes -> <-- 1 byte --> <-- 4 bytes -->
19+ //! <-- 2 bytes -> <-- 1 byte --> <-- 4 bytes -->
2020//! --------------+--------------+---------------+--------------------------------------
2121//! | | | | |
2222//! | client_id | block_type | data_length | payload = data + optional padding |
2626//!
2727//! ```
2828//!
29- //! 4-bytes values are encoded in little-endian byte order.
29+ //! byte values are encoded in little-endian byte order.
3030//!
3131//! In `Heartbeat` blocks, `client_id` is unused and should be set to 0 by the constructor
3232//! caller. Also no data payload should be provided by the constructor caller in case the block
33- //! is of type `Heartbeat`, `Abort` or `End`. Then the `data_length` will be set to 0 by the
34- //! block constructor and the data chunk will be fully padded with zeros.
33+ //! is of type `Heartbeat`, `Abort` or `End`. For `Start`, it contains only the encoded `EndpointId`.
3534
3635use std:: { fmt, io} ;
3736
@@ -250,9 +249,13 @@ impl fmt::Display for EndpointId {
250249 }
251250}
252251
253- pub type ClientId = u32 ;
252+ pub type ClientId = u16 ;
254253
255- const SERIALIZE_OVERHEAD : usize = 4 + 1 + 4 ;
254+ type DataLen = u32 ;
255+
256+ const BLOCK_TYPE_OFFSET : usize = size_of :: < ClientId > ( ) ;
257+ const DATA_LEN_OFFSET : usize = BLOCK_TYPE_OFFSET + 1 ;
258+ const SERIALIZE_OVERHEAD : usize = DATA_LEN_OFFSET + size_of :: < DataLen > ( ) ;
256259
257260pub struct Block {
258261 id : u8 ,
@@ -278,8 +281,10 @@ impl Block {
278281 ) -> Result < Self , Error > {
279282 let mut res = match recycle {
280283 Some ( mut res) => {
284+ const DATA_LEN : DataLen = 0 ;
281285 res. id = id;
282- res. data [ 5 ..9 ] . copy_from_slice ( & 0u32 . to_le_bytes ( ) ) ;
286+ res. data [ DATA_LEN_OFFSET ..DATA_LEN_OFFSET + size_of :: < DataLen > ( ) ]
287+ . copy_from_slice ( & DATA_LEN . to_le_bytes ( ) ) ;
283288 res
284289 }
285290 None => Self {
@@ -291,28 +296,32 @@ impl Block {
291296 ] ,
292297 } ,
293298 } ;
294- res. data [ 0 ..4 ] . copy_from_slice ( & client_id. to_le_bytes ( ) ) ;
295- res. data [ 4 ] = block. serialized ( ) ;
299+ res. data [ 0 ..size_of :: < ClientId > ( ) ] . copy_from_slice ( & client_id. to_le_bytes ( ) ) ;
300+ res. data [ BLOCK_TYPE_OFFSET ] = block. serialized ( ) ;
296301
297302 if let Some ( data) = data {
298303 let data_len = data. len ( ) ;
299- res. data [ 5 ..9 ] . copy_from_slice ( & u32:: to_le_bytes (
300- u32:: try_from ( data_len) . map_err ( |e| Error :: DataTooLarge ( e. to_string ( ) ) ) ?,
301- ) ) ;
302- res. data [ 9 ..9 + data_len] . copy_from_slice ( data) ;
304+ res. data [ DATA_LEN_OFFSET ..DATA_LEN_OFFSET + size_of :: < DataLen > ( ) ] . copy_from_slice (
305+ & DataLen :: to_le_bytes (
306+ DataLen :: try_from ( data_len) . map_err ( |e| Error :: DataTooLarge ( e. to_string ( ) ) ) ?,
307+ ) ,
308+ ) ;
309+ res. data [ SERIALIZE_OVERHEAD ..SERIALIZE_OVERHEAD + data_len] . copy_from_slice ( data) ;
303310 }
304311
305312 Ok ( res)
306313 }
307314
308315 #[ must_use]
309316 pub fn client_id ( & self ) -> ClientId {
310- u32:: from_le_bytes ( [ self . data [ 0 ] , self . data [ 1 ] , self . data [ 2 ] , self . data [ 3 ] ] )
317+ let mut client_id = [ 0u8 ; size_of :: < ClientId > ( ) ] ;
318+ client_id. copy_from_slice ( & self . data [ 0 ..size_of :: < ClientId > ( ) ] ) ;
319+ ClientId :: from_le_bytes ( client_id)
311320 }
312321
313322 pub fn block_type ( & self ) -> Result < BlockType , Error > {
314323 self . data
315- . get ( 4 )
324+ . get ( BLOCK_TYPE_OFFSET )
316325 . ok_or ( Error :: InvalidBlockType ( None ) )
317326 . and_then ( |b| match * b {
318327 ID_HEARTBEAT => Ok ( BlockType :: Heartbeat ) ,
@@ -324,8 +333,11 @@ impl Block {
324333 } )
325334 }
326335
327- fn payload_len ( & self ) -> u32 {
328- u32:: from_le_bytes ( [ self . data [ 5 ] , self . data [ 6 ] , self . data [ 7 ] , self . data [ 8 ] ] )
336+ fn payload_len ( & self ) -> DataLen {
337+ let mut data_len = [ 0u8 ; size_of :: < DataLen > ( ) ] ;
338+ data_len
339+ . copy_from_slice ( & self . data [ DATA_LEN_OFFSET ..DATA_LEN_OFFSET + size_of :: < DataLen > ( ) ] ) ;
340+ DataLen :: from_le_bytes ( data_len)
329341 }
330342
331343 #[ must_use]
0 commit comments