Initial xenia-rs

This commit is contained in:
MechaCat02
2026-04-12 18:25:46 +02:00
parent 1da37db584
commit 06a23212fb
50 changed files with 6759 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
[package]
name = "xenia-vfs"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
xenia-types = { workspace = true }
tracing = { workspace = true }
byteorder = { workspace = true }
thiserror = { workspace = true }
anyhow = { workspace = true }

View File

@@ -0,0 +1,54 @@
use crate::{VfsDevice, VfsEntry, VfsError};
use std::path::{Path, PathBuf};
/// Host filesystem pass-through device.
pub struct HostPathDevice {
name: String,
root: PathBuf,
}
impl HostPathDevice {
pub fn new(name: impl Into<String>, root: impl AsRef<Path>) -> Self {
Self {
name: name.into(),
root: root.as_ref().to_path_buf(),
}
}
}
impl VfsDevice for HostPathDevice {
fn name(&self) -> &str {
&self.name
}
fn list_root(&self) -> Result<Vec<VfsEntry>, VfsError> {
let mut entries = Vec::new();
for entry in std::fs::read_dir(&self.root)? {
let entry = entry?;
let metadata = entry.metadata()?;
entries.push(VfsEntry {
name: entry.file_name().to_string_lossy().into_owned(),
is_directory: metadata.is_dir(),
size: metadata.len(),
offset: 0,
});
}
Ok(entries)
}
fn read_file(&self, path: &str) -> Result<Vec<u8>, VfsError> {
let full_path = self.root.join(path);
std::fs::read(&full_path).map_err(VfsError::from)
}
fn stat(&self, path: &str) -> Result<VfsEntry, VfsError> {
let full_path = self.root.join(path);
let metadata = std::fs::metadata(&full_path)?;
Ok(VfsEntry {
name: path.to_string(),
is_directory: metadata.is_dir(),
size: metadata.len(),
offset: 0,
})
}
}

View File

@@ -0,0 +1,40 @@
use crate::{VfsDevice, VfsEntry, VfsError};
/// XISO disc image device. Parses Xbox 360 disc images.
pub struct DiscImageDevice {
name: String,
_data: Vec<u8>,
}
/// XISO sector size
pub const SECTOR_SIZE: usize = 0x800;
impl DiscImageDevice {
pub fn open(name: impl Into<String>, path: &std::path::Path) -> Result<Self, VfsError> {
let data = std::fs::read(path)?;
// TODO: validate XISO header
Ok(Self {
name: name.into(),
_data: data,
})
}
}
impl VfsDevice for DiscImageDevice {
fn name(&self) -> &str {
&self.name
}
fn list_root(&self) -> Result<Vec<VfsEntry>, VfsError> {
// TODO: Parse XISO directory tree
Ok(Vec::new())
}
fn read_file(&self, _path: &str) -> Result<Vec<u8>, VfsError> {
Err(VfsError::NotFound("Not yet implemented".into()))
}
fn stat(&self, _path: &str) -> Result<VfsEntry, VfsError> {
Err(VfsError::NotFound("Not yet implemented".into()))
}
}

View File

@@ -0,0 +1,33 @@
pub mod device;
pub mod disc_image;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum VfsError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Invalid format: {0}")]
InvalidFormat(String),
#[error("File not found: {0}")]
NotFound(String),
}
/// A virtual filesystem entry (file or directory).
#[derive(Debug)]
pub struct VfsEntry {
pub name: String,
pub is_directory: bool,
pub size: u64,
pub offset: u64,
}
/// Trait for VFS device implementations (XISO, STFS, host path, etc.)
pub trait VfsDevice: Send + Sync {
fn name(&self) -> &str;
fn list_root(&self) -> Result<Vec<VfsEntry>, VfsError>;
fn read_file(&self, path: &str) -> Result<Vec<u8>, VfsError>;
fn stat(&self, path: &str) -> Result<VfsEntry, VfsError>;
}