use std::io::{self, Read};
use lzma_rust2::filter::bcj::BcjReader;
use lzma_rust2::filter::delta::DeltaReader;
use super::{Decoder, method};
pub struct BcjX86Decoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjX86Decoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjX86Decoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjX86Decoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_x86(input, 0),
}
}
pub fn new_with_start_pos(input: R, start_pos: usize) -> Self {
Self {
inner: BcjReader::new_x86(input, start_pos),
}
}
}
impl<R: Read + Send> Read for BcjX86Decoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjX86Decoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_X86
}
}
pub struct BcjArmDecoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjArmDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjArmDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjArmDecoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_arm(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjArmDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjArmDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_ARM
}
}
pub struct BcjArm64Decoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjArm64Decoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjArm64Decoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjArm64Decoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_arm64(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjArm64Decoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjArm64Decoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_ARM64
}
}
pub struct BcjArmThumbDecoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjArmThumbDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjArmThumbDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjArmThumbDecoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_arm_thumb(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjArmThumbDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjArmThumbDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_ARM_THUMB
}
}
pub struct BcjPpcDecoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjPpcDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjPpcDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjPpcDecoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_ppc(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjPpcDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjPpcDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_PPC
}
}
pub struct BcjSparcDecoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjSparcDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjSparcDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjSparcDecoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_sparc(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjSparcDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjSparcDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_SPARC
}
}
pub struct BcjIa64Decoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjIa64Decoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjIa64Decoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjIa64Decoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_ia64(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjIa64Decoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjIa64Decoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_IA64
}
}
pub struct BcjRiscvDecoder<R> {
inner: BcjReader<R>,
}
impl<R> std::fmt::Debug for BcjRiscvDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BcjRiscvDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> BcjRiscvDecoder<R> {
pub fn new(input: R) -> Self {
Self {
inner: BcjReader::new_riscv(input, 0),
}
}
}
impl<R: Read + Send> Read for BcjRiscvDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for BcjRiscvDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::BCJ_RISCV
}
}
pub struct DeltaDecoder<R> {
inner: DeltaReader<R>,
}
impl<R> std::fmt::Debug for DeltaDecoder<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DeltaDecoder").finish_non_exhaustive()
}
}
impl<R: Read + Send> DeltaDecoder<R> {
pub fn new(input: R, properties: &[u8]) -> Self {
let distance = properties.first().map(|b| *b as usize + 1).unwrap_or(1);
Self::new_with_distance(input, distance)
}
pub fn new_with_distance(input: R, distance: usize) -> Self {
Self {
inner: DeltaReader::new(input, distance),
}
}
}
impl<R: Read + Send> Read for DeltaDecoder<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<R: Read + Send> Decoder for DeltaDecoder<R> {
fn method_id(&self) -> &'static [u8] {
method::DELTA
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;
#[test]
fn test_bcj_x86_decoder_method_id() {
let data = vec![0u8; 16];
let decoder = BcjX86Decoder::new(Cursor::new(data));
assert_eq!(decoder.method_id(), method::BCJ_X86);
}
#[test]
fn test_delta_decoder_method_id() {
let data = vec![0u8; 16];
let decoder = DeltaDecoder::new(Cursor::new(data), &[0]);
assert_eq!(decoder.method_id(), method::DELTA);
}
#[test]
fn test_delta_decoder_distance_parsing() {
let data = vec![1, 2, 3, 4];
let mut decoder = DeltaDecoder::new(Cursor::new(data), &[0]);
let mut output = vec![0u8; 4];
decoder.read_exact(&mut output).unwrap();
assert_eq!(output, [1, 3, 6, 10]);
}
#[test]
fn test_delta_decoder_empty_properties() {
let data = vec![1, 1, 1, 1];
let mut decoder = DeltaDecoder::new(Cursor::new(data), &[]);
let mut output = vec![0u8; 4];
decoder.read_exact(&mut output).unwrap();
assert_eq!(output, [1, 2, 3, 4]);
}
}