[][src]Trait buffered_reader::BufferedReader

pub trait BufferedReader<C>: Read + Debug + Display {
    fn buffer(&self) -> &[u8];
fn data(&mut self, amount: usize) -> Result<&[u8], Error>;
fn consume(&mut self, amount: usize) -> &[u8];
fn into_inner<'a>(
        self: Box<Self>
    ) -> Option<Box<dyn BufferedReader<C> + 'a>>
    where
        Self: 'a
;
fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>;
fn get_ref(&self) -> Option<&dyn BufferedReader<C>>;
fn cookie_set(&mut self, cookie: C) -> C;
fn cookie_ref(&self) -> &C;
fn cookie_mut(&mut self) -> &mut C; fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error> { ... }
fn data_eof(&mut self) -> Result<&[u8], Error> { ... }
fn data_consume(&mut self, amount: usize) -> Result<&[u8], Error> { ... }
fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error> { ... }
fn eof(&mut self) -> bool { ... }
fn consummated(&mut self) -> bool { ... }
fn read_be_u16(&mut self) -> Result<u16, Error> { ... }
fn read_be_u32(&mut self) -> Result<u32, Error> { ... }
fn read_to(&mut self, terminal: u8) -> Result<&[u8], Error> { ... }
fn drop_until(&mut self, terminals: &[u8]) -> Result<usize, Error> { ... }
fn drop_through(
        &mut self,
        terminals: &[u8],
        match_eof: bool
    ) -> Result<(Option<u8>, usize), Error> { ... }
fn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error> { ... }
fn steal_eof(&mut self) -> Result<Vec<u8>, Error> { ... }
fn drop_eof(&mut self) -> Result<bool, Error> { ... }
fn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>
    where
        Self: 'a + Sized
, { ... } }

The generic BufferReader interface.

Required methods

fn buffer(&self) -> &[u8]

Returns a reference to the internal buffer.

Note: this returns the same data as self.data(0), but it does so without mutably borrowing self:

use buffered_reader;
use buffered_reader::BufferedReader;

let mut br = buffered_reader::Memory::new(&b"0123456789"[..]);

let first = br.data(10)?.len();
let second = br.buffer().len();
// `buffer` must return exactly what `data` returned.
assert_eq!(first, second);

fn data(&mut self, amount: usize) -> Result<&[u8], Error>

Ensures that the internal buffer has at least amount bytes of data, and returns it.

If the internal buffer contains less than amount bytes of data, the internal buffer is first filled.

The returned slice will have at least amount bytes unless EOF has been reached or an error occurs, in which case the returned slice will contain the rest of the file.

Errors are returned only when the internal buffer is empty.

This function does not advance the cursor. To advance the cursor, use consume().

Note: If the internal buffer already contains at least amount bytes of data, then BufferedReader implementations are guaranteed to simply return the internal buffer. As such, multiple calls to data for the same amount will return the same slice.

Further, BufferedReader implementations are guaranteed to not shrink the internal buffer. Thus, once some data has been returned, it will always be returned until it is consumed. As such, the following must hold:

If BufferedReader receives EINTR when reading, it will automatically retry reading.

use buffered_reader;
use buffered_reader::BufferedReader;

let mut br = buffered_reader::Memory::new(&b"0123456789"[..]);

let first = br.data(10)?.len();
let second = br.data(5)?.len();
// Even though less data is requested, the second call must
// return the same slice as the first call.
assert_eq!(first, second);

fn consume(&mut self, amount: usize) -> &[u8]

Consumes some of the data.

This advances the internal cursor by amount. It is an error to call this function to consume data that hasn't been returned by data() or a related function.

Note: It is safe to call this function to consume more data than requested in a previous call to data(), but only if data() also returned that data.

This function returns the internal buffer including the consumed data. Thus, the BufferedReader implementation must continue to buffer the consumed data until the reference goes out of scope.

Examples

use buffered_reader;
use buffered_reader::BufferedReader;

const AMOUNT : usize = 100 * 1024 * 1024;
let buffer = vec![0u8; AMOUNT];
let mut br = buffered_reader::Generic::new(&buffer[..], None);

let amount = {
    // We want at least 1024 bytes, but we'll be happy with
    // more or less.
    let buffer = br.data(1024)?;
    // Parse the data or something.
    let used = buffer.len();
    used
};
let buffer = br.consume(amount);

