use std::fmt::Display;
use std::fs::File;
use crate::headers::NitfSegmentHeader;
use crate::types::{NitfField, Security, ExtendedSubheader};
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct NitfHeader {
pub fhdr: NitfField<String>,
pub fver: NitfField<String>,
pub clevel: NitfField<u8>,
pub stype: NitfField<String>,
pub ostaid: NitfField<String>,
pub fdt: NitfField<String>,
pub ftitle: NitfField<String>,
pub security: Security,
pub fscop: NitfField<u32>,
pub fscpys: NitfField<u32>,
pub encryp: NitfField<String>,
pub fbkgc: Vec<NitfField<String>>, pub oname: NitfField<String>,
pub ophone: NitfField<String>,
pub fl: NitfField<u64>,
pub hl: NitfField<u32>,
pub numi: NitfField<u16>,
pub imheaders: Vec<SubHeader>,
pub nums: NitfField<u16>,
pub graphheaders: Vec<SubHeader>,
pub numx: NitfField<u16>,
pub numt: NitfField<u16>,
pub textheaders: Vec<SubHeader>,
pub numdes: NitfField<u16>,
pub dextheaders: Vec<SubHeader>,
pub numres: NitfField<u16>,
pub resheaders: Vec<SubHeader>,
pub udhdl: NitfField<u32>,
pub udhofl: NitfField<u16>,
pub udhd: ExtendedSubheader, pub xhdl: NitfField<u32>,
pub xhdlofl: NitfField<u16>,
pub xhd: ExtendedSubheader,
}
impl Display for NitfHeader {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut out_str = String::default();
out_str += format!("FHDR: {}, ", self.fhdr).as_ref();
out_str += format!("FVER: {}, ", self.fver).as_ref();
out_str += format!("CLEVEL: {}, ", self.clevel).as_ref();
out_str += format!("STYPE: {}, ", self.stype).as_ref();
out_str += format!("OSTAID: {}, ", self.ostaid).as_ref();
out_str += format!("FDT: {}, ", self.fdt).as_ref();
out_str += format!("FTITLE: {}, ", self.ftitle).as_ref();
out_str += format!("SECURITY: [{}], ", self.security).as_ref();
out_str += format!("FSCOP: {}, ", self.fscop).as_ref();
out_str += format!("FSCPYS: {}, ", self.fscpys).as_ref();
out_str += format!("ENCRYP: {}, ", self.encryp).as_ref();
out_str += format!(
"FBKGC: [R: {}, G: {}, B: {}], ",
self.fbkgc[0], self.fbkgc[1], self.fbkgc[2],
)
.as_ref();
out_str += format!("ONAME: {}, ", self.oname).as_ref();
out_str += format!("OPHONE: {}, ", self.ophone).as_ref();
out_str += format!("FL: {}, ", self.fl).as_ref();
out_str += format!("HL: {}, ", self.hl).as_ref();
out_str += format!("NUMI: {}, ", self.numi).as_ref();
for seg in &self.imheaders {
out_str += format!("[IMHEADER: {}], ", seg).as_ref()
}
out_str += format!("NUMS: {}, ", self.nums).as_ref();
for seg in &self.graphheaders {
out_str += format!("[GRAPHHEADERS: {}], ", seg).as_ref()
}
out_str += format!("NUMX: {}, ", self.numx).as_ref();
out_str += format!("NUMT: {}, ", self.numt).as_ref();
for seg in &self.textheaders {
out_str += format!("[TEXTHEADER: {}], ", seg).as_ref()
}
out_str += format!("NUMDES: {}, ", self.numdes).as_ref();
for seg in &self.dextheaders {
out_str += format!("[DEXTHEADER: {}], ", seg).as_ref()
}
out_str += format!("NUMRES: {}, ", self.numres).as_ref();
for seg in &self.resheaders {
out_str += format!("[RESHEADER: {}], ", seg).as_ref()
}
out_str += format!("UDHDL: {}, ", self.udhdl).as_ref();
out_str += format!("UDHOFL: {}, ", self.udhofl).as_ref();
out_str += format!("UDHD: {}, ", self.udhd).as_ref();
out_str += format!("XHDL: {}, ", self.xhdl).as_ref();
out_str += format!("XHDLOFL: {}, ", self.xhdlofl).as_ref();
out_str += format!("XHD: {}", self.xhd).as_ref();
write!(f, "[NitfHeader: {out_str}]")
}
}
impl NitfSegmentHeader for NitfHeader {
fn read(&mut self, reader: &mut File) {
self.fhdr.read(reader, 4u8);
self.fver.read(reader, 5u8);
self.clevel.read(reader, 2u8);
self.stype.read(reader, 4u8);
self.ostaid.read(reader, 10u8);
self.fdt.read(reader, 14u8);
self.ftitle.read(reader, 80u8);
self.security.read(reader);
self.fscop.read(reader, 5u8);
self.fscpys.read(reader, 5u8);
self.encryp.read(reader, 1u8);
for _ in 0..3 {
let mut color: NitfField<String> = NitfField::default();
color.read(reader, 1u8);
self.fbkgc.push(color);
}
self.oname.read(reader, 24u8);
self.ophone.read(reader, 18u8);
self.fl.read(reader, 12u8);
self.hl.read(reader, 6u8);
self.numi.read(reader, 3u8);
for _ in 0..self.numi.val {
let mut subheader = SubHeader::default();
subheader.read(reader, 6, 10);
self.imheaders.push(subheader);
}
self.nums.read(reader, 3u8);
for _ in 0..self.nums.val {
let mut subheader = SubHeader::default();
subheader.read(reader, 4, 6);
self.graphheaders.push(subheader);
}
self.numx.read(reader, 3u8);
self.numt.read(reader, 3u8);
for _ in 0..self.numt.val {
let mut subheader = SubHeader::default();
subheader.read(reader, 4, 5);
self.textheaders.push(subheader);
}
self.numdes.read(reader, 3u8);
for _ in 0..self.numdes.val {
let mut subheader = SubHeader::default();
subheader.read(reader, 4, 9);
self.dextheaders.push(subheader);
}
self.numres.read(reader, 3u8);
for _ in 0..self.numres.val {
let mut subheader = SubHeader::default();
subheader.read(reader, 4, 7);
self.resheaders.push(subheader);
}
self.udhdl.read(reader, 5u8);
if self.udhdl.val != 0 {
self.udhofl.read(reader, 3u8);
self.udhd.read(reader, (self.udhdl.val - 3) as usize);
}
self.xhdl.read(reader, 5u8);
if self.xhdl.val != 0 {
self.xhdlofl.read(reader, 3u8);
self.xhd.read(reader, (self.xhdl.val - 3) as usize);
}
}
}
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct SubHeader {
pub subheader_size: NitfField<u32>,
pub item_size: NitfField<u64>,
}
impl SubHeader {
pub fn read(&mut self, reader: &mut File, sh_size: u64, item_size: u64) {
self.subheader_size.read(reader, sh_size);
self.item_size.read(reader, item_size);
}
}
impl Display for SubHeader {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"[subheader_size: {}, item_size: {}]",
&self.subheader_size.string, &self.item_size.string
)
}
}