use std::borrow::Borrow;
use std::io::{Cursor, Read, Seek, Write};
use self::write::BdatWriter;
use super::read::{BdatReader, BdatSlice};
use crate::error::Result;
use crate::table::modern::ModernTable;
use byteorder::ByteOrder;
#[allow(unused_imports)]
use crate::BdatFile;
mod read;
mod write;
pub use read::FileReader;
pub type ModernSlice<'a, E> = FileReader<BdatSlice<'a, E>, E>;
pub type ModernReader<R, E> = FileReader<BdatReader<R, E>, E>;
#[derive(Debug)]
pub(crate) struct FileHeader {
pub table_count: usize,
pub(crate) table_offsets: Vec<usize>,
}
pub fn from_reader<R: Read + Seek, E: ByteOrder>(
reader: R,
) -> Result<FileReader<BdatReader<R, E>, E>> {
FileReader::read_file(BdatReader::new(reader))
}
pub fn from_bytes<E: ByteOrder>(bytes: &[u8]) -> Result<FileReader<BdatSlice<'_, E>, E>> {
FileReader::read_file(BdatSlice::new(bytes))
}
pub fn to_writer<'t, W: Write + Seek, E: ByteOrder>(
writer: W,
tables: impl IntoIterator<Item = impl Borrow<ModernTable<'t>>>,
) -> Result<()> {
let mut writer = BdatWriter::<W, E>::new(writer);
writer.write_file(tables)
}
pub fn to_vec<'t, E: ByteOrder>(
tables: impl IntoIterator<Item = impl Borrow<ModernTable<'t>>>,
) -> Result<Vec<u8>> {
let mut vec = Vec::new();
to_writer::<_, E>(Cursor::new(&mut vec), tables)?;
Ok(vec)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::modern::{ModernColumn, ModernRow, ModernTableBuilder};
use crate::{io::SwitchEndian, BdatFile, Label, Value, ValueType};
#[test]
fn table_write_back() {
let table = ModernTableBuilder::with_name(Label::Hash(0xca_fe_ba_be))
.add_column(ModernColumn::new(
ValueType::HashRef,
Label::Hash(0xde_ad_be_ef),
))
.add_column(ModernColumn::new(
ValueType::UnsignedInt,
Label::Hash(0xca_fe_ca_fe),
))
.add_row(ModernRow::new(vec![
Value::HashRef(0x00_00_00_01),
Value::UnsignedInt(10),
]))
.add_row(ModernRow::new(vec![
Value::HashRef(0x01_00_00_01),
Value::UnsignedInt(100),
]))
.build();
let written = to_vec::<SwitchEndian>([&table]).unwrap();
let read_back = &from_bytes::<SwitchEndian>(&written)
.unwrap()
.get_tables()
.unwrap()[0];
assert_eq!(table, *read_back);
let new_written = to_vec::<SwitchEndian>([read_back]).unwrap();
assert_eq!(written, new_written);
}
}