fn into_inner<'a>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'a>> where
    Self: 'a, 

Returns the underlying reader, if any.

To allow this to work with BufferedReader traits, it is necessary for Self to be boxed.

This can lead to the following unusual code:

let inner = Box::new(br).into_inner();

fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>

Returns a mutable reference to the inner BufferedReader, if any.

It is a very bad idea to read any data from the inner BufferedReader, because this BufferedReader may have some data buffered. However, this function can be useful to get the cookie.

fn get_ref(&self) -> Option<&dyn BufferedReader<C>>

Returns a reference to the inner BufferedReader, if any.

fn cookie_set(&mut self, cookie: C) -> C

Sets the BufferedReader's cookie and returns the old value.

fn cookie_ref(&self) -> &C

Returns a reference to the BufferedReader's cookie.

fn cookie_mut(&mut self) -> &mut C

Returns a mutable reference to the BufferedReader's cookie.

Loading content...

Provided methods

fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>

Like data(), but returns an error if there is not at least amount bytes available.

data_hard() is a variant of data() that returns at least amount bytes of data or an error. Thus, unlike data(), which will return less than amount bytes of data if EOF is encountered, data_hard() returns an error, specifically, io::ErrorKind::UnexpectedEof.

Examples

use buffered_reader;
use buffered_reader::BufferedReader;

let mut br = buffered_reader::Memory::new(&b"0123456789"[..]);

// Trying to read more than there is available results in an error.
assert!(br.data_hard(20).is_err());
// Whereas with data(), everything through EOF is returned.
assert_eq!(br.data(20)?.len(), 10);

fn data_eof(&mut self) -> Result<&[u8], Error>

Returns all of the data until EOF. Like data(), this does not actually consume the data that is read.

In general, you shouldn't use this function as it can cause an enormous amount of buffering. But, if you know that the amount of data is limited, this is acceptable.

Examples

use buffered_reader;
use buffered_reader::BufferedReader;

const AMOUNT : usize = 100 * 1024 * 1024;
let buffer = vec![0u8; AMOUNT];
let mut br = buffered_reader::Generic::new(&buffer[..], None);

// Normally, only a small amount will be buffered.
assert!(br.data(10)?.len() <= AMOUNT);

// `data_eof` buffers everything.
assert_eq!(br.data_eof()?.len(), AMOUNT);

// Now that everything is buffered, buffer(), data(), and
// data_hard() will also return everything.
assert_eq!(br.buffer().len(), AMOUNT);
assert_eq!(br.data(10)?.len(), AMOUNT);
assert_eq!(br.data_hard(10)?.len(), AMOUNT);

fn data_consume(&mut self, amount: usize) -> Result<&[u8], Error>

A convenience function that combines data() and consume().

If less than amount bytes are available, this function consumes what is available.

Note: Due to lifetime issues, it is not possible to call data(), work with the returned buffer, and then call consume() in the same scope, because both data() and consume() take a mutable reference to the BufferedReader. This function makes this common pattern easier.

Examples

use buffered_reader;
use buffered_reader::BufferedReader;

let orig = b"0123456789";
let mut br = buffered_reader::Memory::new(&orig[..]);

// We need a new scope for each call to `data_consume()`, because
// the `buffer` reference locks `br`.
{
    let buffer = br.data_consume(3)?;
    assert_eq!(buffer, &orig[..buffer.len()]);
}

// Note that the cursor has advanced.
{
    let buffer = br.data_consume(3)?;
    assert_eq!(buffer, &orig[3..3 + buffer.len()]);
}

// Like `data()`, `data_consume()` may return and consume less
// than request if there is no more data available.
{
    let buffer = br.data_consume(10)?;
    assert_eq!(buffer, &orig[6..6 + buffer.len()]);
}

{
    let buffer = br.data_consume(10)?;
    assert_eq!(buffer.len(), 0);
}

fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>

A convenience function that effectively combines data_hard() and consume().

This function is identical to data_consume(), but internally uses data_hard() instead of data().

fn eof(&mut self) -> bool

Checks whether the end of the stream is reached.

fn consummated(&mut self) -> bool

Checks whether this reader is consummated.

For most readers, this function will return true once the end of the stream is reached. However, some readers are concerned with packet framing (e.g. the Limitor). Those readers consider themselves consummated if the amount of data indicated by the packet frame is consumed.

