use core::ffi::c_void;

use crate::{
    error::CUsizeResult,
    io::{managed::FILE, Read, Write},
    util::PointerExt,
};

#[no_mangle]
unsafe extern "C" fn fread(
    buf: *mut c_void,
    size: usize,
    nmemb: usize,
    fp: *mut FILE,
) -> CUsizeResult {
    let size = size.checked_mul(nmemb).expect("size * nmemb too large");
    let buf = buf.cast::<u8>().ensure_slice_mut(size);
    let fp = fp.ensure_mut();
    let len = fp.read(buf)?;
    CUsizeResult::success(len)
}

#[no_mangle]
unsafe extern "C" fn fwrite(
    buf: *const c_void,
    size: usize,
    nmemb: usize,
    fp: *mut FILE,
) -> CUsizeResult {
    let size = size.checked_mul(nmemb).expect("size * nmemb too large");
    let buf = buf.cast::<u8>().ensure_slice(size);
    let fp = fp.ensure_mut();
    let len = fp.write(buf)?;
    CUsizeResult::success(len)
}
