pub struct TlvReader<'a> { /* private fields */ }Expand description
A streaming TLV decoder over a borrowed byte slice.
Implementations§
Source§impl<'a> TlvReader<'a>
impl<'a> TlvReader<'a>
Sourcepub fn new(bytes: &'a [u8]) -> Self
pub fn new(bytes: &'a [u8]) -> Self
Construct a reader that walks bytes from the start, using the
DEFAULT_ELEMENT_BUDGET for tree-builder decodes.
Sourcepub fn with_element_budget(bytes: &'a [u8], budget: usize) -> Self
pub fn with_element_budget(bytes: &'a [u8], budget: usize) -> Self
Construct a reader with a custom total-element budget for tree-builder
decoding (see DEFAULT_ELEMENT_BUDGET).
A Self::read_value call that would materialise more than budget
Value elements fails with Error::ElementBudgetExceeded. The
budget only affects the tree-builder path; the streaming Self::next
API is unaffected because it allocates nothing per element.
Sourcepub fn next(&mut self) -> Result<Option<Element>>
pub fn next(&mut self) -> Result<Option<Element>>
Advance one TLV element. Returns Ok(None) at end of input.
§Errors
Returns Err if the input is malformed:
Error::InvalidTagControl— unrecognised tag-control byte form.Error::InvalidElementType— unknown element-type code.Error::UnexpectedEof— truncated payload bytes.Error::UnexpectedEndOfContainer— end-of-container marker (0x18) at the top level, with no container open.Error::ContainerTooDeep— a container open would exceedMAX_DEPTHnesting levels.
§Note on naming
This method is deliberately named next to match the streaming-reader
idiom established by e.g. serde’s Deserializer. It returns
Result<Option<T>> rather than Option<Result<T>> so that callers
use ? naturally. Implementing std::iter::Iterator is deferred to
a later phase when a fallible-iterator adapter is available.
Sourcepub fn skip_container(&mut self) -> Result<()>
pub fn skip_container(&mut self) -> Result<()>
Skip the remaining body of the container whose
ContainerStart was just returned by
Self::next, consuming through its matching
ContainerEnd.
Call this immediately after next() yields a ContainerStart you
want to discard — for example an unknown field carried by a struct
from a newer Matter revision. On return the reader is positioned at
the first element after the skipped container. Scalars inside the
container are walked but not materialised, so cost is bounded by the
input size and nesting by MAX_DEPTH (both enforced by next()).
§Errors
Error::UnclosedContainer— end of input before the container’s closing marker.- Any error returned by
Self::next(malformed body, over-deep nesting, or element-budget exhaustion).
§Examples
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter};
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)?;
w.start_structure(Tag::Context(9))?; // an unknown nested field
w.end_container()?;
w.put_uint(Tag::Context(1), 42)?;
w.end_container()?;
let mut r = TlvReader::new(&buf);
r.next()?; // open the outer struct
// next() returns the nested ctx9 ContainerStart we want to discard:
assert!(matches!(
r.next()?,
Some(Element::ContainerStart { kind: ContainerKind::Structure, .. })
));
r.skip_container()?; // drain the nested struct
// the field after the unknown container is still readable:
assert!(matches!(r.next()?, Some(Element::Scalar { tag: Tag::Context(1), .. })));Sourcepub fn read_value(&mut self) -> Result<(Tag, Value)>
pub fn read_value(&mut self) -> Result<(Tag, Value)>
Materialise one full TLV element as a (Tag, Value). Scalars are
returned directly; containers are read recursively up to
MAX_DEPTH levels (enforced by Self::next’s depth counter).
§Errors
Error::UnexpectedEof— the input is empty.Error::UnexpectedEndOfContainer— the first element is a stray end-of-container marker.Error::UnclosedContainer— end of input was reached before the container’s closing marker.Error::NonAnonymousArrayTag— an array child carried a non-anonymous tag (the spec requires array elements to be anonymous).Error::ElementBudgetExceeded— the decode would materialise more than the configured element budget (seeDEFAULT_ELEMENT_BUDGET).- Any error returned by
Self::next.