Skip to main content

Reader

Struct Reader 

Source
pub struct Reader<'a> { /* private fields */ }
Expand description

A reader of aligned PER: the octets of an encoding, and how far they are read.

Each method reads one field of ITU-T X.691 and moves on. A field that is octet-aligned skips the bits up to the next octet first. The bounds of a constraint are arguments, which a caller writes as constants.

A value that is whole, in another form than the one that its clause gives it, is read, as the encoder of a peer may write it: a length of 127 or less in two octets, a fragment that is not the largest, a small number in the form of a larger one, a whole number in more octets than it needs, padding bits that are not zero, and an arc of an object identifier that starts with an octet that holds nothing. A reader that noting made notes each, faults has what it noted, and decode_strict refuses it.

use oxirush_aper::Reader;

// INTEGER (0..7), then INTEGER (0..65535), which is two octets after padding
let mut reader = Reader::new(&[0b1010_0000, 0x12, 0x34]);
assert_eq!(reader.unsigned(0, 7)?, 5);
assert_eq!(reader.unsigned(0, 65535)?, 0x1234);

A value that holds octets borrows them from the octets of the reader, and lives as long as they do.

Implementations§

Source§

impl<'a> Reader<'a>

Source

pub fn new(octets: &'a [u8]) -> Self

A reader at the first bit of octets.

Source

pub fn noting(octets: &'a [u8]) -> Self

A reader at the first bit of octets that notes what it reads in another form than the one that its clause gives: see Fault, and faults. It reads what a reader of new reads, which looks at no padding bit and notes nothing.

use oxirush_aper::{Fault, Reader, UNBOUNDED};

// An OCTET STRING of one octet, whose length is in two octets
let mut reader = Reader::noting(&[0x80, 0x01, 0xaa]);
assert_eq!(reader.octet_string(0, UNBOUNDED)?, [0xaa]);
assert_eq!(reader.faults()[0].fault, Fault::LengthInTwoOctets);
Source

pub fn faults(&self) -> &Faults

What a reader that noting made read so far in another form than the one that its clause gives, each with the bit of the octets at which it is. None for a reader of new.

Source

pub fn position(&self) -> usize

How many bits are read.

Source

pub fn remaining(&self) -> usize

How many bits are left.

Source

pub fn rest(&self) -> &'a [u8] ⓘ

The octets that are left, from the next octet boundary.

Source

pub fn finish(&self) -> Result<(), Error>

The end of a complete encoding (X.691 §11.1.4): no octet follows the value, whose last octet may have padding bits. An encoding of no bit is one zero octet. The octets that follow the most that a reader takes, usize::MAX / 8 of them, follow the value too.

Source

pub fn bit(&mut self) -> Result<bool, Error>

One bit: a BOOLEAN (X.691 §12), and the bit of an extension marker or of a member that may be absent.

Source

pub fn bits(&mut self, count: usize) -> Result<u64, Error>

The next count bits as a number, the first bit the most significant: 64 bits at most. They are not aligned.

Source

pub fn align(&mut self)

Skip the bits up to the next octet boundary: the padding of an octet-aligned field, and that of the end of a complete encoding (X.691 §11.1.4). Bits of it that are not zero are noted.

Source

pub fn octet(&mut self) -> Result<u8, Error>

One octet, octet-aligned.

Source

pub fn octets(&mut self, count: usize) -> Result<&'a [u8], Error>

The next count octets, octet-aligned.

Source

pub fn unsigned(&mut self, lower: u64, upper: u64) -> Result<u64, Error>

A constrained whole number (X.691 §11.5) of lower..=upper, as an INTEGER of that constraint is encoded (§13.2.2): no bit for one value, a bit-field for a range of 255 values at most, one octet for 256, two octets up to 64K, and above that the number of its octets, then its octets.

Source

pub fn signed(&mut self, lower: i64, upper: i64) -> Result<i64, Error>

A constrained whole number of lower..=upper, where the bounds may be negative.

Source

pub fn unsigned_extensible( &mut self, lower: u64, upper: u64, ) -> Result<u64, Error>

An INTEGER whose constraint lower..=upper has an extension marker (X.691 §13.1): a bit, then the number within the constraint, or any number as an unconstrained one. The bindings hold it in 64 bits without a sign.

§Errors

A number outside the constraint that is negative, or of more than 64 bits, is an error: the bindings have no type for it.

Source

pub fn signed_extensible( &mut self, lower: i64, upper: i64, ) -> Result<i64, Error>

An INTEGER whose constraint lower..=upper has an extension marker, where the bounds may be negative. The bindings hold it in 64 bits with a sign.

Source

pub fn unconstrained(&mut self) -> Result<i64, Error>

An unconstrained whole number (X.691 §11.8), as an INTEGER without a PER-visible constraint is encoded (§13.2.4): the number of its octets, then its octets in two’s complement.

Source

pub fn semi_constrained(&mut self, lower: i64) -> Result<i64, Error>

A semi-constrained whole number (X.691 §11.7), as an INTEGER with a lower bound and no upper one is encoded (§13.2.3): the number of the octets of what it has above lower, then these octets.

Source

pub fn semi_constrained_unsigned(&mut self, lower: u64) -> Result<u64, Error>

A semi-constrained whole number whose lower bound is not negative, in 64 bits without a sign.

Source

pub fn small(&mut self) -> Result<u64, Error>

A normally small non-negative whole number (X.691 §11.6): the index of an alternative or of a value that a later version adds.

Source

pub fn length(&mut self) -> Result<(usize, bool), Error>

An unconstrained length determinant (X.691 §11.9.3.5 to §11.9.3.8): how many items follow it, and whether another length follows these items, which then are a fragment of one to four times 16K items.

use oxirush_aper::Reader;

// 5, then 130 in two octets, then a fragment of 16384
let mut reader = Reader::new(&[0x05, 0x80, 0x82, 0xc1]);
assert_eq!(reader.length()?, (5, false));
assert_eq!(reader.length()?, (130, false));
assert_eq!(reader.length()?, (16384, true));
Source

pub fn length_after(&mut self, fragment: usize) -> Result<(usize, bool), Error>

The length determinant that follows a fragment of fragment items, as length reads it: how many items follow it, and whether they are a fragment too.

A fragment is the largest that the items allow (X.691 §11.9.3.8.1), so the one before another has four times 16K items. A smaller one is read, and a reader that notes its faults notes it.

use oxirush_aper::{Fault, Reader};

// 32768 items in two fragments of 16384, where one fragment holds them
let mut reader = Reader::noting(&[0xc1, 0xc1, 0x00]);
let (first, _) = reader.length()?;
let (second, _) = reader.length_after(first)?;
assert_eq!(reader.length_after(second)?, (0, false));
assert_eq!(reader.faults()[0].fault, Fault::SmallFragment);
Source

pub fn size(&mut self, lower: usize, upper: usize) -> Result<usize, Error>

The size of a string or of a list whose size constraint is lower..=upper, with an upper bound below 64K: a constrained whole number (X.691 §11.9.3.3). For a size of one value there is no field.

Source

pub fn check_size(size: usize, lower: usize, upper: usize) -> Result<(), Error>

Whether size, which was read after an unconstrained length, is within the size constraint lower..=upper: the elements of a list in fragments are counted by its reader.

Source

pub fn enumerated( &mut self, root: u64, additions: u64, extensible: bool, ) -> Result<u64, Error>

The index of a value of an ENUMERATED (X.691 §14) that has root values before its extension marker and additions after it, when it is extensible. The values are counted in the order of their numbers, those of the root first: the first addition has the index root.

§Errors

An index that no value has is an error: a field of two bits holds four indexes for three values, and a later version may add a value.

Source

pub fn choice( &mut self, root: u64, additions: u64, extensible: bool, ) -> Result<u64, Error>

The index of the alternative of a CHOICE (X.691 §23) that has root alternatives before its extension marker and additions after it, when it is extensible. The first addition has the index root, and its value follows in an open type.

§Errors

An index that no alternative has is an error.

Source

pub fn skip_additions(&mut self) -> Result<(), Error>

Skip the extension additions of a SEQUENCE whose extension bit is set (X.691 §19.7 to §19.9): the bitmap of their presence, then an open type for each one that is present. A later version of a specification adds them, and a reader of an earlier one does not know them.

use oxirush_aper::Reader;

// Two additions that this reader does not know, the second present, then the
// octet of what follows the SEQUENCE
let mut reader = Reader::new(&[0b0000_0010, 0b1000_0000, 0x01, 0xaa, 0x07]);
reader.skip_additions()?;
assert_eq!(reader.unsigned(0, 255)?, 7);

// A bitmap of two additions of which none is present has no encoding
assert!(Reader::new(&[0b0000_0010, 0b0000_0000]).skip_additions().is_err());
§Errors

What the clauses give no encoding for is an error: a bitmap of no bit or of which no bit is set, as the extension bit is set when an addition is present (§19.1, §19.8); a bitmap of 64 bits at most whose length is in the form of more (§11.9.3.4); and an addition of no octet (§11.1.3.1).

Source

pub fn additions(&mut self) -> Result<Additions<'a>, Error>

The extension additions of a SEQUENCE whose extension bit is set: which of them are present. Each one that is present follows in an open type, in their order. The bitmap is refused as skip_additions refuses it.

use oxirush_aper::Reader;

// Two additions, of which the second is present: an open type of one octet
let mut reader = Reader::new(&[0b0000_0010, 0b1000_0000, 0x01, 0xaa]);
let mut additions = reader.additions()?;
assert!(!additions.present());
assert!(additions.present());
assert_eq!(reader.open_type()?, [0xaa]);
additions.skip_rest(&mut reader)?;
Source

pub fn octet_array<const N: usize>(&mut self) -> Result<[u8; N], Error>

An OCTET STRING of N octets (X.691 §17.6, §17.7): a bit-field for two octets at most, and octet-aligned otherwise.

Source

pub fn octet_string( &mut self, lower: usize, upper: usize, ) -> Result<Octets<'a>, Error>

An OCTET STRING of the size constraint lower..=upper (X.691 §17), with UNBOUNDED for no upper bound. The octets are borrowed.

A string of 16384 octets or more is in fragments when its size has no bound below 64K, and is then copied.

Source

pub fn octet_string_extensible( &mut self, lower: usize, upper: usize, ) -> Result<Octets<'a>, Error>

An OCTET STRING whose size constraint lower..=upper has an extension marker (X.691 §17.3): a bit, then the string within the constraint, or a string of any size.

Source

pub fn open_type(&mut self) -> Result<Octets<'a>, Error>

The octets of an open type (X.691 §11.2): the complete encoding of a value, after its length. The octets are borrowed, unless they are in fragments.

A value that is decoded from an open type borrows from the input too, when it is read from the octets that Octets::as_borrowed gives: they live as long as the input. An open type of 16384 octets or more comes in fragments, which are gathered: it owns its octets, and what is decoded from it is copied out.

use oxirush_aper::{Error, Octets, Reader};

// The OCTET STRING (SIZE (0..255)) that an open type holds
fn held(input: &[u8]) -> Result<Octets<'_>, Error> {
    let open = Reader::new(input).open_type()?;
    match open.as_borrowed() {
        // In one piece: the string is a part of `input`
        Some(octets) => Reader::new(octets).octet_string(0, 255),
        // Gathered from fragments: the string is copied out of them
        None => Ok(Reader::new(&open).octet_string(0, 255)?.into_owned()),
    }
}

let string = held(&[0x03, 0x02, 0xab, 0xcd])?;
assert_eq!(format!("{string:?}"), "abcd");
assert!(string.is_borrowed());
Source

pub fn bits_sized(&mut self, lower: usize, upper: usize) -> Result<Bits, Error>

A BIT STRING of 64 bits at most, of the size constraint lower..=upper (X.691 §16.9 to §16.11): a bit-field for one size of 16 bits at most, and octet-aligned otherwise, after its length when its size varies.

Source

pub fn bit_string( &mut self, lower: usize, upper: usize, ) -> Result<BitString<'a>, Error>

A BIT STRING of the size constraint lower..=upper (X.691 §16), with UNBOUNDED for no upper bound. The octets are borrowed where the string is octet-aligned, and one of 64 bits at most is held without an allocation.

A string of 16384 bits or more is in fragments when its size has no bound below 64K, and is then copied.

Source

pub fn bit_string_extensible( &mut self, lower: usize, upper: usize, ) -> Result<BitString<'a>, Error>

A BIT STRING whose size constraint lower..=upper has an extension marker (X.691 §16.6): a bit, then the string within the constraint, or a string of any size.

Source

pub fn printable_string( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

A PrintableString of the size constraint lower..=upper (X.691 §30.5), with UNBOUNDED for no upper bound: a character is eight bits in the aligned variant.

Source

pub fn printable_string_extensible( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

A PrintableString whose size constraint has an extension marker (X.691 §30.4).

Source

pub fn visible_string( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

A VisibleString of the size constraint lower..=upper, with UNBOUNDED for no upper bound.

Source

pub fn visible_string_extensible( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

A VisibleString whose size constraint has an extension marker.

Source

pub fn ia5_string( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

An IA5String of the size constraint lower..=upper, with UNBOUNDED for no upper bound.

Source

pub fn ia5_string_extensible( &mut self, lower: usize, upper: usize, ) -> Result<Cow<'a, str>, Error>

An IA5String whose size constraint has an extension marker.

Source

pub fn utf8_string(&mut self) -> Result<Cow<'a, str>, Error>

A UTF8String (X.691 §30.6): the length of its octets, then its octets. A size constraint on it is not PER-visible (§10.3.7), and is not looked at.

Source

pub fn object_identifier(&mut self) -> Result<ObjectIdentifier, Error>

An OBJECT IDENTIFIER (X.691 §24): the length of its contents octets, then the contents octets that the Basic Encoding Rules give it.

Source

pub fn list<T>(&self, count: usize) -> Vec<T>

An empty list that has room for count elements, as far as the octets that are left may hold them: a count that a peer claims reserves little.

Trait Implementations§

Source§

impl<'a> Clone for Reader<'a>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Reader<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Reader<'a>

§

impl<'a> RefUnwindSafe for Reader<'a>

§

impl<'a> Send for Reader<'a>

§

impl<'a> Sync for Reader<'a>

§

impl<'a> Unpin for Reader<'a>

§

impl<'a> UnsafeUnpin for Reader<'a>

§

impl<'a> UnwindSafe for Reader<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.