use std::collections::HashMap;
use std::io::{Cursor};
use crate::{
Result,
HeaderCoding,
ValueEncoder,
ValueDecoder,
};
use crate::{
FOOTER_IDENTIFIER_SEGMENT_FOOTER,
};
#[derive(Debug,Clone)]
pub struct SegmentFooter {
version: u8,
length_of_segment: u64,
object_header_offsets: HashMap<u64, u64>, object_footer_offsets: HashMap<u64, u64>, chunk_offsets: HashMap<u64, u64>, footer_offset: u64,
}
impl SegmentFooter {
pub fn new_empty(version: u8) -> SegmentFooter {
Self {
version,
length_of_segment: 0,
object_header_offsets: HashMap::new(),
object_footer_offsets: HashMap::new(),
chunk_offsets: HashMap::new(),
footer_offset: 0,
}
}
pub fn new(version: u8, length_of_segment: u64, object_header_offsets: HashMap<u64, u64>, object_footer_offsets: HashMap<u64, u64>, chunk_offsets: HashMap<u64, u64>, footer_offset: u64) -> SegmentFooter {
Self {
version,
length_of_segment,
object_header_offsets,
object_footer_offsets,
chunk_offsets,
footer_offset,
}
}
pub fn length_of_segment(&self) -> u64 {
self.length_of_segment
}
pub fn set_length_of_segment(&mut self, value: u64) {
self.length_of_segment = value
}
pub fn add_chunk_offset(&mut self, chunk_number: u64, offset: u64) {
self.chunk_offsets.insert(chunk_number, offset);
}
pub fn chunk_offsets(&self) -> &HashMap<u64, u64> {
&self.chunk_offsets
}
pub fn add_object_header_offset(&mut self, object_number: u64, offset: u64) {
self.object_header_offsets.insert(object_number, offset);
}
pub fn object_header_offsets(&self) -> &HashMap<u64, u64> {
&self.object_header_offsets
}
pub fn add_object_footer_offset(&mut self, object_number: u64, offset: u64) {
self.object_footer_offsets.insert(object_number, offset);
}
pub fn object_footer_offsets(&self) -> &HashMap<u64, u64> {
&self.object_footer_offsets
}
pub fn set_footer_offset(&mut self, offset: u64) {
self.footer_offset = offset;
}
}
impl HeaderCoding for SegmentFooter {
type Item = SegmentFooter;
fn identifier() -> u32 {
FOOTER_IDENTIFIER_SEGMENT_FOOTER
}
fn version(&self) -> u8 {
self.version
}
fn encode_header(&self) -> Vec<u8> {
let mut vec = Vec::new();
vec.append(&mut self.version.encode_directly());
vec.append(&mut self.length_of_segment.encode_directly());
vec.append(&mut self.object_header_offsets.encode_directly());
vec.append(&mut self.object_footer_offsets.encode_directly());
vec.append(&mut self.chunk_offsets.encode_directly());
vec.append(&mut self.footer_offset.encode_directly());
vec
}
fn decode_content(data: Vec<u8>) -> Result<SegmentFooter> {
let mut cursor = Cursor::new(data);
let footer_version = u8::decode_directly(&mut cursor)?;
let length_of_segment = u64::decode_directly(&mut cursor)?;
let object_header_offsets = HashMap::<u64, u64>::decode_directly(&mut cursor)?;
let object_footer_offsets = HashMap::<u64, u64>::decode_directly(&mut cursor)?;
let chunk_offsets = HashMap::<u64, u64>::decode_directly(&mut cursor)?;
let footer_offset = u64::decode_directly(&mut cursor)?;
Ok(SegmentFooter::new(footer_version, length_of_segment, object_header_offsets, object_footer_offsets, chunk_offsets, footer_offset))
}
}