1use std::fmt::Display;
3use std::io::{Read, Seek, Write};
4
5use std::str::FromStr;
6
7use crate::headers::NitfSegmentHeader;
8use crate::types::{ExtendedSubheader, NitfField, Security};
9use crate::{NitfError, NitfResult};
10#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
12pub struct TextHeader {
13 pub te: NitfField<TE>,
15 pub textid: NitfField<String>,
17 pub txtalvl: NitfField<u16>,
19 pub txtdt: NitfField<String>,
21 pub txttitl: NitfField<String>,
23 pub security: Security,
25 pub encryp: NitfField<String>,
27 pub txtfmt: NitfField<TextFormat>,
29 pub txshdl: NitfField<u16>,
31 pub txsofl: NitfField<u16>,
33 pub txshd: ExtendedSubheader,
35}
36impl Default for TextHeader {
37 fn default() -> Self {
38 Self {
39 te: NitfField::init(2u8, "TE"),
40 textid: NitfField::init(7u8, "TEXTID"),
41 txtalvl: NitfField::init(3u8, "TXTALVL"),
42 txtdt: NitfField::init(14u8, "TXTDT"),
43 txttitl: NitfField::init(80u8, "TXTTITL"),
44 security: Security::default(),
45 encryp: NitfField::init(1u8, "ENCRYP"),
46 txtfmt: NitfField::init(3u8, "TXTFMT"),
47 txshdl: NitfField::init(5u8, "TXSHDL"),
48 txsofl: NitfField::init(3u8, "TXSOFL"),
49 txshd: ExtendedSubheader::init("TXSHD"),
50 }
51 }
52}
53
54#[derive(Default, Clone, Debug, Eq, PartialEq, Copy, Ord, PartialOrd)]
55pub enum TE {
56 #[default]
57 TE,
58}
59impl FromStr for TE {
60 type Err = NitfError;
61 fn from_str(s: &str) -> Result<Self, Self::Err> {
62 match s {
63 "TE" => Ok(Self::default()),
64 _ => Err(NitfError::ParseError("TE".to_string())),
65 }
66 }
67}
68impl Display for TE {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 write!(f, "TE")
71 }
72}
73
74#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
76pub enum TextFormat {
77 #[default]
78 MTF,
80 STA,
82 UT1,
84 U8S,
86}
87
88impl NitfSegmentHeader for TextHeader {
89 fn read(&mut self, reader: &mut (impl Read + Seek)) -> NitfResult<()> {
90 self.te.read(reader)?;
91 self.textid.read(reader)?;
92 self.txtalvl.read(reader)?;
93 self.txtdt.read(reader)?;
94 self.txttitl.read(reader)?;
95 self.security.read(reader)?;
96 self.encryp.read(reader)?;
97 self.txtfmt.read(reader)?;
98 self.txshdl.read(reader)?;
99 if self.txshdl.val != 0 {
100 self.txsofl.read(reader)?;
101 self.txshd.read(reader, (self.txshdl.val - 3) as usize)?;
102 }
103 Ok(())
104 }
105 fn write(&self, writer: &mut (impl Write + Seek)) -> NitfResult<usize> {
106 let mut bytes_written = 0;
107 bytes_written += self.te.write(writer)?;
108 bytes_written += self.textid.write(writer)?;
109 bytes_written += self.txtalvl.write(writer)?;
110 bytes_written += self.txtdt.write(writer)?;
111 bytes_written += self.txttitl.write(writer)?;
112 bytes_written += self.security.write(writer)?;
113 bytes_written += self.encryp.write(writer)?;
114 bytes_written += self.txtfmt.write(writer)?;
115 bytes_written += self.txshdl.write(writer)?;
116 if self.txshdl.val != 0 {
117 bytes_written += self.txsofl.write(writer)?;
118 bytes_written += self.txshd.write(writer)?;
119 }
120 Ok(bytes_written)
121 }
122 fn length(&self) -> usize {
123 let mut length = 0;
124 length += self.te.length;
125 length += self.textid.length;
126 length += self.txtalvl.length;
127 length += self.txtdt.length;
128 length += self.txttitl.length;
129 length += self.security.length();
130 length += self.encryp.length;
131 length += self.txtfmt.length;
132 length += self.txshdl.length;
133 if self.txshdl.val != 0 {
134 length += self.txsofl.length;
135 length += self.txshd.size();
136 }
137 length
138 }
139}
140impl Display for TextHeader {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 let mut out_str = String::default();
143 out_str += format!("{}, ", self.te).as_ref();
144 out_str += format!("{}, ", self.textid).as_ref();
145 out_str += format!("{}, ", self.txtalvl).as_ref();
146 out_str += format!("{}, ", self.txtdt).as_ref();
147 out_str += format!("{}, ", self.txttitl).as_ref();
148 out_str += format!("SECURITY: [{}], ", self.security).as_ref();
149 out_str += format!("{}, ", self.encryp).as_ref();
150 out_str += format!("{}, ", self.txtfmt).as_ref();
151 out_str += format!("{}", self.txshdl).as_ref();
152 out_str += format!("{}", self.txsofl).as_ref();
153 out_str += format!("{}", self.txshd).as_ref();
154 write!(f, "Text Segment: [{out_str}]")
155 }
156}
157impl FromStr for TextFormat {
158 type Err = NitfError;
159 fn from_str(s: &str) -> Result<Self, Self::Err> {
160 match s {
161 "MTF" => Ok(Self::MTF),
162 "STA" => Ok(Self::STA),
163 "UT1" => Ok(Self::UT1),
164 "U8S" => Ok(Self::U8S),
165 _ => Err(NitfError::ParseError("TextFormat".to_string())),
166 }
167 }
168}
169impl Display for TextFormat {
170 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171 match self {
172 Self::MTF => write!(f, "MTF"),
173 Self::STA => write!(f, "STA"),
174 Self::UT1 => write!(f, "UT1"),
175 Self::U8S => write!(f, "U8S"),
176 }
177 }
178}