#![forbid(unsafe_code)]
#![allow(clippy::cast_possible_truncation)]
pub fn write_chunk(out: &mut Vec<u8>, fourcc: &[u8; 4], payload: &[u8]) {
out.extend_from_slice(fourcc);
let size = payload.len() as u32;
out.extend_from_slice(&size.to_le_bytes());
out.extend_from_slice(payload);
if payload.len() % 2 == 1 {
out.push(0); }
}
pub fn write_list(out: &mut Vec<u8>, list_type: &[u8; 4], payload: &[u8]) {
let total = 4u32 + payload.len() as u32; out.extend_from_slice(b"LIST");
out.extend_from_slice(&total.to_le_bytes());
out.extend_from_slice(list_type);
out.extend_from_slice(payload);
}
pub fn patch_u32_le(buf: &mut [u8], offset: usize, value: u32) {
buf[offset..offset + 4].copy_from_slice(&value.to_le_bytes());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn write_chunk_even_payload() {
let mut out = Vec::new();
write_chunk(&mut out, b"data", &[1u8, 2, 3, 4]);
assert_eq!(out.len(), 12);
assert_eq!(&out[0..4], b"data");
assert_eq!(u32::from_le_bytes([out[4], out[5], out[6], out[7]]), 4);
assert_eq!(&out[8..12], &[1, 2, 3, 4]);
}
#[test]
fn write_chunk_odd_payload() {
let mut out = Vec::new();
write_chunk(&mut out, b"test", &[0xABu8]);
assert_eq!(out.len(), 10);
assert_eq!(u32::from_le_bytes([out[4], out[5], out[6], out[7]]), 1);
assert_eq!(out[8], 0xAB);
assert_eq!(out[9], 0x00); }
#[test]
fn write_list_structure() {
let payload = b"abcd";
let mut out = Vec::new();
write_list(&mut out, b"hdrl", payload);
assert_eq!(out.len(), 16);
assert_eq!(&out[0..4], b"LIST");
assert_eq!(u32::from_le_bytes([out[4], out[5], out[6], out[7]]), 8);
assert_eq!(&out[8..12], b"hdrl");
assert_eq!(&out[12..16], b"abcd");
}
#[test]
fn patch_u32_le_works() {
let mut buf = vec![0u8; 8];
patch_u32_le(&mut buf, 2, 0xDEAD_BEEFu32);
assert_eq!(&buf[2..6], &[0xEF, 0xBE, 0xAD, 0xDE]);
}
}