1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Data Extension segment subheader definition
use std::fmt::Display;
use std::fs::File;
use std::str::FromStr;

use crate::error::NitfError;
use crate::headers::NitfSegmentHeader;
use crate::types::{NitfField, Security, ExtendedSubheader};

/// Metadata for Data Extension Segment
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct DataExtensionHeader {
    /// File Part Type
    pub de: NitfField<String>,
    /// Unique DES Type Identifier
    pub desid: NitfField<String>,
    /// Check on this registration
    /// Version of the Data Definition
    pub desver: NitfField<u8>,
    //// Security information
    pub security: Security,
    /// Overflowed Header Type
    pub desoflw: NitfField<OverflowedHeaderType>,
    /// Data Item Overflowed
    pub desitem: NitfField<u16>,
    /// DES User-defined Subheader Length
    pub desshl: NitfField<u16>,
    /// User-defined Subheader Fields
    pub desshf: ExtendedSubheader, 
}

/// Selection of which header/subheader this extension corresponds to
#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub enum OverflowedHeaderType {
    #[default]
    /// Image subheader extended subheader data overflow
    IXSHD,
    /// Graphic subheader extended subheader data overflow
    SXSHD,
    /// Text subheader extended subheader data overflow
    TXSHD,
    /// Header user defined header overflow
    UDHD,
    /// Image subheader user defined image data overflow
    UDID,
}

impl NitfSegmentHeader for DataExtensionHeader {
    fn read(&mut self, reader: &mut File) {
        self.de.read(reader, 2u8);
        self.desid.read(reader, 25u8);
        self.desver.read(reader, 2u8);
        self.security.read(reader);
        if self.desid.string.trim() == "TRE_OVERFLOW" {
            self.desoflw.read(reader, 6u8);
            self.desitem.read(reader, 3u8);
        }
        self.desshl.read(reader, 4u8);
        if self.desshl.val != 0 {
            self.desshf.read(reader, self.desshl.val as usize);
        }
    }
}
impl Display for DataExtensionHeader {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut out_str = String::default();
        out_str += format!("DE: {}, ", self.de).as_ref();
        out_str += format!("DESID: {}, ", self.desid).as_ref();
        out_str += format!("DESVER: {}, ", self.desver).as_ref();
        out_str += format!("SECURITY: [{}], ", self.security).as_ref();
        out_str += format!("DESOFLW: {}, ", self.desoflw).as_ref();
        out_str += format!("DESITEM: {}, ", self.desitem).as_ref();
        out_str += format!("DESSHL: {}, ", self.desshl).as_ref();
        out_str += format!("DESSHF: {}", self.desshf).as_ref();
        write!(f, "[Data Extension Subheader: {out_str}]")
    }
}
impl FromStr for OverflowedHeaderType {
    type Err = NitfError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "IXSHD" => Ok(Self::IXSHD),
            "SXSHD" => Ok(Self::SXSHD),
            "TXSHD" => Ok(Self::TXSHD),
            "UDHD" => Ok(Self::UDHD),
            "UDID" => Ok(Self::UDID),
            _ => Err(NitfError::FieldError),
        }
    }
}