nitf_rs/headers/
text_hdr.rs

1//! Text segment definition
2use 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/// Text Segment Metadata
11#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
12pub struct TextHeader {
13    /// File Part Type
14    pub te: NitfField<TE>,
15    /// Text Identifier
16    pub textid: NitfField<String>,
17    /// Text Attachment Level
18    pub txtalvl: NitfField<u16>,
19    /// Text Date and Time
20    pub txtdt: NitfField<String>,
21    /// Text Title
22    pub txttitl: NitfField<String>,
23    /// Security information
24    pub security: Security,
25    /// Encryption
26    pub encryp: NitfField<String>,
27    /// Text Format
28    pub txtfmt: NitfField<TextFormat>,
29    /// Text Extended Subheader Data Length
30    pub txshdl: NitfField<u16>,
31    /// Text Extended Subheader Overflow
32    pub txsofl: NitfField<u16>,
33    /// Text Extended Subheader Data
34    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/// Formatting specification
75#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
76pub enum TextFormat {
77    #[default]
78    /// USMTF formatting
79    MTF,
80    /// BCS formatting
81    STA,
82    /// ECS formatting
83    UT1,
84    /// U8S formatting
85    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}