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

A type for reading messages from a slice of bytes.

Unlike io::Read, this object has a simpler error type, and is designed for in-memory parsing only.

The methods in Reader should never panic, with one exception: the extract and extract_n methods will panic if the underlying Readable object’s take_from method panics.

Examples

You can use a Reader to extract information byte-by-byte:

use tor_bytes::{Reader,Result};
let msg = [ 0x00, 0x01, 0x23, 0x45, 0x22, 0x00, 0x00, 0x00 ];
let mut r = Reader::from_slice(&msg[..]);
// Multi-byte values are always big-endian.
assert_eq!(r.take_u32()?, 0x12345);
assert_eq!(r.take_u8()?, 0x22);

// You can check on the length of the message...
assert_eq!(r.total_len(), 8);
assert_eq!(r.consumed(), 5);
assert_eq!(r.remaining(), 3);
// then skip over a some bytes...
r.advance(3)?;
// ... and check that the message is really exhausted.
r.should_be_exhausted()?;

You can also use a Reader to extract objects that implement Readable.

use tor_bytes::{Reader,Result,Readable};
use std::net::Ipv4Addr;
let msg = [ 0x00, 0x04, 0x7f, 0x00, 0x00, 0x01];
let mut r = Reader::from_slice(&msg[..]);

let tp: u16 = r.extract()?;
let ip: Ipv4Addr = r.extract()?;
assert_eq!(tp, 4);
assert_eq!(ip, Ipv4Addr::LOCALHOST);

Implementations

Construct a new Reader from a slice of bytes.

Construct a new Reader from a ‘Bytes’ object.

Return the total length of the slice in this reader, including consumed bytes and remaining bytes.

Return the total number of bytes in this reader that have not yet been read.

Consume this reader, and return a slice containing the remaining bytes from its slice that it did not consume.

Return the total number of bytes in this reader that have already been read.

Skip n bytes from the reader.

Returns Ok on success. Returns Err(Error::Truncated) if there were not enough bytes to skip.

Check whether this reader is exhausted (out of bytes).

Return Ok if it is, and Err(Error::ExtraneousBytes) if there were extra bytes.

Truncate this reader, so that no more than n bytes remain.

Fewer than n bytes may remain if there were not enough bytes to begin with.

Try to return a slice of n bytes from this reader without consuming them.

On success, returns Ok(slice). If there are fewer than n bytes, returns Err(Error::Truncated).

Try to consume and return a slice of n bytes from this reader.

On success, returns Ok(Slice). If there are fewer than n bytes, returns Err(Error::Truncated).

Example
use tor_bytes::{Reader,Result};
let m = b"Hello World";
let mut r = Reader::from_slice(m);
assert_eq!(r.take(5)?, b"Hello");
assert_eq!(r.take_u8()?, 0x20);
assert_eq!(r.take(5)?, b"World");
r.should_be_exhausted()?;

Try to fill a provided buffer with bytes consumed from this reader.

On success, the buffer will be filled with data from the reader, the reader will advance by the length of the buffer, and we’ll return Ok(()). On failure the buffer will be unchanged.

Example
use tor_bytes::Reader;
let m = b"Hello world";
let mut v1 = vec![0; 5];
let mut v2 = vec![0; 5];
let mut r = Reader::from_slice(m);
r.take_into(&mut v1[..])?;
assert_eq!(r.take_u8()?, b' ');
r.take_into(&mut v2[..])?;
assert_eq!(&v1[..], b"Hello");
assert_eq!(&v2[..], b"world");
r.should_be_exhausted()?;

Try to consume and return a u8 from this reader.

Try to consume and return a big-endian u16 from this reader.

Try to consume and return a big-endian u32 from this reader.

Try to consume and return a big-endian u64 from this reader.

Try to consume and return a big-endian u128 from this reader.

Try to consume and return bytes from this buffer until we encounter a terminating byte equal to term.

On success, returns Ok(Slice), where the slice does not include the terminating byte. Returns Err(Error::Truncated) if we do not find the terminating bytes.

Advances the reader to the point immediately after the terminating byte.

Example
use tor_bytes::{Reader,Result};
let m = b"Hello\0wrld";
let mut r = Reader::from_slice(m);
assert_eq!(r.take_until(0)?, b"Hello");
assert_eq!(r.into_rest(), b"wrld");

Consume and return all the remaining bytes, but do not consume the reader

This can be useful if you need to possibly read either fixed-length data, or variable length data eating the rest of the Reader.

The Reader will be left devoid of further bytes. Consider using into_rest() instead.

Try to decode and remove a Readable from this reader, using its take_from() method.

On failure, consumes nothing.

Try to decode and remove n Readables from this reader, using the Readable’s take_from() method.

On failure, consumes nothing.

Decode something with a u8 length field

Prefer to use this function, rather than ad-hoc take_u8 and subsequent manual length checks. Using this facility eliminates the need to separately keep track of the lengths.

read_nested consumes a length field, and provides the closure f with an inner Reader that contains precisely that many bytes - the bytes which follow the length field in the original reader. If the closure is successful, read_nested checks that that inner reader is exhausted, i.e. that the inner contents had the same length as was specified.

The closure should read whatever is inside the nested structure from the nested reader. It may well want to use take_rest, to consume all of the counted bytes.

On failure, the amount consumed is not specified.

Start decoding something with a u16 length field

Start decoding something with a u32 length field

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

Should always be Self

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.