1use std::fmt::Display;
3use std::io::{Read, Seek, Write};
4use std::str::FromStr;
5
6use crate::headers::NitfSegmentHeader;
7use crate::types::{ExtendedSubheader, NitfField, Security};
8use crate::{NitfError, NitfResult};
9
10#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
12pub struct DataExtensionHeader {
13 pub de: NitfField<DE>,
15 pub desid: NitfField<String>,
17 pub desver: NitfField<u8>,
20 pub security: Security,
22 pub desoflw: NitfField<OverflowedHeaderType>,
24 pub desitem: NitfField<u16>,
26 pub desshl: NitfField<u16>,
28 pub desshf: ExtendedSubheader,
30}
31impl Default for DataExtensionHeader {
32 fn default() -> Self {
33 Self {
34 de: NitfField::init(2u8, "DE"),
35 desid: NitfField::init(25u8, "DESID"),
36 desver: NitfField::init(2u8, "DESVER"),
37 security: Security::default(),
38 desoflw: NitfField::init(6u8, "DESOFLW"),
39 desitem: NitfField::init(3u8, "DESITEM"),
40 desshl: NitfField::init(4u8, "DESSHL"),
41 desshf: ExtendedSubheader::init("DESSHF"),
42 }
43 }
44}
45impl NitfSegmentHeader for DataExtensionHeader {
46 fn read(&mut self, reader: &mut (impl Read + Seek)) -> NitfResult<()> {
47 self.de.read(reader)?;
48 self.desid.read(reader)?;
49 self.desver.read(reader)?;
50 self.security.read(reader)?;
51 if self.desid.val.trim() == "TRE_OVERFLOW" {
52 self.desoflw.read(reader)?;
53 self.desitem.read(reader)?;
54 }
55 self.desshl.read(reader)?;
56 if self.desshl.val != 0 {
57 self.desshf.read(reader, self.desshl.val as usize)?;
58 }
59 Ok(())
60 }
61 fn write(&self, writer: &mut (impl Write + Seek)) -> NitfResult<usize> {
62 let mut bytes_written = 0;
63 bytes_written += self.de.write(writer)?;
64 bytes_written += self.desid.write(writer)?;
65 bytes_written += self.desver.write(writer)?;
66 bytes_written += self.security.write(writer)?;
67 if self.desid.val.trim() == "TRE_OVERFLOW" {
68 bytes_written += self.desoflw.write(writer)?;
69 bytes_written += self.desitem.write(writer)?;
70 }
71 bytes_written += self.desshl.write(writer)?;
72 if self.desshl.val != 0 {
73 bytes_written += self.desshf.write(writer)?;
74 }
75 Ok(bytes_written)
76 }
77 fn length(&self) -> usize {
78 let mut length: usize = 0;
79 length += self.de.length;
80 length += self.desid.length;
81 length += self.desver.length;
82 length += self.security.length();
83 if self.desid.val.trim() == "TRE_OVERFLOW" {
84 length += self.desoflw.length;
85 length += self.desitem.length;
86 }
87 length += self.desshl.length;
88 length += self.desshf.size();
89 length
90 }
91}
92#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
93pub enum DE {
94 #[default]
95 DE,
96}
97impl FromStr for DE {
98 type Err = NitfError;
99 fn from_str(s: &str) -> Result<Self, Self::Err> {
100 match s {
101 "DE" => Ok(Self::default()),
102 _ => Err(NitfError::ParseError("DE".to_string())),
103 }
104 }
105}
106impl Display for DE {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 write!(f, "DE")
109 }
110}
111
112#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
114pub enum OverflowedHeaderType {
115 #[default]
116 IXSHD,
118 SXSHD,
120 TXSHD,
122 UDHD,
124 UDID,
126}
127impl Display for DataExtensionHeader {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 let mut out_str = String::default();
130 out_str += format!("{}, ", self.de).as_ref();
131 out_str += format!("{}, ", self.desid).as_ref();
132 out_str += format!("{}, ", self.desver).as_ref();
133 out_str += format!("SECURITY: [{}], ", self.security).as_ref();
134 out_str += format!("{}, ", self.desoflw).as_ref();
135 out_str += format!("{}, ", self.desitem).as_ref();
136 out_str += format!("{}, ", self.desshl).as_ref();
137 out_str += format!("{}", self.desshf).as_ref();
138 write!(f, "Data Extension Segment: [{out_str}]")
139 }
140}
141impl FromStr for OverflowedHeaderType {
142 type Err = NitfError;
143 fn from_str(s: &str) -> Result<Self, Self::Err> {
144 match s {
145 "IXSHD" => Ok(Self::IXSHD),
146 "SXSHD" => Ok(Self::SXSHD),
147 "TXSHD" => Ok(Self::TXSHD),
148 "UDHD" => Ok(Self::UDHD),
149 "UDID" => Ok(Self::UDID),
150 _ => Err(NitfError::ParseError("OverflowedHeaderType".to_string())),
151 }
152 }
153}
154impl Display for OverflowedHeaderType {
155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156 match self {
157 Self::IXSHD => write!(f, "IXSHD"),
158 Self::SXSHD => write!(f, "SXSHD"),
159 Self::TXSHD => write!(f, "TXSHD"),
160 Self::UDHD => write!(f, "UDHD"),
161 Self::UDID => write!(f, "UDID"),
162 }
163 }
164}