1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
pub mod file_hash;

#[cfg(test)]
extern crate std;

mod sixty_four;

#[cfg(feature = "std")]
mod std_support;
#[cfg(feature = "std")]
pub use std_support::sixty_four::RandomXxHashBuilder64;
#[cfg(feature = "std")]
pub use std_support::thirty_two::RandomXxHashBuilder32;

#[cfg(feature = "digest")]
mod digest_support;

pub use crate::sixty_four::XxHash64;

#[cfg(feature = "std")]
/// A backwards compatibility type alias. Consider directly using
/// `RandomXxHashBuilder64` instead.
pub type RandomXxHashBuilder = RandomXxHashBuilder64;

trait TransmutingByteSlices {
    fn as_u64_arrays(&self) -> (&[u8], &[[u64; 4]], &[u8]);
    fn as_u64s(&self) -> (&[u8], &[u64], &[u8]);
    fn as_u32_arrays(&self) -> (&[u8], &[[u32; 4]], &[u8]);
    fn as_u32s(&self) -> (&[u8], &[u32], &[u8]);
}

// # Safety
//
// - Interpreting a properly-aligned set of bytes as a `u64` should be
//   valid.
// - `align_to` guarantees to only transmute aligned data.
// - An array is a tightly-packed set of bytes (as shown by `impl
//   TryFrom<&[u8]> for &[u8; N]`)
impl TransmutingByteSlices for [u8] {
    fn as_u64_arrays(&self) -> (&[u8], &[[u64; 4]], &[u8]) {
        unsafe { self.align_to::<[u64; 4]>() }
    }

    fn as_u64s(&self) -> (&[u8], &[u64], &[u8]) {
        unsafe { self.align_to::<u64>() }
    }

    fn as_u32_arrays(&self) -> (&[u8], &[[u32; 4]], &[u8]) {
        unsafe { self.align_to::<[u32; 4]>() }
    }

    fn as_u32s(&self) -> (&[u8], &[u32], &[u8]) {
        unsafe { self.align_to::<u32>() }
    }
}