feat(assets): implement AssetFile with seeking, buffering, and reading mechanics

This commit is contained in:
katR 2026-10-01 07:31:04 +05:30
parent 436be80d30
commit f07b5e7d6a
5 changed files with 90 additions and 0 deletions

View file

@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use super::types::{SEEK_CUR, SEEK_END, SEEK_SET};
use std::ffi::c_void;
pub struct AssetFile {
data: Vec<u8>,
cursor: usize,
}
impl AssetFile {
pub fn new(data: Vec<u8>) -> Self {
Self { data, cursor: 0 }
}
pub fn length(&self) -> i64 {
self.data.len() as i64
}
pub fn remaining_length(&self) -> i64 {
self.data.len().saturating_sub(self.cursor) as i64
}
pub fn get_buffer(&self) -> *const c_void {
self.data.as_ptr() as *const c_void
}
pub fn read(&mut self, buf: &mut [u8]) -> usize {
let available = self.data.len().saturating_sub(self.cursor);
let to_read = buf.len().min(available);
if to_read > 0 {
buf[..to_read].copy_from_slice(&self.data[self.cursor..self.cursor + to_read]);
self.cursor += to_read;
}
to_read
}
pub fn seek(&mut self, offset: i64, whence: i32) -> i64 {
let new_pos: i64 = match whence {
SEEK_SET => offset,
SEEK_CUR => self.cursor as i64 + offset,
SEEK_END => self.data.len() as i64 + offset,
_ => return -1,
};
if new_pos >= 0 && (new_pos as usize) <= self.data.len() {
self.cursor = new_pos as usize;
self.cursor as i64
} else {
-1
}
}
}

View file

@ -0,0 +1,3 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pub mod asset;
pub mod types;

View file

@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pub const AASSET_MODE_UNKNOWN: i32 = 0;
pub const AASSET_MODE_RANDOM: i32 = 1;
pub const AASSET_MODE_STREAMING: i32 = 2;
pub const AASSET_MODE_BUFFER: i32 = 3;
pub const SEEK_SET: i32 = 0;
pub const SEEK_CUR: i32 = 1;
pub const SEEK_END: i32 = 2;

View file

@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pub mod assets;
pub mod audio;
pub mod dynamic;
pub mod elf;

View file

@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later
use molotov_core::assets::asset::AssetFile;
#[test]
fn test_asset_read_and_seek_flow() {
let data = b"ROBLOX_ASSET_CONTENT_12345".to_vec();
let mut asset = AssetFile::new(data);
assert_eq!(asset.length(), 26);
assert_eq!(asset.remaining_length(), 26);
let mut buf = [0u8; 6];
assert_eq!(asset.read(&mut buf), 6);
assert_eq!(&buf, b"ROBLOX");
assert_eq!(asset.remaining_length(), 20);
// Seek to offset 7 (SEEK_SET = 0)
assert_eq!(asset.seek(7, 0), 7);
assert_eq!(asset.remaining_length(), 19);
let mut next_buf = [0u8; 5];
assert_eq!(asset.read(&mut next_buf), 5);
assert_eq!(&next_buf, b"ASSET");
}