use super::{LiteralsView, decode_literals_zerocopy};
use crate::blocks::literals_section::{LiteralsSection, LiteralsSectionType};
use crate::decoding::scratch::HuffmanScratch;
use alloc::vec::Vec;
fn raw_section(regen: u32) -> LiteralsSection {
LiteralsSection {
ls_type: LiteralsSectionType::Raw,
regenerated_size: regen,
compressed_size: None,
num_streams: None,
}
}
fn rle_section(regen: u32) -> LiteralsSection {
LiteralsSection {
ls_type: LiteralsSectionType::RLE,
regenerated_size: regen,
compressed_size: None,
num_streams: None,
}
}
fn fresh_scratch() -> HuffmanScratch {
HuffmanScratch::new()
}
#[test]
fn raw_truncated_source_returns_error_no_panic() {
let section = raw_section(10);
let source: [u8; 3] = [1, 2, 3];
let mut target: Vec<u8> = Vec::new();
let mut scratch = fresh_scratch();
let result = decode_literals_zerocopy(§ion, &mut scratch, None, &source, &mut target);
assert!(
result.is_err(),
"truncated raw source must error, not panic; got {:?}",
result.map(|_| ())
);
}
#[test]
fn rle_empty_source_returns_error_no_panic() {
let section = rle_section(10);
let source: [u8; 0] = [];
let mut target: Vec<u8> = Vec::new();
let mut scratch = fresh_scratch();
let result = decode_literals_zerocopy(§ion, &mut scratch, None, &source, &mut target);
assert!(
result.is_err(),
"empty RLE source must error, not panic; got {:?}",
result.map(|_| ())
);
}
#[test]
fn compressed_truncated_source_returns_error_no_panic() {
let section = LiteralsSection {
ls_type: LiteralsSectionType::Compressed,
regenerated_size: 5,
compressed_size: Some(10),
num_streams: Some(1),
};
let source: [u8; 3] = [1, 2, 3];
let mut target: Vec<u8> = Vec::new();
let mut scratch = fresh_scratch();
let result = decode_literals_zerocopy(§ion, &mut scratch, None, &source, &mut target);
assert!(
matches!(
&result,
Err(
crate::decoding::errors::DecompressLiteralsError::MissingBytesForLiterals {
got: 3,
needed: 10,
}
)
),
"truncated compressed source must report MissingBytesForLiterals, got {:?}",
result.map(|_| ())
);
}
#[test]
fn rle_view_excludes_pre_existing_target_bytes() {
let mut target: Vec<u8> = Vec::from([0xAA, 0xBB, 0xCC]);
let section = rle_section(4);
let source: [u8; 1] = [0x42];
let mut scratch = fresh_scratch();
let view = decode_literals_zerocopy(§ion, &mut scratch, None, &source, &mut target)
.expect("RLE with valid source must succeed");
assert_eq!(view.data.len(), 4, "view length must match regen_size");
assert!(
view.data.iter().all(|&b| b == 0x42),
"view must contain only the newly-RLE-expanded bytes, got {:?}",
view.data
);
let _ = LiteralsView {
data: view.data,
bytes_used: view.bytes_used,
};
}