summaryrefslogtreecommitdiff
path: root/src/asn1_types/embedded_pdv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/asn1_types/embedded_pdv.rs')
-rw-r--r--src/asn1_types/embedded_pdv.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/asn1_types/embedded_pdv.rs b/src/asn1_types/embedded_pdv.rs
new file mode 100644
index 0000000..9452856
--- /dev/null
+++ b/src/asn1_types/embedded_pdv.rs
@@ -0,0 +1,125 @@
+use crate::*;
+use core::convert::TryFrom;
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct EmbeddedPdv<'a> {
+ pub identification: PdvIdentification<'a>,
+ pub data_value_descriptor: Option<ObjectDescriptor<'a>>,
+ pub data_value: &'a [u8],
+}
+
+#[derive(Debug, PartialEq, Eq)]
+pub enum PdvIdentification<'a> {
+ Syntaxes {
+ s_abstract: Oid<'a>,
+ s_transfer: Oid<'a>,
+ },
+ Syntax(Oid<'a>),
+ PresentationContextId(Integer<'a>),
+ ContextNegotiation {
+ presentation_context_id: Integer<'a>,
+ presentation_syntax: Oid<'a>,
+ },
+ TransferSyntax(Oid<'a>),
+ Fixed,
+}
+
+impl<'a> TryFrom<Any<'a>> for EmbeddedPdv<'a> {
+ type Error = Error;
+
+ fn try_from(any: Any<'a>) -> Result<Self> {
+ TryFrom::try_from(&any)
+ }
+}
+
+impl<'a, 'b> TryFrom<&'b Any<'a>> for EmbeddedPdv<'a> {
+ type Error = Error;
+
+ fn try_from(any: &'b Any<'a>) -> Result<Self> {
+ let data = any.data;
+ // AUTOMATIC TAGS means all values will be tagged (IMPLICIT)
+ // [0] -> identification
+ let (rem, seq0) =
+ TaggedParser::<Explicit, Any>::parse_ber(Class::ContextSpecific, Tag(0), data)?;
+ let inner = seq0.inner;
+ let identification = match inner.tag() {
+ Tag(0) => {
+ // syntaxes SEQUENCE {
+ // abstract OBJECT IDENTIFIER,
+ // transfer OBJECT IDENTIFIER
+ // },
+ // AUTOMATIC tags -> implicit! Hopefully, Oid does not check tag value!
+ let (rem, s_abstract) = Oid::from_ber(inner.data)?;
+ let (_, s_transfer) = Oid::from_ber(rem)?;
+ PdvIdentification::Syntaxes {
+ s_abstract,
+ s_transfer,
+ }
+ }
+ Tag(1) => {
+ // syntax OBJECT IDENTIFIER
+ let oid = Oid::new(inner.data.into());
+ PdvIdentification::Syntax(oid)
+ }
+ Tag(2) => {
+ // presentation-context-id INTEGER
+ let i = Integer::new(inner.data);
+ PdvIdentification::PresentationContextId(i)
+ }
+ Tag(3) => {
+ // context-negotiation SEQUENCE {
+ // presentation-context-id INTEGER,
+ // transfer-syntax OBJECT IDENTIFIER
+ // },
+ // AUTOMATIC tags -> implicit!
+ let (rem, any) = Any::from_ber(inner.data)?;
+ let presentation_context_id = Integer::new(any.data);
+ let (_, presentation_syntax) = Oid::from_ber(rem)?;
+ PdvIdentification::ContextNegotiation {
+ presentation_context_id,
+ presentation_syntax,
+ }
+ }
+ Tag(4) => {
+ // transfer-syntax OBJECT IDENTIFIER
+ let oid = Oid::new(inner.data.into());
+ PdvIdentification::TransferSyntax(oid)
+ }
+ Tag(5) => {
+ // fixed NULL
+ PdvIdentification::Fixed
+ }
+ _ => {
+ return Err(inner
+ .tag()
+ .invalid_value("Invalid identification tag in EMBEDDED PDV"))
+ }
+ };
+ // [1] -> data-value-descriptor ObjectDescriptor OPTIONAL
+ // *BUT* WITH COMPONENTS data-value-descriptor ABSENT
+ // XXX this should be parse_ber?
+ // let (rem, data_value_descriptor) =
+ // TaggedOptional::from(1).parse_der(rem, |_, inner| ObjectDescriptor::from_ber(inner))?;
+ let (rem, data_value_descriptor) = (rem, None);
+ // [2] -> data-value OCTET STRING
+ let (_, data_value) =
+ TaggedParser::<Implicit, &[u8]>::parse_ber(Class::ContextSpecific, Tag(2), rem)?;
+ let data_value = data_value.inner;
+ let obj = EmbeddedPdv {
+ identification,
+ data_value_descriptor,
+ data_value,
+ };
+ Ok(obj)
+ }
+}
+
+impl CheckDerConstraints for EmbeddedPdv<'_> {
+ fn check_constraints(any: &Any) -> Result<()> {
+ any.header.length().assert_definite()?;
+ any.header.assert_constructed()?;
+ Ok(())
+ }
+}
+
+impl DerAutoDerive for EmbeddedPdv<'_> {}