You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.3 KiB

extern crate getrandom;
use getrandom::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let mut f: f64 = 0.0;
assert_eq!(sample(&mut f as *mut f64), 1);
}
#[test]
fn bytes_works() {
let mut buf: [u8; 16] = [0; 16];
assert_eq!(bytes(&mut buf[0] as *mut u8, 16), 1);
}
}
fn get<T: Default>() -> Result<T, Error>
{
let mut value: T = Default::default();
unsafe {
let mut slice = std::slice::from_raw_parts_mut(&mut value as *mut T as *mut u8, std::mem::size_of::<T>());
populate(&mut slice)?;
}
Ok(value)
}
fn double() -> Result<f64, Error>
{
let long: i64 = get::<i64>()?;
Ok( ((long & ((1i64 << 53) - 1)) as f64) * (1_f64 / ((1_i64 << 53) as f64)))
}
fn populate(mut value: &mut [u8]) -> Result<(), Error>
{
getrandom(&mut value)?;
Ok(())
}
#[no_mangle]
pub extern "C" fn sample(value: *mut f64) -> i32
{
match std::panic::catch_unwind(|| {
unsafe {
match double() {
Ok(x) => *value = x,
Err(_) => return 0,
}
}
1
}) {
Ok(v) => v,
Err(_) => 0,
}
}
#[no_mangle]
pub extern "C" fn bytes(value: *mut u8, size: i32) -> i32
{
let mut buf: &mut [u8];
if size < 0 {
return 0
}
unsafe {
buf = std::slice::from_raw_parts_mut(value, size as usize);
}
match getrandom(&mut buf) {
Ok(_) => 1,
Err(_) => 0,
}
}