Struct sequoia_openpgp::parse::PacketParser
source · [−]pub struct PacketParser<'a> {
pub packet: Packet,
/* private fields */
}
Expand description
A low-level OpenPGP message parser.
A PacketParser
provides a low-level, iterator-like interface to
parse OpenPGP messages.
For each iteration, the user is presented with a Packet
corresponding to the last packet, a PacketParser
for the next
packet, and their positions within the message.
Using the PacketParser
, the user is able to configure how the
new packet will be parsed. For instance, it is possible to stream
the packet’s contents (a PacketParser
implements the
std::io::Read
and the BufferedReader
traits), buffer them
within the Packet
, or drop them. The user can also decide to
recurse into the packet, if it is a container, instead of getting
the following packet.
See the PacketParser::next
and PacketParser::recurse
methods for more details.
Examples
These examples demonstrate how to process packet bodies by parsing the simplest possible OpenPGP message containing just a single literal data packet with the body “Hello world.”. There are three options. First, the body can be dropped. Second, it can be buffered. Lastly, the body can be streamed. In general, streaming should be preferred, because it avoids buffering in Sequoia.
This example demonstrates simply ignoring the packet body:
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// By default, the `PacketParser` will drop packet bodies.
let mut ppr =
PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
while let PacketParserResult::Some(pp) = ppr {
// Get the packet out of the parser and start parsing the next
// packet, recursing.
let (packet, next_ppr) = pp.recurse()?;
ppr = next_ppr;
// Process the packet.
if let Packet::Literal(literal) = packet {
// The body was dropped.
assert_eq!(literal.body(), b"");
} else {
unreachable!("We know it is a literal packet.");
}
}
This example demonstrates how the body can be buffered by
configuring the PacketParser
to buffer all packet bodies:
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParserBuilder};
// By default, the `PacketParser` will drop packet bodies. Use a
// `PacketParserBuilder` to change that.
let mut ppr =
PacketParserBuilder::from_bytes(
b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?
.buffer_unread_content()
.build()?;
while let PacketParserResult::Some(pp) = ppr {
// Get the packet out of the parser and start parsing the next
// packet, recursing.
let (packet, next_ppr) = pp.recurse()?;
ppr = next_ppr;
// Process the packet.
if let Packet::Literal(literal) = packet {
// The body was buffered.
assert_eq!(literal.body(), b"Hello world.");
} else {
unreachable!("We know it is a literal packet.");
}
}
This example demonstrates how the body can be buffered by buffering an individual packet:
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// By default, the `PacketParser` will drop packet bodies.
let mut ppr =
PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
while let PacketParserResult::Some(mut pp) = ppr {
if let Packet::Literal(_) = pp.packet {
// Buffer this packet's body.
pp.buffer_unread_content()?;
}
// Get the packet out of the parser and start parsing the next
// packet, recursing.
let (packet, next_ppr) = pp.recurse()?;
ppr = next_ppr;
// Process the packet.
if let Packet::Literal(literal) = packet {
// The body was buffered.
assert_eq!(literal.body(), b"Hello world.");
} else {
unreachable!("We know it is a literal packet.");
}
}
This example demonstrates how to stream the packet body:
use std::io::Read;
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
let mut ppr =
PacketParser::from_bytes(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.")?;
while let PacketParserResult::Some(mut pp) = ppr {
if let Packet::Literal(_) = pp.packet {
// Stream the body.
let mut buf = Vec::new();
pp.read_to_end(&mut buf)?;
assert_eq!(buf, b"Hello world.");
} else {
unreachable!("We know it is a literal packet.");
}
// Get the packet out of the parser and start parsing the next
// packet, recursing.
let (packet, next_ppr) = pp.recurse()?;
ppr = next_ppr;
// Process the packet.
if let Packet::Literal(literal) = packet {
// The body was streamed, not buffered.
assert_eq!(literal.body(), b"");
} else {
unreachable!("We know it is a literal packet.");
}
}
Packet Parser Design
There are two major concerns that inform the design of the parsing API.
First, when processing a container, it is possible to either
recurse into the container, and process its children, or treat the
contents of the container as an opaque byte stream, and process
the packet following the container. The low-level
PacketParser
and mid-level PacketPileParser
abstractions
allow the caller to choose the behavior by either calling the
PacketParser::recurse
method or the PacketParser::next
method, as appropriate. OpenPGP doesn’t impose any restrictions
on the amount of nesting. So, to prevent a denial of service
attack, the parsers don’t recurse more than
DEFAULT_MAX_RECURSION_DEPTH
times, by default.
Second, packets can contain an effectively unbounded amount of
data. To avoid errors due to memory exhaustion, the
PacketParser
and PacketPileParser
abstractions support
parsing packets in a streaming manner, i.e., never buffering more
than O(1) bytes of data. To do this, the parsers initially only
parse a packet’s header (which is rarely more than a few kilobytes
of data), and return control to the caller. After inspecting that
data, the caller can decide how to handle the packet’s contents.
If the content is deemed interesting, it can be streamed or
buffered. Otherwise, it can be dropped. Streaming is possible
not only for literal data packets, but also containers (other
packets also support the interface, but just return EOF). For
instance, encryption can be stripped by saving the decrypted
content of an encryption packet, which is just an OpenPGP message.
Iterator Design
We explicitly chose to not use a callback-based API, but something
that is closer to Rust’s iterator API. Unfortunately, because a
PacketParser
needs mutable access to the input stream (so that
the content can be streamed), only a single PacketParser
item
can be live at a time (without a fair amount of unsafe nastiness).
This is incompatible with Rust’s iterator concept, which allows
any number of items to be live at any time. For instance:
let mut v = vec![1, 2, 3, 4];
let mut iter = v.iter_mut();
let x = iter.next().unwrap();
let y = iter.next().unwrap();
*x += 10; // This does not cause an error!
*y += 10;
Fields
packet: Packet
The packet that is being parsed.
Implementations
sourceimpl<'a> PacketParser<'a>
impl<'a> PacketParser<'a>
sourcepub fn processed(&self) -> bool
pub fn processed(&self) -> bool
Returns whether the packet’s contents have been processed.
This function returns true
while processing an encryption
container before it is decrypted using
PacketParser::decrypt
. Once successfully decrypted, it
returns false
.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::fmt::hex;
use openpgp::types::SymmetricAlgorithm;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse an encrypted message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
if let Packet::SEIP(_) = pp.packet {
assert!(!pp.processed());
pp.decrypt(SymmetricAlgorithm::AES256,
&hex::decode("7EF4F08C44F780BEA866961423306166\
B8912C43352F3D9617F745E4E3939710")?
.into())?;
assert!(pp.processed());
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn encrypted(&self) -> bool
👎 Deprecated since 1.10.0: Use !processed()
pub fn encrypted(&self) -> bool
Use !processed()
Returns whether the packet’s contents are encrypted.
This function has been obsoleted by the negation of
PacketParser::processed
.
sourcepub fn last_path(&self) -> &[usize]
pub fn last_path(&self) -> &[usize]
Returns the path of the last packet.
This function returns the path (see PacketPile::path_ref
for a description of paths) of the packet last returned by a
call to PacketParser::recurse
or PacketParser::next
.
If no packet has been returned (i.e. the current packet is the
first packet), this returns the empty slice.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a compressed message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
match pp.packet {
Packet::CompressedData(_) => assert_eq!(pp.last_path(), &[]),
Packet::Literal(_) => assert_eq!(pp.last_path(), &[0]),
_ => (),
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn path(&self) -> &[usize]
pub fn path(&self) -> &[usize]
Returns the path of the current packet.
This function returns the path (see PacketPile::path_ref
for a description of paths) of the packet currently being
processed (see PacketParser::packet
).
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a compressed message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
match pp.packet {
Packet::CompressedData(_) => assert_eq!(pp.path(), &[0]),
Packet::Literal(_) => assert_eq!(pp.path(), &[0, 0]),
_ => (),
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn recursion_depth(&self) -> isize
pub fn recursion_depth(&self) -> isize
The current packet’s recursion depth.
A top-level packet has a recursion depth of 0. Packets in a top-level container have a recursion depth of 1, etc.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a compressed message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
match pp.packet {
Packet::CompressedData(_) => assert_eq!(pp.recursion_depth(), 0),
Packet::Literal(_) => assert_eq!(pp.recursion_depth(), 1),
_ => (),
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn last_recursion_depth(&self) -> Option<isize>
pub fn last_recursion_depth(&self) -> Option<isize>
The last packet’s recursion depth.
A top-level packet has a recursion depth of 0. Packets in a top-level container have a recursion depth of 1, etc.
Note: if no packet has been returned yet, this returns None.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a compressed message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
match pp.packet {
Packet::CompressedData(_) => assert_eq!(pp.last_recursion_depth(), None),
Packet::Literal(_) => assert_eq!(pp.last_recursion_depth(), Some(0)),
_ => (),
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn possible_message(&self) -> Result<()>
pub fn possible_message(&self) -> Result<()>
Returns whether the message appears to be an OpenPGP Message.
Only when the whole message has been processed is it possible
to say whether the message is definitely an OpenPGP Message.
Before that, it is only possible to say that the message is a
valid prefix or definitely not an OpenPGP message (see
PacketParserEOF::is_message
).
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a compressed message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
pp.possible_message()?;
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn possible_keyring(&self) -> Result<()>
pub fn possible_keyring(&self) -> Result<()>
Returns whether the message appears to be an OpenPGP keyring.
Only when the whole message has been processed is it possible
to say whether the message is definitely an OpenPGP keyring.
Before that, it is only possible to say that the message is a
valid prefix or definitely not an OpenPGP keyring (see
PacketParserEOF::is_keyring
).
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a certificate.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
pp.possible_keyring()?;
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn possible_cert(&self) -> Result<()>
pub fn possible_cert(&self) -> Result<()>
Returns whether the message appears to be an OpenPGP Cert.
Only when the whole message has been processed is it possible
to say whether the message is definitely an OpenPGP Cert.
Before that, it is only possible to say that the message is a
valid prefix or definitely not an OpenPGP Cert (see
PacketParserEOF::is_cert
).
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a certificate.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
pp.possible_cert()?;
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn next(self) -> Result<(Packet, PacketParserResult<'a>)>
pub fn next(self) -> Result<(Packet, PacketParserResult<'a>)>
Finishes parsing the current packet and starts parsing the next one.
This function finishes parsing the current packet. By
default, any unread content is dropped. (See
PacketParsererBuilder
for how to configure this.) It then
creates a new packet parser for the next packet. If the
current packet is a container, this function does not
recurse into the container, but skips any packets it contains.
To recurse into the container, use the recurse()
method.
The return value is a tuple containing:
-
A
Packet
holding the fully processed old packet; -
A
PacketParser
holding the new packet;
To determine the two packet’s position within the parse tree,
you can use last_path()
and path()
, respectively. To
determine their depth, you can use last_recursion_depth()
and recursion_depth()
, respectively.
Note: A recursion depth of 0 means that the packet is a top-level packet, a recursion depth of 1 means that the packet is an immediate child of a top-level-packet, etc.
Since the packets are serialized in depth-first order and all interior nodes are visited, we know that if the recursion depth is the same, then the packets are siblings (they have a common parent) and not, e.g., cousins (they have a common grandparent). This is because, if we move up the tree, the only way to move back down is to first visit a new container (e.g., an aunt).
Using the two positions, we can compute the change in depth as new_depth - old_depth. Thus, if the change in depth is 0, the two packets are siblings. If the value is 1, the old packet is a container, and the new packet is its first child. And, if the value is -1, the new packet is contained in the old packet’s grandparent. The idea is illustrated below:
ancestor
| \
... -n
|
grandparent
| \
parent -1
| \
packet 0
|
1
Note: since this function does not automatically recurse into a container, the change in depth will always be non-positive. If the current container is empty, this function DOES pop that container off the container stack, and returns the following packet in the parent container.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
// Start parsing the next packet.
ppr = pp.next()?.1;
}
sourcepub fn recurse(self) -> Result<(Packet, PacketParserResult<'a>)>
pub fn recurse(self) -> Result<(Packet, PacketParserResult<'a>)>
Finishes parsing the current packet and starts parsing the next one, recursing if possible.
This method is similar to the next()
method (see that
method for more details), but if the current packet is a
container (and we haven’t reached the maximum recursion depth,
and the user hasn’t started reading the packet’s contents), we
recurse into the container, and return a PacketParser
for
its first child. Otherwise, we return the next packet in the
packet stream. If this function recurses, then the new
packet’s recursion depth will be last_recursion_depth() + 1
;
because we always visit interior nodes, we can’t recurse more
than one level at a time.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn buffer_unread_content(&mut self) -> Result<&[u8]>
pub fn buffer_unread_content(&mut self) -> Result<&[u8]>
Causes the PacketParser to buffer the packet’s contents.
The packet’s contents can be retrieved using
e.g. Container::body
. In general, you should avoid
buffering a packet’s content and prefer streaming its content
unless you are certain that the content is small.
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
// Process the packet.
if let Packet::Literal(_) = pp.packet {
assert!(pp.buffer_unread_content()?
.starts_with(b"A Cypherpunk's Manifesto"));
if let Packet::Literal(l) = &pp.packet {
assert!(l.body().starts_with(b"A Cypherpunk's Manifesto"));
assert_eq!(l.body().len(), 5158);
} else {
unreachable!();
}
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn finish(&mut self) -> Result<&Packet>
pub fn finish(&mut self) -> Result<&Packet>
Finishes parsing the current packet.
By default, this drops any unread content. Use, for instance,
PacketParserBuilder
to customize the default behavior.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
let p = pp.finish()?;
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn header(&self) -> &Header
pub fn header(&self) -> &Header
Returns a reference to the current packet’s header.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse a message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
pp.header().valid(false)?;
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
sourcepub fn map(&self) -> Option<&Map>
pub fn map(&self) -> Option<&Map>
Returns a reference to the map (if any is written).
Examples
use sequoia_openpgp as openpgp;
use openpgp::parse::{Parse, PacketParserBuilder};
let message_data = b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.";
let pp = PacketParserBuilder::from_bytes(message_data)?
.map(true) // Enable mapping.
.build()?
.expect("One packet, not EOF");
let map = pp.map().expect("Mapping is enabled");
assert_eq!(map.iter().nth(0).unwrap().name(), "CTB");
assert_eq!(map.iter().nth(0).unwrap().offset(), 0);
assert_eq!(map.iter().nth(0).unwrap().as_bytes(), &[0xcb]);
sourcepub fn take_map(&mut self) -> Option<Map>
pub fn take_map(&mut self) -> Option<Map>
Takes the map (if any is written).
Examples
use sequoia_openpgp as openpgp;
use openpgp::parse::{Parse, PacketParserBuilder};
let message_data = b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.";
let mut pp = PacketParserBuilder::from_bytes(message_data)?
.map(true) // Enable mapping.
.build()?
.expect("One packet, not EOF");
let map = pp.take_map().expect("Mapping is enabled");
assert_eq!(map.iter().nth(0).unwrap().name(), "CTB");
assert_eq!(map.iter().nth(0).unwrap().offset(), 0);
assert_eq!(map.iter().nth(0).unwrap().as_bytes(), &[0xcb]);
sourceimpl<'a> PacketParser<'a>
impl<'a> PacketParser<'a>
sourcepub fn decrypt(
&mut self,
algo: SymmetricAlgorithm,
key: &SessionKey
) -> Result<()>
pub fn decrypt(
&mut self,
algo: SymmetricAlgorithm,
key: &SessionKey
) -> Result<()>
Tries to decrypt the current packet.
On success, this function pushes one or more readers onto the
PacketParser
’s reader stack, and sets the packet parser’s
processed
flag (see PacketParser::processed
).
If this function is called on a packet that does not contain
encrypted data, or some of the data was already read, then it
returns Error::InvalidOperation
.
Examples
use sequoia_openpgp as openpgp;
use openpgp::Packet;
use openpgp::fmt::hex;
use openpgp::types::SymmetricAlgorithm;
use openpgp::parse::{Parse, PacketParserResult, PacketParser};
// Parse an encrypted message.
let message_data: &[u8] = // ...
let mut ppr = PacketParser::from_bytes(message_data)?;
while let PacketParserResult::Some(mut pp) = ppr {
if let Packet::SEIP(_) = pp.packet {
pp.decrypt(SymmetricAlgorithm::AES256,
&hex::decode("7EF4F08C44F780BEA866961423306166\
B8912C43352F3D9617F745E4E3939710")?
.into())?;
}
// Start parsing the next packet, recursing.
ppr = pp.recurse()?.1;
}
Security Considerations
This functions returns rich errors in case the decryption fails. In combination with certain asymmetric algorithms (RSA), this may lead to compromise of secret key material or (partial) recovery of the message’s plain text. See Section 14 of RFC 4880.
DO NOT relay these errors in situations where an attacker can
request decryption of messages in an automated fashion. The
API of the streaming Decryptor
prevents leaking rich
decryption errors.
Nevertheless, decrypting messages that do not use an authenticated encryption mode in an automated fashion that relays or leaks information to a third party is NEVER SAFE due to unavoidable format oracles, see Format Oracles on OpenPGP.
Trait Implementations
sourceimpl<'a> BufferedReader<Cookie> for PacketParser<'a>
impl<'a> BufferedReader<Cookie> for PacketParser<'a>
This interface allows a caller to read the content of a
PacketParser
using the BufferedReader
interface. This is
essential to supporting streaming operation.
Note: it is safe to mix the use of the std::io::Read
and
BufferedReader
interfaces.
sourcefn buffer(&self) -> &[u8]ⓘNotable traits for &[u8]impl<'_> Read for &[u8]impl<'_> Write for &mut [u8]
fn buffer(&self) -> &[u8]ⓘNotable traits for &[u8]impl<'_> Read for &[u8]impl<'_> Write for &mut [u8]
Returns a reference to the internal buffer. Read more
sourcefn data(&mut self, amount: usize) -> Result<&[u8]>
fn data(&mut self, amount: usize) -> Result<&[u8]>
Ensures that the internal buffer has at least amount
bytes
of data, and returns it. Read more
sourcefn data_hard(&mut self, amount: usize) -> Result<&[u8]>
fn data_hard(&mut self, amount: usize) -> Result<&[u8]>
Like data()
, but returns an error if there is not at least
amount
bytes available. Read more
sourcefn data_eof(&mut self) -> Result<&[u8]>
fn data_eof(&mut self) -> Result<&[u8]>
Returns all of the data until EOF. Like data()
, this does not
actually consume the data that is read. Read more
sourcefn consume(&mut self, amount: usize) -> &[u8]ⓘNotable traits for &[u8]impl<'_> Read for &[u8]impl<'_> Write for &mut [u8]
fn consume(&mut self, amount: usize) -> &[u8]ⓘNotable traits for &[u8]impl<'_> Read for &[u8]impl<'_> Write for &mut [u8]
Consumes some of the data. Read more
sourcefn data_consume(&mut self, amount: usize) -> Result<&[u8]>
fn data_consume(&mut self, amount: usize) -> Result<&[u8]>
A convenience function that combines data()
and consume()
. Read more
sourcefn data_consume_hard(&mut self, amount: usize) -> Result<&[u8]>
fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8]>
A convenience function that effectively combines data_hard()
and consume()
. Read more
sourcefn steal(&mut self, amount: usize) -> Result<Vec<u8>>
fn steal(&mut self, amount: usize) -> Result<Vec<u8>>
Like data_consume_hard()
, but returns the data in a
caller-owned buffer. Read more
sourcefn steal_eof(&mut self) -> Result<Vec<u8>>
fn steal_eof(&mut self) -> Result<Vec<u8>>
Like steal()
, but instead of stealing a fixed number of
bytes, steals all of the data until the end of file. Read more
sourcefn get_mut(&mut self) -> Option<&mut dyn BufferedReader<Cookie>>
fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<Cookie>>
Returns a mutable reference to the inner BufferedReader
, if
any. Read more
sourcefn get_ref(&self) -> Option<&dyn BufferedReader<Cookie>>
fn get_ref(&self) -> Option<&dyn BufferedReader<Cookie>>
Returns a reference to the inner BufferedReader
, if any.
sourcefn into_inner<'b>(
self: Box<Self>
) -> Option<Box<dyn BufferedReader<Cookie> + 'b>> where
Self: 'b,
fn into_inner<'b>(
self: Box<Self>
) -> Option<Box<dyn BufferedReader<Cookie> + 'b>> where
Self: 'b,
Returns the underlying reader, if any. Read more
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.
sourcefn consummated(&mut self) -> bool
fn consummated(&mut self) -> bool
Checks whether this reader is consummated. Read more
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. Read more
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. Read more
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. Read more
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. Read more
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. Read more
sourcefn drop_eof(&mut self) -> Result<bool, Error>
fn drop_eof(&mut self) -> Result<bool, Error>
Like steal_eof()
, but instead of returning the data, the
data is discarded. Read more
sourcefn copy(&mut self, sink: &mut dyn Write) -> Result<u64, Error>
fn copy(&mut self, sink: &mut dyn Write) -> Result<u64, Error>
Copies data to the given writer returning the copied amount. Read more
sourcefn dump(&self, sink: &mut dyn Write) -> Result<(), Error>
fn dump(&self, sink: &mut dyn Write) -> Result<(), Error>
A helpful debugging aid to pretty print a Buffered Reader stack. Read more
sourcefn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a, Global>ⓘNotable traits for Box<R, Global>impl<R> Read for Box<R, Global> where
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;
where
Self: 'a,
fn as_boxed<'a>(self) -> Box<dyn BufferedReader<C> + 'a, Global>ⓘNotable traits for Box<R, Global>impl<R> Read for Box<R, Global> where
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;
where
Self: 'a,
R: Read + ?Sized, impl<W> Write for Box<W, Global> where
W: Write + ?Sized, impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;
Boxes the reader.
sourceimpl<'a> Debug for PacketParser<'a>
impl<'a> Debug for PacketParser<'a>
sourceimpl<'a> Display for PacketParser<'a>
impl<'a> Display for PacketParser<'a>
sourceimpl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a>
impl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a>
sourcefn from_reader<R: Read + 'a + Send + Sync>(
reader: R
) -> Result<PacketParserResult<'a>>
fn from_reader<R: Read + 'a + Send + Sync>(
reader: R
) -> Result<PacketParserResult<'a>>
Starts parsing an OpenPGP message stored in a std::io::Read
object.
This function returns a PacketParser
for the first packet in
the stream.
sourcefn from_file<P: AsRef<Path>>(path: P) -> Result<PacketParserResult<'a>>
fn from_file<P: AsRef<Path>>(path: P) -> Result<PacketParserResult<'a>>
Starts parsing an OpenPGP message stored in a file named path
.
This function returns a PacketParser
for the first packet in
the stream.
sourcefn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(
data: &'a D
) -> Result<PacketParserResult<'a>>
fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(
data: &'a D
) -> Result<PacketParserResult<'a>>
Starts parsing an OpenPGP message stored in a buffer.
This function returns a PacketParser
for the first packet in
the stream.
sourceimpl<'a> Read for PacketParser<'a>
impl<'a> Read for PacketParser<'a>
This interface allows a caller to read the content of a
PacketParser
using the Read
interface. This is essential to
supporting streaming operation.
Note: it is safe to mix the use of the std::io::Read
and
BufferedReader
interfaces.
sourcefn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more
1.36.0 · sourcefn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
Like read
, except that it reads into a slice of buffers. Read more
sourcefn is_read_vectored(&self) -> bool
fn is_read_vectored(&self) -> bool
can_vector
)Determines if this Read
er has an efficient read_vectored
implementation. Read more
1.0.0 · sourcefn read_to_end(&mut self, buf: &mut Vec<u8, Global>) -> Result<usize, Error>
fn read_to_end(&mut self, buf: &mut Vec<u8, Global>) -> Result<usize, Error>
Read all bytes until EOF in this source, placing them into buf
. Read more
1.0.0 · sourcefn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
Read all bytes until EOF in this source, appending them to buf
. Read more
1.6.0 · sourcefn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
Read the exact number of bytes required to fill buf
. Read more
sourcefn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<(), Error>
fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<(), Error>
read_buf
)Pull some bytes from this source into the specified buffer. Read more
sourcefn read_buf_exact(&mut self, buf: &mut ReadBuf<'_>) -> Result<(), Error>
fn read_buf_exact(&mut self, buf: &mut ReadBuf<'_>) -> Result<(), Error>
read_buf
)Read the exact number of bytes required to fill buf
. Read more
1.0.0 · sourcefn by_ref(&mut self) -> &mut Self
fn by_ref(&mut self) -> &mut Self
Creates a “by reference” adaptor for this instance of Read
. Read more
Auto Trait Implementations
impl<'a> !RefUnwindSafe for PacketParser<'a>
impl<'a> Send for PacketParser<'a>
impl<'a> Sync for PacketParser<'a>
impl<'a> Unpin for PacketParser<'a>
impl<'a> !UnwindSafe for PacketParser<'a>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more