Trait buffered_reader::BufferedReader
source · pub trait BufferedReader<C>: Read + Debug + Display + Send + Sync{
Show 27 methods
// Required methods
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;
// Provided methods
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 copy(&mut self, sink: &mut dyn Write) -> Result<u64> { ... }
fn dump(&self, sink: &mut dyn Write) -> Result<()>
where Self: Sized { ... }
fn into_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>
where Self: 'a + Sized { ... }
fn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>
where Self: 'a + Sized { ... }
}
Expand description
The generic BufferReader
interface.
Required Methods§
sourcefn buffer(&self) -> &[u8] ⓘ
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);
sourcefn data(&mut self, amount: usize) -> Result<&[u8], Error>
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 BufferedReader::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 BufferedReader::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 read
ing, 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);
sourcefn consume(&mut self, amount: usize) -> &[u8] ⓘ
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 BufferedReader::data
or a related function.
Note: It is safe to call this function to consume more data
than requested in a previous call to BufferedReader::data
, but only if
BufferedReader::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);
sourcefn into_inner<'a>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'a>>where
Self: 'a,
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();
Note: if Self
is not actually owned, e.g., you passed a
reference, then this returns None
as it is not possible to
consume the outer buffered reader. Consider:
let mut mem = Memory::new(DATA);
let mut limitor = Limitor::new(mem, 20);
let mut br = Box::new(&mut limitor);
// br doesn't owned limitor, so it can't consume it.
assert!(matches!(br.into_inner(), None));
let mut mem = Memory::new(DATA);
let mut limitor = Limitor::new(mem, 20);
let mut br = Box::new(limitor);
assert!(matches!(br.into_inner(), Some(_)));
sourcefn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>
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.
sourcefn get_ref(&self) -> Option<&dyn BufferedReader<C>>
fn get_ref(&self) -> Option<&dyn BufferedReader<C>>
Returns a reference to the inner BufferedReader
, if any.
Sets the BufferedReader
’s cookie and returns the old value.
Returns a reference to the BufferedReader
’s cookie.
Returns a mutable reference to the BufferedReader
’s cookie.
Provided Methods§
sourcefn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>
Like BufferedReader::data
, but returns an error if there is not at least
amount
bytes available.
BufferedReader::data_hard
is a variant of BufferedReader::data
that returns at least
amount
bytes of data or an error. Thus, unlike BufferedReader::data
,
which will return less than amount
bytes of data if EOF is
encountered, BufferedReader::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);
sourcefn data_eof(&mut self) -> Result<&[u8], Error>
fn data_eof(&mut self) -> Result<&[u8], Error>
Returns all of the data until EOF. Like BufferedReader::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);
sourcefn data_consume(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_consume(&mut self, amount: usize) -> Result<&[u8], Error>
A convenience function that combines BufferedReader::data
and BufferedReader::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
BufferedReader::data
, work with the returned buffer, and then call
BufferedReader::consume
in the same scope, because both BufferedReader::data
and
BufferedReader::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 [`BufferedReader::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 [`BufferedReader::data`], [`BufferedReader::data_consume`] may return and consume less
// than requested 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);
}
sourcefn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>
A convenience function that effectively combines BufferedReader::data_hard
and BufferedReader::consume
.
This function is identical to BufferedReader::data_consume
, but internally
uses BufferedReader::data_hard
instead of BufferedReader::data
.
sourcefn consummated(&mut self) -> bool
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.
sourcefn read_be_u16(&mut self) -> Result<u16, Error>
fn read_be_u16(&mut self) -> Result<u16, Error>
A convenience function for reading a 16-bit unsigned integer in big endian format.
sourcefn read_be_u32(&mut self) -> Result<u32, Error>
fn read_be_u32(&mut self) -> Result<u32, Error>
A convenience function for reading a 32-bit unsigned integer in big endian format.
sourcefn read_to(&mut self, terminal: u8) -> Result<&[u8], Error>
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");
}
// [`BufferedReader::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");
}
sourcefn drop_until(&mut self, terminals: &[u8]) -> Result<usize, Error>
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.
sourcefn drop_through(
&mut self,
terminals: &[u8],
match_eof: bool
) -> Result<(Option<u8>, usize), Error>
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.
sourcefn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error>
fn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error>
Like BufferedReader::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.
sourcefn steal_eof(&mut self) -> Result<Vec<u8>, Error>
fn steal_eof(&mut self) -> Result<Vec<u8>, Error>
Like BufferedReader::steal
, but instead of stealing a fixed number of
bytes, steals all of the data until the end of file.
sourcefn drop_eof(&mut self) -> Result<bool, Error>
fn drop_eof(&mut self) -> Result<bool, Error>
Like BufferedReader::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 BufferedReader::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.
sourcefn copy(&mut self, sink: &mut dyn Write) -> Result<u64>
fn copy(&mut self, sink: &mut dyn Write) -> Result<u64>
Copies data to the given writer returning the copied amount.
This is like using std::io::copy
, but more efficient as it
avoids an extra copy, and it will try to copy all the data the
reader has already buffered.
On success, returns the amount of data (in bytes) that has been copied.
Note: this function reads and copies the data a chunk at a time. A consequence of this is that an error may occur after we have consumed some of the data.
sourcefn dump(&self, sink: &mut dyn Write) -> Result<()>where
Self: Sized,
fn dump(&self, sink: &mut dyn Write) -> Result<()>where
Self: Sized,
A helpful debugging aid to pretty print a Buffered Reader stack.
Uses the Buffered Readers’ fmt::Display
implementations.
sourcefn into_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>where
Self: 'a + Sized,
fn into_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>where
Self: 'a + Sized,
Boxes the reader.
sourcefn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>where
Self: 'a + Sized,
👎Deprecated: Use into_boxed
fn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a>where
Self: 'a + Sized,
Boxes the reader.
Trait Implementations§
source§impl<'a, C: Debug + Sync + Send> BufferedReader<C> for Box<dyn BufferedReader<C> + 'a>
impl<'a, C: Debug + Sync + Send> BufferedReader<C> for Box<dyn BufferedReader<C> + 'a>
Make a Box<BufferedReader>
look like a BufferedReader.
source§fn data(&mut self, amount: usize) -> Result<&[u8], Error>
fn data(&mut self, amount: usize) -> Result<&[u8], Error>
amount
bytes
of data, and returns it. Read moresource§fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>
BufferedReader::data
, but returns an error if there is not at least
amount
bytes available. Read moresource§fn data_eof(&mut self) -> Result<&[u8], Error>
fn data_eof(&mut self) -> Result<&[u8], Error>
BufferedReader::data
, this does not
actually consume the data that is read. Read moresource§fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>
BufferedReader::data_hard
and BufferedReader::consume
. Read moresource§fn consummated(&mut self) -> bool
fn consummated(&mut self) -> bool
source§fn read_be_u16(&mut self) -> Result<u16, Error>
fn read_be_u16(&mut self) -> Result<u16, Error>
source§fn read_be_u32(&mut self) -> Result<u32, Error>
fn read_be_u32(&mut self) -> Result<u32, Error>
source§fn read_to(&mut self, terminal: u8) -> Result<&[u8], Error>
fn read_to(&mut self, terminal: u8) -> Result<&[u8], Error>
terminal
is encountered or EOF. Read moresource§fn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error>
fn steal(&mut self, amount: usize) -> Result<Vec<u8>, Error>
BufferedReader::data_consume_hard
, but returns the data in a
caller-owned buffer. Read moresource§fn steal_eof(&mut self) -> Result<Vec<u8>, Error>
fn steal_eof(&mut self) -> Result<Vec<u8>, Error>
BufferedReader::steal
, but instead of stealing a fixed number of
bytes, steals all of the data until the end of file.source§fn drop_eof(&mut self) -> Result<bool, Error>
fn drop_eof(&mut self) -> Result<bool, Error>
BufferedReader::steal_eof
, but instead of returning the data, the
data is discarded. Read moresource§fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>
fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>
BufferedReader
, if
any. Read moresource§fn get_ref(&self) -> Option<&dyn BufferedReader<C>>
fn get_ref(&self) -> Option<&dyn BufferedReader<C>>
BufferedReader
, if any.source§fn into_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
fn into_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
source§fn as_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
fn as_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
source§fn into_inner<'b>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'b>>where
Self: 'b,
fn into_inner<'b>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'b>>where
Self: 'b,
BufferedReader
’s cookie and returns the old value.BufferedReader
’s cookie.BufferedReader
’s cookie.source§fn drop_until(&mut self, terminals: &[u8]) -> Result<usize, Error>
fn drop_until(&mut self, terminals: &[u8]) -> Result<usize, Error>
source§fn drop_through(
&mut self,
terminals: &[u8],
match_eof: bool
) -> Result<(Option<u8>, usize), Error>
fn drop_through( &mut self, terminals: &[u8], match_eof: bool ) -> Result<(Option<u8>, usize), Error>
terminals
is
encountered. Read moreImplementations on Foreign Types§
source§impl<'a, C: Debug + Sync + Send> BufferedReader<C> for Box<dyn BufferedReader<C> + 'a>
impl<'a, C: Debug + Sync + Send> BufferedReader<C> for Box<dyn BufferedReader<C> + 'a>
Make a Box<BufferedReader>
look like a BufferedReader.
fn buffer(&self) -> &[u8] ⓘ
fn data(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_hard(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_eof(&mut self) -> Result<&[u8], Error>
fn consume(&mut self, amount: usize) -> &[u8] ⓘ
fn data_consume(&mut self, amount: usize) -> Result<&[u8], Error>
fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], Error>
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 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 get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>>
fn get_ref(&self) -> Option<&dyn BufferedReader<C>>
fn into_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
source§fn as_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
fn as_boxed<'b>(self) -> Box<dyn BufferedReader<C> + 'b>where
Self: 'b,
fn into_inner<'b>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'b>>where
Self: 'b,
source§impl<'a, T, C> BufferedReader<C> for &'a mut T
impl<'a, T, C> BufferedReader<C> for &'a mut T
Make a &mut T
where T
implements BufferedReader
look like a
BufferedReader.