Skip to content

Commit 760d124

Browse files
committed
refactor: stop using loops in byte_order.rs
Instead of copying the buffers byte-by-byte in a loop, just use copy_from_slice, which compiles to a memcpy. Signed-off-by: Patrick Roy <[email protected]>
1 parent 6e28d9d commit 760d124

File tree

1 file changed

+27
-23
lines changed

1 file changed

+27
-23
lines changed

src/vmm/src/utils/byte_order.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ macro_rules! generate_read_fn {
55
($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => {
66
/// Read bytes from the slice
77
pub fn $fn_name(input: &[$byte_type]) -> $data_type {
8-
assert!($type_size == std::mem::size_of::<$data_type>());
9-
let mut array = [0u8; $type_size];
10-
#[allow(clippy::cast_sign_loss)]
11-
#[allow(clippy::cast_possible_wrap)]
12-
for (byte, read) in array.iter_mut().zip(input.iter().cloned()) {
13-
*byte = read as u8;
14-
}
8+
let mut array = [0u8; std::mem::size_of::<$data_type>()];
9+
let how_many = input.len().min(std::mem::size_of::<$data_type>());
10+
array[..how_many].copy_from_slice(&input[..how_many]);
1511
<$data_type>::$endian_type(array)
1612
}
1713
};
@@ -21,36 +17,46 @@ macro_rules! generate_write_fn {
2117
($fn_name: ident, $data_type: ty, $byte_type: ty, $endian_type: ident) => {
2218
/// Write bytes to the slice
2319
pub fn $fn_name(buf: &mut [$byte_type], n: $data_type) {
24-
#[allow(clippy::cast_sign_loss)]
25-
#[allow(clippy::cast_possible_wrap)]
26-
for (byte, read) in buf
27-
.iter_mut()
28-
.zip(<$data_type>::$endian_type(n).iter().cloned())
29-
{
30-
*byte = read as $byte_type;
31-
}
20+
let bytes = n.$endian_type();
21+
let how_much = buf.len().min(bytes.len());
22+
buf[..how_much].copy_from_slice(&bytes[..how_much]);
3223
}
3324
};
3425
}
3526

36-
generate_read_fn!(read_le_u16, u16, u8, 2, from_le_bytes);
3727
generate_read_fn!(read_le_u32, u32, u8, 4, from_le_bytes);
38-
generate_read_fn!(read_le_u32_from_i8, u32, i8, 4, from_le_bytes);
3928
generate_read_fn!(read_le_u64, u64, u8, 8, from_le_bytes);
40-
generate_read_fn!(read_le_i32, i32, i8, 4, from_le_bytes);
4129

4230
generate_read_fn!(read_be_u16, u16, u8, 2, from_be_bytes);
4331
generate_read_fn!(read_be_u32, u32, u8, 4, from_be_bytes);
4432

45-
generate_write_fn!(write_le_u16, u16, u8, to_le_bytes);
4633
generate_write_fn!(write_le_u32, u32, u8, to_le_bytes);
47-
generate_write_fn!(write_le_u32_to_i8, u32, i8, to_le_bytes);
4834
generate_write_fn!(write_le_u64, u64, u8, to_le_bytes);
49-
generate_write_fn!(write_le_i32, i32, i8, to_le_bytes);
5035

5136
generate_write_fn!(write_be_u16, u16, u8, to_be_bytes);
5237
generate_write_fn!(write_be_u32, u32, u8, to_be_bytes);
5338

39+
/// Reads a `u32` from a stream of `i8` by casting the input to `u8`s. If `input`
40+
/// is too small for reading an entire u32, the function pads it with zeros.
41+
pub fn read_le_u32_from_i8(input: &[i8]) -> u32 {
42+
let mut tmp = [0u8; std::mem::size_of::<u32>()];
43+
#[allow(clippy::cast_sign_loss)]
44+
tmp.iter_mut()
45+
.zip(input)
46+
.for_each(|(b_tmp, &b)| *b_tmp = b as u8);
47+
u32::from_le_bytes(tmp)
48+
}
49+
50+
/// Writes the given `u32` into the given buffer, casting the individual bytes to i8. If
51+
/// the buffer is too small to contain an entire u32, the function truncates and does
52+
/// a partial write.
53+
pub fn write_le_u32_to_i8(buf: &mut [i8], n: u32) {
54+
#[allow(clippy::cast_possible_wrap)]
55+
buf.iter_mut()
56+
.zip(n.to_le_bytes())
57+
.for_each(|(b_buf, b)| *b_buf = b as i8);
58+
}
59+
5460
#[cfg(test)]
5561
mod tests {
5662
use super::*;
@@ -110,10 +116,8 @@ mod tests {
110116
};
111117
}
112118

113-
byte_order_test_read_write!(test_le_u16, write_le_u16, read_le_u16, false, u16);
114119
byte_order_test_read_write!(test_le_u32, write_le_u32, read_le_u32, false, u32);
115120
byte_order_test_read_write!(test_le_u64, write_le_u64, read_le_u64, false, u64);
116-
byte_order_test_read_write!(test_le_i32, write_le_i32, read_le_i32, false, i32);
117121
byte_order_test_read_write!(test_be_u16, write_be_u16, read_be_u16, true, u16);
118122
byte_order_test_read_write!(test_be_u32, write_be_u32, read_be_u32, true, u32);
119123
}

0 commit comments

Comments
 (0)