use std::collections::HashMap;
use crate::file_group::log_file::log_block::{BlockMetadataKey, BlockType};
use crate::file_group::log_file::log_format::MAGIC;
pub struct LogFileWriter;
impl LogFileWriter {
pub fn write_log_block(
block_type: BlockType,
header: HashMap<BlockMetadataKey, String>,
content: &[u8],
) -> Vec<u8> {
write_log_block(block_type, header, content)
}
}
pub fn write_log_block(
block_type: BlockType,
header: HashMap<BlockMetadataKey, String>,
content: &[u8],
) -> Vec<u8> {
let mut payload = Vec::new();
payload.extend_from_slice(&1u32.to_be_bytes());
payload.extend_from_slice(&(block_type as u32).to_be_bytes());
write_metadata(&mut payload, header);
payload.extend_from_slice(&(content.len() as u64).to_be_bytes());
payload.extend_from_slice(content);
payload.extend_from_slice(&0u32.to_be_bytes());
let block_length = (payload.len() + 8) as u64;
let footer_length = block_length + MAGIC.len() as u64;
let mut output = Vec::with_capacity(MAGIC.len() + 8 + payload.len() + 8);
output.extend_from_slice(MAGIC);
output.extend_from_slice(&block_length.to_be_bytes());
output.extend_from_slice(&payload);
output.extend_from_slice(&footer_length.to_be_bytes());
output
}
fn write_metadata(output: &mut Vec<u8>, metadata: HashMap<BlockMetadataKey, String>) {
output.extend_from_slice(&(metadata.len() as u32).to_be_bytes());
for (key, value) in metadata {
output.extend_from_slice(&(key as u32).to_be_bytes());
output.extend_from_slice(&(value.len() as u32).to_be_bytes());
output.extend_from_slice(value.as_bytes());
}
}