feat(assets): implement AssetFile with seeking, buffering, and reading mechanics
This commit is contained in:
parent
436be80d30
commit
f07b5e7d6a
5 changed files with 90 additions and 0 deletions
52
crates/molotov-core/src/assets/asset.rs
Normal file
52
crates/molotov-core/src/assets/asset.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
crates/molotov-core/src/assets/mod.rs
Normal file
3
crates/molotov-core/src/assets/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
pub mod asset;
|
||||||
|
pub mod types;
|
||||||
10
crates/molotov-core/src/assets/types.rs
Normal file
10
crates/molotov-core/src/assets/types.rs
Normal 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;
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
pub mod assets;
|
||||||
pub mod audio;
|
pub mod audio;
|
||||||
pub mod dynamic;
|
pub mod dynamic;
|
||||||
pub mod elf;
|
pub mod elf;
|
||||||
|
|
|
||||||
24
crates/molotov-core/tests/asset_read_test.rs
Normal file
24
crates/molotov-core/tests/asset_read_test.rs
Normal 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");
|
||||||
|
}
|
||||||
Reference in a new issue