use std::io::{Read, Write};
use mcelp::{Encoder, FRAME, bitstream};
fn main() -> std::io::Result<()> {
let stdin = std::io::stdin();
let stdout = std::io::stdout();
encode_stream(stdin.lock(), std::io::BufWriter::new(stdout.lock()))
}
fn encode_stream(mut input: impl Read, mut output: impl Write) -> std::io::Result<()> {
let mut encoder = Encoder::new();
let mut block = [0u8; FRAME];
loop {
match input.read_exact(&mut block) {
Ok(()) => {
let frame = encoder.encode(&block);
output.write_all(bitstream::to_hex_line(&frame).as_bytes())?;
output.write_all(b"\n")?;
}
Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => break,
Err(error) => return Err(error),
}
}
output.flush()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn stream_matches_encoder_and_drops_a_partial_frame() {
let first = [0xff; FRAME];
let second = std::array::from_fn(|i| i as u8);
let mut input = Vec::from(first);
input.extend_from_slice(&second);
input.extend_from_slice(&[0; 17]);
let mut encoder = Encoder::new();
let mut expected = String::new();
for block in [&first, &second] {
expected.push_str(&bitstream::to_hex_line(&encoder.encode(block)));
expected.push('\n');
}
let mut output = Vec::new();
encode_stream(input.as_slice(), &mut output).unwrap();
assert_eq!(output, expected.as_bytes());
}
}