32 lines
1.0 KiB
Rust
32 lines
1.0 KiB
Rust
use std::ffi::c_void;
|
|
|
|
#[unsafe(no_mangle)]
|
|
unsafe fn vbu_realloc_shim(ptr: *mut c_void, new_size: usize) -> *mut c_void {
|
|
if !ptr.is_null() {
|
|
// not supporting proper realloc because it needs bookkeeping and it's unnecessary
|
|
return std::ptr::null_mut();
|
|
}
|
|
let allocation = vec![0u8; new_size].into_boxed_slice();
|
|
Box::into_raw(allocation).cast()
|
|
}
|
|
|
|
#[link(name = "vb")]
|
|
unsafe extern "C" {
|
|
#[link_name = "vbuFromISX"]
|
|
fn vbu_from_isx(bytes: *const c_void, length: usize, rom_length: *mut usize) -> *mut c_void;
|
|
}
|
|
|
|
pub fn rom_from_isx(bytes: &[u8]) -> Option<Vec<u8>> {
|
|
if !bytes.starts_with(b"ISX") {
|
|
return None;
|
|
}
|
|
let mut rom_length = 0;
|
|
let raw_rom = unsafe { vbu_from_isx(bytes.as_ptr().cast(), bytes.len(), &mut rom_length) };
|
|
if raw_rom.is_null() {
|
|
return None;
|
|
}
|
|
// SAFETY: the rom was allocated by vbu_realloc_shim, which created it from a Vec<u8>.
|
|
let rom = unsafe { Vec::from_raw_parts(raw_rom.cast(), rom_length, rom_length) };
|
|
Some(rom)
|
|
}
|