use super::libc;
use core::ops::Shl;
use rand_core::{Error, RngCore, SeedableRng};
pub fn rand8(max_value: u8) -> u8 {
unsafe { libc::rand8(max_value) }
}
#[derive(Default)]
pub struct LibcRng {}
impl LibcRng {
pub fn new(seed: LibcSeed) -> Self {
unsafe { libc::srand(u32::from_ne_bytes(seed.0)) };
LibcRng::default()
}
}
impl RngCore for LibcRng {
fn next_u32(&mut self) -> u32 {
unsafe { libc::rand32(u32::MAX) }
}
fn next_u64(&mut self) -> u64 {
u64::from(self.next_u32()).shl(32) | u64::from(self.next_u32())
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
dest.iter_mut()
.for_each(|byte| *byte = unsafe { libc::rand8(u8::MAX) });
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.fill_bytes(dest);
Ok(())
}
}
#[derive(Default)]
pub struct LibcSeed(pub [u8; 4]);
impl AsMut<[u8]> for LibcSeed {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl SeedableRng for LibcRng {
type Seed = LibcSeed;
fn from_seed(seed: Self::Seed) -> Self {
LibcRng::new(seed)
}
}