Wire --raw through InputOptions to streams

set_raw() on IsoStream and DiscStream sets keys to None.
open_input passes raw flag to streams via InputOptions.
Streams skip decrypt when raw=true.
This commit is contained in:
MattJackson
2026-04-15 01:38:18 +00:00
parent 31ba60b66f
commit 119d09ed02
3 changed files with 51 additions and 16 deletions
+5
View File
@@ -172,6 +172,11 @@ impl DiscStream {
} }
} }
/// Skip decryption — return raw encrypted bytes.
pub fn set_raw(&mut self) {
self.decrypt_keys = crate::decrypt::DecryptKeys::None;
}
/// Lock the tray. /// Lock the tray.
pub fn lock_tray(&mut self) { pub fn lock_tray(&mut self) {
self.drive.lock_tray(); self.drive.lock_tray();
+5
View File
@@ -220,6 +220,11 @@ impl IsoStream {
Ok(true) Ok(true)
} }
/// Skip decryption — return raw encrypted bytes.
pub fn set_raw(&mut self) {
self.decrypt_keys = DecryptKeys::None;
}
} }
impl IOStream for IsoStream { impl IOStream for IsoStream {
+40 -15
View File
@@ -14,7 +14,7 @@
//! //!
//! Bare paths without a scheme are rejected. //! Bare paths without a scheme are rejected.
use super::disc::{DiscOptions, DiscStream}; use super::disc::DiscStream;
use super::iso::IsoStream; use super::iso::IsoStream;
use super::network::NetworkStream; use super::network::NetworkStream;
use super::null::NullStream; use super::null::NullStream;
@@ -104,17 +104,25 @@ pub fn parse_url(url: &str) -> StreamUrl {
return if rest.is_empty() { return if rest.is_empty() {
StreamUrl::Disc { device: None } StreamUrl::Disc { device: None }
} else { } else {
StreamUrl::Disc { device: Some(PathBuf::from(rest)) } StreamUrl::Disc {
device: Some(PathBuf::from(rest)),
}
}; };
} }
if let Some(rest) = url.strip_prefix("m2ts://") { if let Some(rest) = url.strip_prefix("m2ts://") {
return StreamUrl::M2ts { path: PathBuf::from(rest) }; return StreamUrl::M2ts {
path: PathBuf::from(rest),
};
} }
if let Some(rest) = url.strip_prefix("mkv://") { if let Some(rest) = url.strip_prefix("mkv://") {
return StreamUrl::Mkv { path: PathBuf::from(rest) }; return StreamUrl::Mkv {
path: PathBuf::from(rest),
};
} }
if let Some(rest) = url.strip_prefix("network://") { if let Some(rest) = url.strip_prefix("network://") {
return StreamUrl::Network { addr: rest.to_string() }; return StreamUrl::Network {
addr: rest.to_string(),
};
} }
if url == "null://" || url.starts_with("null://") { if url == "null://" || url.starts_with("null://") {
return StreamUrl::Null; return StreamUrl::Null;
@@ -123,9 +131,13 @@ pub fn parse_url(url: &str) -> StreamUrl {
return StreamUrl::Stdio; return StreamUrl::Stdio;
} }
if let Some(rest) = url.strip_prefix("iso://") { if let Some(rest) = url.strip_prefix("iso://") {
return StreamUrl::Iso { path: PathBuf::from(rest) }; return StreamUrl::Iso {
path: PathBuf::from(rest),
};
}
StreamUrl::Unknown {
raw: url.to_string(),
} }
StreamUrl::Unknown { raw: url.to_string() }
} }
/// Validate that a file path is non-empty and has a filename component. /// Validate that a file path is non-empty and has a filename component.
@@ -139,7 +151,10 @@ fn validate_file_path(path: &Path, scheme: &str) -> io::Result<()> {
if path.file_name().is_none() { if path.file_name().is_none() {
return Err(io::Error::new( return Err(io::Error::new(
io::ErrorKind::InvalidInput, io::ErrorKind::InvalidInput,
format!("{scheme}://{} is not a valid file path — must include a filename", path.display()), format!(
"{scheme}://{} is not a valid file path — must include a filename",
path.display()
),
)); ));
} }
Ok(()) Ok(())
@@ -168,13 +183,17 @@ pub fn open_input(url: &str, opts: &InputOptions) -> io::Result<Box<dyn IOStream
match parsed { match parsed {
StreamUrl::Disc { device } => { StreamUrl::Disc { device } => {
let disc_opts = DiscOptions { let result = DiscStream::open(
device, device.as_deref(),
keydb_path: opts.keydb_path.as_ref().map(|p| p.into()), opts.keydb_path.as_deref(),
title_index: opts.title_index, opts.title_index.unwrap_or(0),
}; None,
let stream = DiscStream::open(disc_opts) )
.map_err(|e| io::Error::other(e.to_string()))?; .map_err(|e| io::Error::other(e.to_string()))?;
let mut stream = result.stream;
if opts.raw {
stream.set_raw();
}
Ok(Box::new(stream)) Ok(Box::new(stream))
} }
StreamUrl::M2ts { ref path } => { StreamUrl::M2ts { ref path } => {
@@ -206,7 +225,11 @@ pub fn open_input(url: &str, opts: &InputOptions) -> io::Result<Box<dyn IOStream
Some(p) => crate::disc::ScanOptions::with_keydb(p), Some(p) => crate::disc::ScanOptions::with_keydb(p),
None => crate::disc::ScanOptions::default(), None => crate::disc::ScanOptions::default(),
}; };
Ok(Box::new(IsoStream::open(&path.to_string_lossy(), opts.title_index, &scan_opts)?)) let mut stream = IsoStream::open(&path.to_string_lossy(), opts.title_index, &scan_opts)?;
if opts.raw {
stream.set_raw();
}
Ok(Box::new(stream))
} }
StreamUrl::Null => { StreamUrl::Null => {
Err(io::Error::new(io::ErrorKind::InvalidInput, Err(io::Error::new(io::ErrorKind::InvalidInput,
@@ -275,4 +298,6 @@ pub fn open_output(url: &str, meta: &DiscTitle) -> io::Result<Box<dyn IOStream>>
pub struct InputOptions { pub struct InputOptions {
pub keydb_path: Option<String>, pub keydb_path: Option<String>,
pub title_index: Option<usize>, pub title_index: Option<usize>,
/// Skip decryption — return raw encrypted bytes.
pub raw: bool,
} }