This allows us to detect truncation. A packet is truncated, iff the end of the stream is reached, but the reader is not consummated.

fn read_be_u16(&mut self) -> Result<u16, Error>

A convenience function for reading a 16-bit unsigned integer in big endian format.

fn read_be_u32(&mut self) -> Result<u32, Error>

A convenience function for reading a 32-bit unsigned integer in big endian format.

fn read_to(&mut self, terminal: u8) -> Result<&[u8], Error>

Reads until either terminal is encountered or EOF.

Returns either a &[u8] terminating in terminal or the rest of the data, if EOF was encountered.

Note: this function does not consume the data.

Examples

use buffered_reader;
use buffered_reader::BufferedReader;

let orig = b"0123456789";
let mut br = buffered_reader::Memory::new(&orig[..]);

{
    let s = br.read_to(b'3')?;
    assert_eq!(s, b"0123");
}

// `read_to()` doesn't consume the data.
{
    let s = br.read_to(b'5')?;
    assert_eq!(s, b"012345");
}

// Even if there is more data in the internal buffer, only
// the data through the match is returned.
{
    let s = br.read_to(b'1')?;
    assert_eq!(s, b"01");
}

// If the terminal is not found, everything is returned...
{
    let s = br.read_to(b'A')?;
    assert_eq!(s, orig);
}

// If we consume some data, the search starts at the cursor,
// not the beginning of the file.
br.consume(3);

{
    let s = br.read_to(b'5')?;
    assert_eq!(s, b"345");
}

fn drop_until(&mut self, terminals: &[u8]) -> Result<usize, Error>

Discards the input until one of the bytes in terminals is encountered.

The matching byte is not discarded.

Returns the number of bytes discarded.

The end of file is considered a match.

terminals must be sorted.

fn drop_through(
    &mut self,
    terminals: &[u8],
    match_eof: bool
) -> Result<(Option<u8>, usize), Error>

Discards the input until one of the bytes in terminals is encountered.

The matching byte is also discarded.

Returns the terminal byte and the number of bytes discarded.

If match_eof is true, then the end of file is considered a match. Otherwise, if the end of file is encountered, an error is returned.

terminals must be sorted.

fn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error>

Like data_consume_hard(), but returns the data in a caller-owned buffer.

BufferedReader implementations may optimize this to avoid a copy by directly returning the internal buffer.

fn steal_eof(&mut self) -> Result<Vec<u8>, Error>

Like steal(), but instead of stealing a fixed number of bytes, steals all of the data until the end of file.

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

Like steal_eof(), but instead of returning the data, the data is discarded.

On success, returns whether any data (i.e., at least one byte) was discarded.

Note: whereas steal_eof() needs to buffer all of the data, this function reads the data a chunk at a time, and then discards it. A consequence of this is that an error may occur after we have consumed some of the data.

fn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a> where
    Self: 'a + Sized

Boxes the reader.

Loading content...

Implementations on Foreign Types

impl<'a, C> BufferedReader<C> for Box<dyn BufferedReader<C> + 'a>[src]

Make a Box<BufferedReader> look like a BufferedReader.

Loading content...

Implementors

impl<'a, C> BufferedReader<C> for File<'a, C>[src]

impl<'a, C> BufferedReader<C> for Memory<'a, C>[src]

impl<C> BufferedReader<C> for EOF<C>[src]

impl<R: BufferedReader<C>, C> BufferedReader<C> for Bzip<R, C>[src]

impl<R: BufferedReader<C>, C> BufferedReader<C> for Deflate<R, C>[src]

impl<R: BufferedReader<C>, C> BufferedReader<C> for Zlib<R, C>[src]

impl<T: BufferedReader<C>, C> BufferedReader<C> for Dup<T, C>[src]

impl<T: BufferedReader<C>, C> BufferedReader<C> for Limitor<T, C>[src]

fn data(&mut self, amount: usize) -> Result<&[u8], Error>[src]

Return the buffer. Ensure that it contains at least amount bytes.

impl<T: BufferedReader<C>, C> BufferedReader<C> for Reserve<T, C>[src]

fn data(&mut self, amount: usize) -> Result<&[u8], Error>[src]

Return the buffer. Ensure that it contains at least amount bytes.

impl<T: Read, C> BufferedReader<C> for Generic<T, C>[src]

Loading content...