use std::io::{Read, Write};
use crate::bottle::{BottleReader, BottleStream, BottleWriter};
use crate::bottle_error::{BottleError, BottleResult};
use crate::header::Header;
const MAGIC: [u8; 4] = [ 0xf0, 0x9f, 0x97, 0x83 ];
pub fn write_header_stream<W: Write>(bottle_writer: &mut BottleWriter<W>, header: &Header) -> BottleResult<()> {
let mut prefix = [0u8; 8];
prefix[0..4].copy_from_slice(&MAGIC);
prefix[4..8].copy_from_slice(&crc32c::crc32c(&header.data).to_le_bytes());
bottle_writer.write_data_stream()?;
bottle_writer.write_all(&prefix)?;
bottle_writer.write_all(header.pack())?;
bottle_writer.close_stream()
}
pub fn read_header_stream<R: Read>(bottle_reader: &mut BottleReader<R>) -> BottleResult<Header> {
bottle_reader.expect_next_stream(BottleStream::Data)?;
let mut buffer = Vec::new();
bottle_reader.data_stream()?.read_to_end(&mut buffer)?;
bottle_reader.close_stream()?;
let mut start = 0;
if buffer[0] == 0xf0 {
if !&buffer[0..4].eq(&MAGIC) {
return Err(BottleError::BadMagic);
}
let crc = u32::from_le_bytes(buffer[4..8].try_into().unwrap());
let my_crc = crc32c::crc32c(&buffer[8..]);
if crc != my_crc {
return Err(BottleError::BadCrc { expected: my_crc, got: crc });
}
start += 8;
}
let mut header = Header::new();
header.data.extend_from_slice(&buffer[start..]);
Ok(header)
}