Skip to content

Commit 4461af8

Browse files
committed
cleanify block (de)serialize + reduce ClientId to u16
1 parent ecbe202 commit 4461af8

2 files changed

Lines changed: 31 additions & 19 deletions

File tree

lidi-protocol/src/lib.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
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
@@ -16,7 +16,7 @@
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 |
@@ -26,12 +26,11 @@
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
3635
use 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

257260
pub 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]

lidi-send/src/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::client;
44
use lidi_protocol as protocol;
55
use std::{io::Read, os::fd::AsRawFd, sync};
66

7-
static CLIENT_ID_COUNTER: sync::atomic::AtomicU32 = sync::atomic::AtomicU32::new(0);
7+
static CLIENT_ID_COUNTER: sync::atomic::AtomicU16 = sync::atomic::AtomicU16::new(0);
88

99
fn new_client_id() -> protocol::ClientId {
1010
CLIENT_ID_COUNTER.fetch_add(1, sync::atomic::Ordering::Relaxed)

0 commit comments

Comments
 (0)