Spaces:
Runtime error
Runtime error
| use std::alloc; | |
| extern "C" { | |
| fn ZSTD_createDStream() -> u32; | |
| fn ZSTD_freeDStream(ctx: u32) -> i32; | |
| fn ZSTD_decompressStream_simpleArgs( | |
| ctx: u32, | |
| dst: *mut u8, | |
| dstCapacity: u32, | |
| dstPos: *mut u32, | |
| src: *const u8, | |
| srcSize: u32, | |
| srcPos: *mut u32, | |
| ) -> i32; | |
| fn ZSTD_isError(err: i32) -> bool; | |
| } | |
| const MALLOC_ALIGN: usize = 16; | |
| // malloc and free are needed by the zstd library | |
| pub unsafe fn v86_malloc(size: u32) -> u32 { | |
| let layout = alloc::Layout::from_size_align(size as usize + 4, MALLOC_ALIGN).unwrap(); | |
| let addr = alloc::alloc(layout); | |
| *(addr as *mut u32) = size as u32; | |
| addr as u32 + 4 | |
| } | |
| pub unsafe fn v86_free(addr: u32) { | |
| let size = *((addr - 4) as *mut u32); | |
| let layout = alloc::Layout::from_size_align(size as usize + 4, MALLOC_ALIGN).unwrap(); | |
| alloc::dealloc((addr - 4) as *mut u8, layout) | |
| } | |
| pub struct ZstdContext { | |
| ctx: u32, | |
| src: *mut u8, | |
| src_size: u32, | |
| src_pos: u32, | |
| } | |
| pub unsafe fn zstd_create_ctx(src_size: u32) -> *mut ZstdContext { | |
| let src = alloc::alloc(alloc::Layout::from_size_align(src_size as usize, 1).unwrap()); | |
| let ctx = ZSTD_createDStream(); | |
| let result = alloc::alloc(alloc::Layout::new::<ZstdContext>()) as *mut ZstdContext; | |
| *result = ZstdContext { | |
| ctx, | |
| src, | |
| src_size, | |
| src_pos: 0, | |
| }; | |
| result | |
| } | |
| pub unsafe fn zstd_get_src_ptr(ctx: *mut ZstdContext) -> *mut u8 { (*ctx).src } | |
| pub unsafe fn zstd_free_ctx(ctx: *mut ZstdContext) { | |
| alloc::dealloc( | |
| (*ctx).src, | |
| alloc::Layout::from_size_align((*ctx).src_size as usize, 1).unwrap(), | |
| ); | |
| ZSTD_freeDStream((*ctx).ctx); | |
| std::ptr::drop_in_place(ctx); | |
| } | |
| pub unsafe fn zstd_read(ctx: *mut ZstdContext, length: u32) -> *mut u8 { | |
| let dst = alloc::alloc(alloc::Layout::from_size_align(length as usize, 1).unwrap()); | |
| let mut dst_pos = 0; | |
| let result = ZSTD_decompressStream_simpleArgs( | |
| (*ctx).ctx, | |
| dst, | |
| length, | |
| &mut dst_pos, | |
| (*ctx).src, | |
| (*ctx).src_size, | |
| &mut (*ctx).src_pos, | |
| ); | |
| if ZSTD_isError(result) { | |
| dbg_log!( | |
| "ZSTD_decompressStream_simpleArgs returned error: {}", | |
| result | |
| ); | |
| dbg_assert!(false); | |
| zstd_read_free(dst, length); | |
| return std::ptr::null_mut::<u8>(); | |
| } | |
| if dst_pos != length { | |
| dbg_assert!(false, "ZSTD: Partial read"); | |
| zstd_read_free(dst, length); | |
| return std::ptr::null_mut::<u8>(); | |
| } | |
| dst | |
| } | |
| pub unsafe fn zstd_read_free(ptr: *mut u8, length: u32) { | |
| alloc::dealloc( | |
| ptr, | |
| alloc::Layout::from_size_align(length as usize, 1).unwrap(), | |
| ); | |
| } | |