Skip to content

Commit 7d8fcb9

Browse files
authored
block-buffer: improve split_blocks implementations (#1220)
This PR simplifies implementations and removes `unsafe` by leveraging `Array::slice_as_chunks`. The resulting code is still panic-free, as can be seen here: https://rust.godbolt.org/z/43xMT3ExP
1 parent 16c3b91 commit 7d8fcb9

File tree

1 file changed

+7
-30
lines changed

1 file changed

+7
-30
lines changed

block-buffer/src/sealed.rs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use hybrid_array::sizes::{U0, U1};
22

33
use super::{Array, ArraySize};
4-
use core::{mem::MaybeUninit, ptr, slice};
4+
use core::{mem::MaybeUninit, ptr};
55

66
type Block<N> = MaybeUninit<Array<u8, N>>;
77

@@ -60,18 +60,7 @@ impl Sealed for super::Eager {
6060

6161
#[inline(always)]
6262
fn split_blocks<N: ArraySize>(data: &[u8]) -> (&[Array<u8, N>], &[u8]) {
63-
let nb = data.len() / N::USIZE;
64-
let blocks_len = nb * N::USIZE;
65-
let tail_len = data.len() - blocks_len;
66-
// SAFETY: we guarantee that created slices do not point outside of `data`
67-
unsafe {
68-
let blocks_ptr = data.as_ptr() as *const Array<u8, N>;
69-
let tail_ptr = data.as_ptr().add(blocks_len);
70-
(
71-
slice::from_raw_parts(blocks_ptr, nb),
72-
slice::from_raw_parts(tail_ptr, tail_len),
73-
)
74-
}
63+
Array::slice_as_chunks(data)
7564
}
7665
}
7766

@@ -96,24 +85,12 @@ impl Sealed for super::Lazy {
9685

9786
#[inline(always)]
9887
fn split_blocks<N: ArraySize>(data: &[u8]) -> (&[Array<u8, N>], &[u8]) {
99-
if data.is_empty() {
100-
return (&[], &[]);
101-
}
102-
let (nb, tail_len) = if data.len() % N::USIZE == 0 {
103-
(data.len() / N::USIZE - 1, N::USIZE)
88+
let (blocks, tail) = Array::slice_as_chunks(data);
89+
if data.is_empty() || !tail.is_empty() {
90+
(blocks, tail)
10491
} else {
105-
let nb = data.len() / N::USIZE;
106-
(nb, data.len() - nb * N::USIZE)
107-
};
108-
let blocks_len = nb * N::USIZE;
109-
// SAFETY: we guarantee that created slices do not point outside of `data`
110-
unsafe {
111-
let blocks_ptr = data.as_ptr() as *const Array<u8, N>;
112-
let tail_ptr = data.as_ptr().add(blocks_len);
113-
(
114-
slice::from_raw_parts(blocks_ptr, nb),
115-
slice::from_raw_parts(tail_ptr, tail_len),
116-
)
92+
let (tail, blocks) = blocks.split_last().expect("`blocks` can not be empty");
93+
(blocks, tail)
11794
}
11895
}
11996
}

0 commit comments

Comments
 (0)