pub struct ScopedReader<'a: 'operation, 'operation> { /* private fields */ }Expand description
Reads the elements of one container, in order.
Cloning one keeps where it is and how deep it sits, so a caller that has to come back to a container later can put the reader aside rather than start again from the document and count the nesting as one.
Implementations§
Source§impl<'a: 'operation, 'operation> ScopedReader<'a, 'operation>
impl<'a: 'operation, 'operation> ScopedReader<'a, 'operation>
Sourcepub fn integer_reading(
&self,
element: &Element<'a>,
) -> Result<IntegerReading<'a>>
pub fn integer_reading( &self, element: &Element<'a>, ) -> Result<IntegerReading<'a>>
Recover the unique numeric value while retaining nonminimal spelling.
Unlike Self::integer, this explicit diagnostic operation reads
redundant sign octets. It does not declare them conforming: X.690
§§8.3.1–8.3.3 requires primitive, nonempty, minimal two’s complement
already under BER. Schema layers decide how to retain the fault.
https://www.itu.int/rec/T-REC-X.690-202102-I/en
Use the Reader which produced element. Like the strict reader, this
supports primitive IMPLICIT tagging and leaves tag selection to the
schema. Original offsets, depth and cumulative local work are retained;
future work and diagnostic storage use the current execution account.
Payload bytes remain borrowed. Padding is scanned once, before any
bounded numeric conversion requested on the returned view.
use std::sync::Arc;
use structured_asn1::{Parser, ErrorCode};
use structured_asn1::memory::{Memory, MemoryAccount};
let memory = Memory::new(Arc::new(MemoryAccount::new(1024, 1024)));
let parser = Parser::der(memory);
let mut reader = parser.read(&[2, 2, 0, 1], 400)?;
let element = reader.next_element()?.unwrap();
let reading = reader.integer_reading(&element)?;
assert_eq!(reading.as_bytes(), &[0, 1]);
let (value, fault) = reading.into_parts();
assert_eq!(value.as_u64(), Some(1));
let fault = fault.unwrap();
assert_eq!(fault.code(), ErrorCode::IntegerNotMinimal);
assert_eq!(fault.offset(), 400);§Errors
Empty and constructed contents remain errors. Work is admitted before scanning; failure to retain the fault path is a resource refusal, never a successful reading without its diagnostic.
Source§impl<'a: 'operation, 'operation> ScopedReader<'a, 'operation>
impl<'a: 'operation, 'operation> ScopedReader<'a, 'operation>
Sourcepub fn execution(&self) -> Execution<'_>
pub fn execution(&self) -> Execution<'_>
Borrows both the current account and original cumulative work ceiling.
Schema scratch must use this boundary when work belongs to the parse:
allocator growth, copying and sorting then retain the session ceiling
as well as the aggregate account. Independently retained results use
Self::memory instead.
§Examples
use std::sync::Arc;
use structured_asn1::{Parser, memory::{Memory, MemoryAccount, Work}};
let parser = Parser::ber(Memory::new(Arc::new(MemoryAccount::new(1024, 1024))));
let reader = parser.read(&[], 900).unwrap();
let mut scratch = reader.execution().vector();
scratch.try_push(7_u8)?;
assert_eq!(&*scratch, &[7]);Sourcepub fn execution_in<'work>(&self, memory: &'work Memory) -> Execution<'work>where
'a: 'work,
'operation: 'work,
pub fn execution_in<'work>(&self, memory: &'work Memory) -> Execution<'work>where
'a: 'work,
'operation: 'work,
Borrows the source/query budgets independently of this reader cursor.
Supply the operation account explicitly so scratch can keep the same admission while the cursor advances. This creates no allocation or owning account clone and cannot discard an inherited query ceiling.
Sourcepub fn execution_query<'query>(
&self,
query: &'query Reader<'_>,
) -> Execution<'query>where
'a: 'query,
pub fn execution_query<'query>(
&self,
query: &'query Reader<'_>,
) -> Execution<'query>where
'a: 'query,
Borrows original-source and current root-operation work ceilings for metadata queries that do not enter a payload or advance a cursor.
Construction allocates nothing, copies no diagnostic path and does not inspect bytes or require an additional ASN.1 nesting level. Work and collection admission still checks both cumulative ceilings, charging the current query’s aggregate account once. A prior foreign source is replaced by this source, never by a wider ancestor operation.
Sourcepub fn with_execution(self, execution: &Memory) -> Self
pub fn with_execution(self, execution: &Memory) -> Self
Selects the domain for subsequent execution without moving existing storage charges. Offsets, depth and parser-session cumulative limits remain unchanged; a new domain does not reset that session ceiling.
Sourcepub fn with_query<'query>(
self,
query: &Reader<'query>,
) -> Result<Reader<'query>>where
'a: 'query,
pub fn with_query<'query>(
self,
query: &Reader<'query>,
) -> Result<Reader<'query>>where
'a: 'query,
Moves this cursor into a current query without copying its retained path. Original parser, data, offsets and depth remain unchanged. Both source and operation admission apply before changing execution; existing path capacity keeps its original owner until actually freed.
Sourcepub fn try_clone(&self) -> Result<Self>
pub fn try_clone(&self) -> Result<Self>
Copies the reader position and diagnostic path fallibly in the same domain.
Sourcepub fn parser(&self) -> &'a Parser
pub fn parser(&self) -> &'a Parser
Original parser, whose session ceilings remain cumulative across
deferred reads. Use Self::memory for the current execution domain;
the parser’s storage domain may belong to an earlier operation.
Sourcepub fn charge(&self, amount: u64) -> Result<()>
pub fn charge(&self, amount: u64) -> Result<()>
Charges caller-side scanning to the shared work budget.
For a schema layer that walks an element’s contents itself, text validation and named-bit walks among them: the walk costs what the bytes cost, and a caller bounding work must see that cost on the same meter the reads use.
Sourcepub fn depth(&self) -> u32
pub fn depth(&self) -> u32
How many containers deep this reader sits, counted as the depth
ceiling counts it. What Parser::read_nested is given for a value
found here.
Sourcepub fn offset(&self) -> u64
pub fn offset(&self) -> u64
The offset of the next unread byte, in the document.
Ordinary arithmetic, because pos never exceeds the length of data
and base plus that length was shown to fit when this reader was made.
Sourcepub fn path(&self) -> &Path
pub fn path(&self) -> &Path
The path to this container, for a caller building its own diagnostics.
Sourcepub fn encoding(&self) -> Encoding
pub fn encoding(&self) -> Encoding
Which encoding this reader accepts, for a schema whose own rules differ between the two, such as the ordering DER requires of a set.
Sourcepub fn reread(&self, element: &Element<'a>, encoding: Encoding) -> Result<Self>
pub fn reread(&self, element: &Element<'a>, encoding: Encoding) -> Result<Self>
A reader over an element’s own bytes, header included, under a chosen encoding.
For a structure whose schema fixes its encoding regardless of the container’s: a certificate is DER even when the envelope carrying it is BER, and reading it with the container’s leniency would let spellings survive that the certificate’s own rules refuse. The element’s header is read again under the chosen rules, so a header only the lenient encoding accepts is refused too. Offsets stay offsets in the document and the budget stays the shared one.
Sourcepub fn next_element(&mut self) -> Result<Option<Element<'a>>>
pub fn next_element(&mut self) -> Result<Option<Element<'a>>>
Reads the next element, or None at the end of this container.
Sourcepub fn expect(&mut self, tag: Tag) -> Result<Element<'a>>
pub fn expect(&mut self, tag: Tag) -> Result<Element<'a>>
Reads the next element and requires it to carry tag.
Sourcepub fn skip(&mut self) -> Result<bool>
pub fn skip(&mut self) -> Result<bool>
Reads and discards the next element, whatever it is.
This is how a schema layer steps over an extension it does not know: the element is skipped within its declared length, so an unknown tag costs what a known one costs and cannot make the reader wander.
Sourcepub fn enter(&self, element: &Element<'a>) -> Result<Self>
pub fn enter(&self, element: &Element<'a>) -> Result<Self>
A reader over the contents of a constructed element read from here.
Refused for a primitive element: its contents are a value rather than further elements, and reading them as elements is how a parser is talked into finding structure inside an octet string that nobody put there.
Sourcepub fn oid(&self, element: &Element<'a>) -> Result<Oid<'a>>
pub fn oid(&self, element: &Element<'a>) -> Result<Oid<'a>>
Reads an element’s contents as an object identifier.
Sourcepub fn integer(&self, element: &Element<'a>) -> Result<Integer<'a>>
pub fn integer(&self, element: &Element<'a>) -> Result<Integer<'a>>
Reads an element’s contents as an integer.
Sourcepub fn bit_string(&self, element: &Element<'a>) -> Result<BitString<'a>>
pub fn bit_string(&self, element: &Element<'a>) -> Result<BitString<'a>>
Reads an element’s contents as a bit string.
The segmented form BER allows for a constructed bit string is refused: every bit string this product reads is covered by a signature computed over the bytes, where one value with two spellings is one value too many.
Sourcepub fn boolean(&self, element: &Element<'a>) -> Result<bool>
pub fn boolean(&self, element: &Element<'a>) -> Result<bool>
Reads an element’s contents as a boolean.
Sourcepub fn null(&self, element: &Element<'a>) -> Result<()>
pub fn null(&self, element: &Element<'a>) -> Result<()>
Reads an element’s contents as a null, which has none.
Sourcepub fn real(&self, element: &Element<'a>) -> Result<()>
pub fn real(&self, element: &Element<'a>) -> Result<()>
Reads an element’s contents as a real, and answers only whether they are a value of the type.
The number itself is not read: no schema this product parses has a real in it, and one arrives only inside a value preserved for somebody else, who is promised octets that are what they claim.
Sourcepub fn read_integer(&mut self) -> Result<Integer<'a>>
pub fn read_integer(&mut self) -> Result<Integer<'a>>
Reads the next element as an integer.
Sourcepub fn read_bit_string(&mut self) -> Result<BitString<'a>>
pub fn read_bit_string(&mut self) -> Result<BitString<'a>>
Reads the next element as a bit string.
Sourcepub fn read_boolean(&mut self) -> Result<bool>
pub fn read_boolean(&mut self) -> Result<bool>
Reads the next element as a boolean.
Sourcepub fn fail_under(&self, code: ErrorCode, element: &Element<'a>) -> Error
pub fn fail_under(&self, code: ErrorCode, element: &Element<'a>) -> Error
An error naming an element read from this container.