Skip to main content

Module tagged

Module tagged 

Source
Expand description

Decode helpers for tagged fields, shared by the constructed codecs, the formal Error bodies in apdu/ and the service parameters bacnet-services decodes.

Each helper reads one field at an offset and returns what it read with the offset just past it. Each takes the what label its codec passes (the production, sometimes narrowed to one alternative or member), so every codec words a refusal the same way:

  • a tag of the wrong number, class or form: {what}: expected context tag [n], {what}: expected opening tag [n], {what}: expected closing tag [n] or {what}: expected application-tagged Unsigned, reported at the offending tag;
  • a fixed-size primitive of the wrong length: {what}: [n] REAL has 5 contents octets, expected 4;
  • an Unsigned or ENUMERATED too large for its field: {what}: [n] value 70000 exceeds u16, or {what}: Unsigned exceeds u16 for an application-tagged one;
  • bytes left after a value that must fill its input: {what}: 2 trailing byte(s).

One error-kind rule holds across the crate’s decoders (#1333):

An Error::Decoding carries the DecodingKind of the fault, which a responder turns into a Reject reason (#1446):

The helpers another crate needs are public: the peeks for an optional member, a frame’s opening and closing tags and its body, the context readers for contents, fixed-size contents, Unsigned or ENUMERATED values, REAL, BOOLEAN, BIT STRING, OCTET STRING, CharacterString and object identifiers, the optional-member wrapper, the application readers, the trailing-data check, and the kinds a misplaced tag is (misplaced_kind, misplaced_tag, unclosed_kind). The rest stay private to this crate.

use bacnet_encoding::constructed::tagged::{decode_ctx_unsigned, expect_end, next_is_context};
use bacnet_types::error::Error;

// A required `[0]` Unsigned 7 and no optional `[1]` after it.
let data = [0x09, 0x07];
let (value, end) = decode_ctx_unsigned::<u32>(&data, 0, 0, "Example")?;
assert_eq!((value, end), (7, 2));
assert!(!next_is_context(&data, end, 1)?);
expect_end(&data, end, end, "Example")?;

// The same member announcing two contents octets but holding one.
let cut = decode_ctx_unsigned::<u32>(&[0x0A, 0x07], 0, 0, "Example");
assert!(matches!(cut, Err(Error::BufferTooShort { need: 3, have: 2 })));

Traits§

UnsignedWidth
An unsigned integer type a decoded Unsigned or ENUMERATED is narrowed to: u8, u16, u32 or u64. Sealed, so no other type implements it.

Functions§

decode_app_bit_string
Decode one application-tagged BIT STRING (SEQUENCE OF BIT STRING item).
decode_app_character_string
Decode one application-tagged CharacterString.
decode_app_enumerated
Decode one application-tagged ENUMERATED (a SEQUENCE OF item, or an error class or code) that fits T. Leading zero octets are accepted.
decode_app_fixed
Require an application tag number at offset holding exactly octets contents octets; return them and the offset past them. As with decode_ctx_fixed, a header announcing any other length is Error::Decoding even when the data also stops early.
decode_app_object_id
Require an application-tagged object identifier, four contents octets, at offset.
decode_app_primitive
Require an application tag number (one of tags::app_tag) at offset; return its contents and the offset past them.
decode_app_unsigned
Decode one application-tagged Unsigned that fits T. Leading zero octets are accepted.
decode_canonical_unsigned
The value of Unsigned or ENUMERATED contents in their shortest encoding: one to eight octets, and no leading zero octet unless it is the only one. Errors report offset, the field’s tag.
decode_ctx_bit_string
Require a primitive context tag tag at offset holding a BIT STRING; returns its unused-bit count and data octets.
decode_ctx_boolean
Require a primitive context tag tag at offset holding a BOOLEAN: one contents octet, 0 or 1 (Clause 20.2.3).
decode_ctx_canonical_unsigned
decode_ctx_unsigned for a codec that must re-encode what it read octet for octet: the contents must also be the shortest encoding (see decode_canonical_unsigned).
decode_ctx_character_string
Require a primitive context tag tag at offset holding a CharacterString.
decode_ctx_constructed
Require constructed context tag tag at offset; return its body (the octets between its opening and closing tags, with nested frames balanced) and the offset past its closing tag.
decode_ctx_fixed
Require a primitive context tag tag at offset holding exactly octets contents octets of the type kind names ("Time", say, for the error); return those contents and the offset past them. A header announcing any other length is Error::Decoding even when the data also stops early.
decode_ctx_object_id
Require a primitive context tag tag at offset holding an object identifier, which is always four octets.
decode_ctx_octet_string
Require a primitive context tag tag at offset holding an OCTET STRING; returns a copy of its octets.
decode_ctx_primitive
Require a primitive context tag tag at offset; return its contents and the offset past them.
decode_ctx_real
Require a primitive context tag tag at offset holding a REAL.
decode_ctx_unsigned
Require a primitive context tag tag at offset holding an Unsigned that fits T. An ENUMERATED’s contents are encoded the same way, so this reads those too. Leading zero octets are accepted, as primitives::decode_unsigned accepts them.
decode_optional_ctx
Read the optional member under primitive context tag tag with decode when that tag comes next; otherwise None with the offset unchanged. What decode returns may borrow from data, so decode_ctx_primitive yields the member’s contents.
expect_closing
Require a closing context tag tag at offset; return the offset past it. Any other tag there is of the kind unclosed_kind gives.
expect_end
Require a value that stopped at end to have used all of data.
expect_opening
Require an opening context tag tag at offset; return the offset of its content.
misplaced_kind
The kind of fault the tag found, at at in data, is where a required member is due.
misplaced_tag
The error for the tag found, at offset in data, where a required member is due, of the kind misplaced_kind gives.
next_is_application
Whether an application tag number (one of tags::app_tag) starts at offset; false at the end of the data, so an optional application-tagged member may be the last one. A malformed tag there is an error.
next_is_context
Whether a primitive context tag tag starts at offset; false at the end of the data, so an optional member may be the last one. A malformed tag there is an error.
next_is_opening
Whether an opening context tag tag starts at offset; false at the end of the data. A malformed tag there is an error.
unclosed_kind
The kind of fault the tag found is where a frame’s closing tag is due: another closing tag is DecodingKind::InvalidTag; any other tag is a member the frame holds beyond its last one, DecodingKind::Trailing.