asn1_rs/asn1_types/
embedded_pdv.rs

1use crate::*;
2use core::convert::TryFrom;
3
4#[derive(Debug, PartialEq, Eq)]
5pub struct EmbeddedPdv<'a> {
6    pub identification: PdvIdentification<'a>,
7    pub data_value_descriptor: Option<ObjectDescriptor<'a>>,
8    pub data_value: &'a [u8],
9}
10
11#[derive(Debug, PartialEq, Eq)]
12pub enum PdvIdentification<'a> {
13    Syntaxes {
14        s_abstract: Oid<'a>,
15        s_transfer: Oid<'a>,
16    },
17    Syntax(Oid<'a>),
18    PresentationContextId(Integer<'a>),
19    ContextNegotiation {
20        presentation_context_id: Integer<'a>,
21        presentation_syntax: Oid<'a>,
22    },
23    TransferSyntax(Oid<'a>),
24    Fixed,
25}
26
27impl<'a> TryFrom<Any<'a>> for EmbeddedPdv<'a> {
28    type Error = Error;
29
30    fn try_from(any: Any<'a>) -> Result<Self> {
31        TryFrom::try_from(&any)
32    }
33}
34
35impl<'a, 'b> TryFrom<&'b Any<'a>> for EmbeddedPdv<'a> {
36    type Error = Error;
37
38    fn try_from(any: &'b Any<'a>) -> Result<Self> {
39        let data = any.data;
40        // AUTOMATIC TAGS means all values will be tagged (IMPLICIT)
41        // [0] -> identification
42        let (rem, seq0) =
43            TaggedParser::<Explicit, Any>::parse_ber(Class::ContextSpecific, Tag(0), data)?;
44        let inner = seq0.inner;
45        let identification = match inner.tag() {
46            Tag(0) => {
47                // syntaxes SEQUENCE {
48                //     abstract OBJECT IDENTIFIER,
49                //     transfer OBJECT IDENTIFIER
50                // },
51                // AUTOMATIC tags -> implicit! Hopefully, Oid does not check tag value!
52                let (rem, s_abstract) = Oid::from_ber(inner.data)?;
53                let (_, s_transfer) = Oid::from_ber(rem)?;
54                PdvIdentification::Syntaxes {
55                    s_abstract,
56                    s_transfer,
57                }
58            }
59            Tag(1) => {
60                // syntax OBJECT IDENTIFIER
61                let oid = Oid::new(inner.data.into());
62                PdvIdentification::Syntax(oid)
63            }
64            Tag(2) => {
65                // presentation-context-id INTEGER
66                let i = Integer::new(inner.data);
67                PdvIdentification::PresentationContextId(i)
68            }
69            Tag(3) => {
70                // context-negotiation SEQUENCE {
71                //     presentation-context-id INTEGER,
72                //     transfer-syntax OBJECT IDENTIFIER
73                // },
74                // AUTOMATIC tags -> implicit!
75                let (rem, any) = Any::from_ber(inner.data)?;
76                let presentation_context_id = Integer::new(any.data);
77                let (_, presentation_syntax) = Oid::from_ber(rem)?;
78                PdvIdentification::ContextNegotiation {
79                    presentation_context_id,
80                    presentation_syntax,
81                }
82            }
83            Tag(4) => {
84                // transfer-syntax OBJECT IDENTIFIER
85                let oid = Oid::new(inner.data.into());
86                PdvIdentification::TransferSyntax(oid)
87            }
88            Tag(5) => {
89                // fixed NULL
90                PdvIdentification::Fixed
91            }
92            _ => {
93                return Err(inner
94                    .tag()
95                    .invalid_value("Invalid identification tag in EMBEDDED PDV"))
96            }
97        };
98        // [1] -> data-value-descriptor ObjectDescriptor OPTIONAL
99        // *BUT* WITH COMPONENTS data-value-descriptor ABSENT
100        // XXX this should be parse_ber?
101        // let (rem, data_value_descriptor) =
102        //     TaggedOptional::from(1).parse_der(rem, |_, inner| ObjectDescriptor::from_ber(inner))?;
103        let (rem, data_value_descriptor) = (rem, None);
104        // [2] -> data-value OCTET STRING
105        let (_, data_value) =
106            TaggedParser::<Implicit, &[u8]>::parse_ber(Class::ContextSpecific, Tag(2), rem)?;
107        let data_value = data_value.inner;
108        let obj = EmbeddedPdv {
109            identification,
110            data_value_descriptor,
111            data_value,
112        };
113        Ok(obj)
114    }
115}
116
117impl CheckDerConstraints for EmbeddedPdv<'_> {
118    fn check_constraints(any: &Any) -> Result<()> {
119        any.header.length().assert_definite()?;
120        any.header.assert_constructed()?;
121        Ok(())
122    }
123}
124
125impl DerAutoDerive for EmbeddedPdv<'_> {}