nitf_rs/headers/
data_extension_hdr.rs

1//! Data Extension segment subheader definition
2use 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/// Metadata for Data Extension Segment
11#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
12pub struct DataExtensionHeader {
13    /// File Part Type
14    pub de: NitfField<DE>,
15    /// Unique DES Type Identifier
16    pub desid: NitfField<String>,
17    /// Check on this registration
18    /// Version of the Data Definition
19    pub desver: NitfField<u8>,
20    //// Security information
21    pub security: Security,
22    /// Overflowed Header Type
23    pub desoflw: NitfField<OverflowedHeaderType>,
24    /// Data Item Overflowed
25    pub desitem: NitfField<u16>,
26    /// DES User-defined Subheader Length
27    pub desshl: NitfField<u16>,
28    /// User-defined Subheader Fields
29    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/// Selection of which header/subheader this extension corresponds to
113#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
114pub enum OverflowedHeaderType {
115    #[default]
116    /// Image subheader extended subheader data overflow
117    IXSHD,
118    /// Graphic subheader extended subheader data overflow
119    SXSHD,
120    /// Text subheader extended subheader data overflow
121    TXSHD,
122    /// Header user defined header overflow
123    UDHD,
124    /// Image subheader user defined image data overflow
125    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}