summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2018-07-02 11:00:00 +0200
committerNeal H. Walfield <neal@pep.foundation>2018-07-02 11:08:39 +0200
commitc9ee0ac8d7689aca241b9b117749a6faf4923676 (patch)
treede1b416db32a46c1edeae16d59f52596440185e9
parent36c99d079120607a048284345d4ded09137615de (diff)
openpgp: Create a special Option-like type for PacketParser.
- In the future, we want to return some summary information about a parsed packet sequence after the packet sequence is fully parsed. Currently, PacketParser::next() and PacketParser::recurse() consume the PacketParser and return None on EOF. Thus, even if the summary information were stored in the PacketParser, it becomes inaccessible on EOF. - This change introduces a new type, PacketParserResult, that contains either a PacketParser or a PacketParserEOF. PacketParserEOF is returned on EOF instead of None. Since it is a struct, it can hold only any information that we want to return to the caller.
-rw-r--r--openpgp/examples/statistics.rs8
-rw-r--r--openpgp/src/lib.rs8
-rw-r--r--openpgp/src/packet_pile.rs54
-rw-r--r--openpgp/src/parse/packet_parser_builder.rs20
-rw-r--r--openpgp/src/parse/packet_pile_parser.rs58
-rw-r--r--openpgp/src/parse/parse.rs183
-rw-r--r--openpgp/src/serialize/stream.rs14
-rw-r--r--openpgp/src/signature.rs11
-rw-r--r--openpgp/src/subpacket.rs8
-rw-r--r--openpgp/src/tpk.rs53
-rw-r--r--tool/src/commands.rs25
-rw-r--r--tool/src/sqv.rs10
12 files changed, 289 insertions, 163 deletions
diff --git a/openpgp/examples/statistics.rs b/openpgp/examples/statistics.rs
index 27cdc946..a5d75dda 100644
--- a/openpgp/examples/statistics.rs
+++ b/openpgp/examples/statistics.rs
@@ -15,7 +15,7 @@ use buffered_reader::BufferedReaderGeneric;
extern crate openpgp;
use openpgp::Packet;
use openpgp::packet::{BodyLength, Tag};
-use openpgp::parse::PacketParser;
+use openpgp::parse::{PacketParserResult, PacketParser};
fn main() {
let args: Vec<String> = env::args().collect();
@@ -47,11 +47,11 @@ fn main() {
File::open(&args[1]).expect("Failed to open file"),
Some(128 * 1024 * 1024) // Use a large buffer.
);
- let mut ppo = PacketParser::from_reader(br)
+ let mut ppr = PacketParser::from_reader(br)
.expect("Failed to create reader");
// Iterate over all packets.
- while let Some(pp) = ppo {
+ while let PacketParserResult::Some(pp) = ppr {
// While the packet is in the parser, get some data for later.
let size = match pp.header.length {
BodyLength::Full(n) => Some(n),
@@ -61,7 +61,7 @@ fn main() {
// Get the packet and advance the parser.
let (packet, _, tmp, _) = pp.next()
.expect("Failed to get next packet");
- ppo = tmp;
+ ppr = tmp;
packet_count += 1;
if let Some(n) = size {
diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs
index 8289d6b9..b24e88ee 100644
--- a/openpgp/src/lib.rs
+++ b/openpgp/src/lib.rs
@@ -571,14 +571,13 @@ pub struct PacketPile {
/// ```rust
/// # extern crate openpgp;
/// # use openpgp::Result;
-/// # use openpgp::parse::PacketParser;
+/// # use openpgp::parse::{PacketParserResult, PacketParser};
/// use openpgp::TPK;
///
/// # fn main() { f().unwrap(); }
/// # fn f() -> Result<()> {
-/// # let ppo = PacketParser::from_bytes(&b""[..])?;
-/// # if let Some(pp) = ppo {
-/// match TPK::from_packet_parser(pp) {
+/// # let ppr = PacketParser::from_bytes(&b""[..])?;
+/// match TPK::from_packet_parser(ppr) {
/// Ok(tpk) => {
/// println!("Key: {}", tpk.primary());
/// for binding in tpk.userids() {
@@ -590,7 +589,6 @@ pub struct PacketPile {
/// }
/// }
///
-/// # }
/// # Ok(())
/// # }
#[derive(Debug, Clone, PartialEq)]
diff --git a/openpgp/src/packet_pile.rs b/openpgp/src/packet_pile.rs
index a286307b..c910f538 100644
--- a/openpgp/src/packet_pile.rs
+++ b/openpgp/src/packet_pile.rs
@@ -14,7 +14,7 @@ use Error;
use Packet;
use packet::{Container, PacketIter};
use PacketPile;
-use parse::PacketParser;
+use parse::PacketParserResult;
use parse::PacketParserBuilder;
use parse::Cookie;
@@ -304,8 +304,8 @@ impl PacketPile {
/// Reads all of the packets from a `PacketParser`, and turns them
/// into a message.
///
- /// Note: this assumes that `ppo` points to a top-level packet.
- pub fn from_packet_parser<'a>(ppo: Option<PacketParser<'a>>)
+ /// Note: this assumes that `ppr` points to a top-level packet.
+ pub fn from_packet_parser<'a>(ppr: PacketParserResult<'a>)
-> Result<PacketPile>
{
// Things are not going to work out if we don't start with a
@@ -313,7 +313,7 @@ impl PacketPile {
// ppo.recursion_depth and leave the rest of the message, but
// it is hard to imagine that that is what the caller wants.
// Instead of hiding that error, fail fast.
- if let Some(ref pp) = ppo {
+ if let PacketParserResult::Some(ref pp) = ppr {
assert_eq!(pp.recursion_depth, 0);
}
@@ -322,14 +322,14 @@ impl PacketPile {
let mut last_position = 0;
- if ppo.is_none() {
+ if ppr.is_none() {
// Empty message.
return Ok(PacketPile::from_packets(Vec::new()));
}
- let mut pp = ppo.unwrap();
+ let mut pp = ppr.unwrap();
'outer: loop {
- let (mut packet, mut position, mut ppo, _) = pp.recurse()?;
+ let (mut packet, mut position, mut ppr, _) = pp.recurse()?;
let mut relative_position : isize = position - last_position;
assert!(relative_position <= 1);
@@ -367,11 +367,11 @@ impl PacketPile {
container.packets.push(packet);
- if ppo.is_none() {
+ if ppr.is_none() {
break 'outer;
}
- pp = ppo.unwrap();
+ pp = ppr.unwrap();
last_position = position;
position = pp.recursion_depth as isize;
@@ -385,7 +385,7 @@ impl PacketPile {
let result = pp.recurse()?;
packet = result.0;
assert_eq!(position, result.1);
- ppo = result.2;
+ ppr = result.2;
}
}
@@ -434,6 +434,7 @@ mod message_test {
use CompressedData;
use SEIP;
use packet::Tag;
+ use parse::PacketParser;
#[test]
fn deserialize_test_1 () {
@@ -519,8 +520,13 @@ mod message_test {
.to_packet_pile_parser().unwrap();
while ppp.recurse() {
- let pp = ppp.ppo.as_mut().unwrap();
- eprintln!("{:?}", pp);
+ if let PacketParserResult::Some(ref pp) = ppp.ppr {
+ eprintln!("{:?}", pp);
+ } else {
+ // If PacketPileParser::recurse returns true, then
+ // ppp.ppr is not EOF.
+ unreachable!();
+ }
}
let pile = ppp.finish();
pile.pretty_print();
@@ -555,14 +561,14 @@ mod message_test {
// Use the iterator interface to parse an OpenPGP quine.
let path = path_to("compression-quine.gpg");
let max_recursion_depth = 255;
- let mut ppo : Option<PacketParser>
+ let mut ppr : PacketParserResult
= PacketParserBuilder::from_file(path).unwrap()
.max_recursion_depth(max_recursion_depth)
.finalize().unwrap();
let mut count : usize = 0;
loop {
- if let Some(pp2) = ppo {
+ if let PacketParserResult::Some(pp2) = ppr {
count += 1;
let (_packet, packet_depth, pp2, pp_depth)
@@ -572,7 +578,7 @@ mod message_test {
if pp2.is_some() {
assert_eq!(pp_depth as usize, count);
}
- ppo = pp2;
+ ppr = pp2;
} else {
break;
}
@@ -588,12 +594,12 @@ mod message_test {
// literal packet. When we read some of the compressed
// packet, we expect recurse() to not recurse.
- let ppo = PacketParserBuilder::from_file(
+ let ppr = PacketParserBuilder::from_file(
path_to("compressed-data-algo-1.gpg")).unwrap()
.buffer_unread_content()
.finalize().unwrap();
- let mut pp = ppo.unwrap();
+ let mut pp = ppr.unwrap();
if let Packet::CompressedData(_) = pp.packet {
} else {
panic!("Expected a compressed packet!");
@@ -605,9 +611,9 @@ mod message_test {
assert_eq!(amount, 1);
// recurse should now not recurse. Since there is nothing
- // following the compressed packet, ppo should be None.
- let (mut packet, _, ppo, _) = pp.next().unwrap();
- assert!(ppo.is_none());
+ // following the compressed packet, ppr should be EOF.
+ let (mut packet, _, ppr, _) = pp.next().unwrap();
+ assert!(ppr.is_none());
// Get the rest of the content and put the initial byte that
// we stole back.
@@ -615,16 +621,16 @@ mod message_test {
content.insert(0, data[0]);
let content = &content.into_boxed_slice()[..];
- let ppo = PacketParser::from_bytes(content).unwrap();
- let pp = ppo.unwrap();
+ let ppr = PacketParser::from_bytes(content).unwrap();
+ let pp = ppr.unwrap();
if let Packet::Literal(_) = pp.packet {
} else {
panic!("Expected a literal packet!");
}
// And we're done...
- let (_packet, _, ppo, _) = pp.next().unwrap();
- assert!(ppo.is_none());
+ let (_packet, _, ppr, _) = pp.next().unwrap();
+ assert!(ppr.is_none());
}
#[test]
diff --git a/openpgp/src/parse/packet_parser_builder.rs b/openpgp/src/parse/packet_parser_builder.rs
index 3fa6a68c..082d7fcf 100644
--- a/openpgp/src/parse/packet_parser_builder.rs
+++ b/openpgp/src/parse/packet_parser_builder.rs
@@ -7,7 +7,9 @@ use buffered_reader::BufferedReaderGeneric;
use buffered_reader::BufferedReaderMemory;
use Result;
+use parse::PacketParserResult;
use parse::PacketParser;
+use parse::PacketParserEOF;
use parse::PacketParserSettings;
use parse::ParserResult;
use parse::Cookie;
@@ -88,17 +90,21 @@ impl<'a> PacketParserBuilder<'a> {
///
/// ```rust
/// # use openpgp::Result;
- /// # use openpgp::parse::{PacketParser, PacketParserBuilder};
+ /// # use openpgp::parse::{
+ /// # PacketParserResult, PacketParser, PacketParserBuilder
+ /// # };
/// # f(include_bytes!("../../tests/data/messages/public-key.gpg"));
/// #
/// # fn f(message_data: &[u8])
- /// # -> Result<Option<PacketParser>> {
- /// let ppo = PacketParserBuilder::from_bytes(message_data)?.finalize()?;
- /// # return Ok(ppo);
+ /// # -> Result<PacketParserResult> {
+ /// let ppr = PacketParserBuilder::from_bytes(message_data)?.finalize()?;
+ /// # return Ok(ppr);
/// # }
/// ```
pub fn finalize(self)
- -> Result<Option<PacketParser<'a>>> where Self: 'a {
+ -> Result<PacketParserResult<'a>>
+ where Self: 'a
+ {
// Parse the first packet.
let pp = PacketParser::parse(Box::new(self.bio), &self.settings, 0)?;
@@ -108,10 +114,10 @@ impl<'a> PacketParserBuilder<'a> {
// Override the defaults.
pp.settings = self.settings;
- Ok(Some(pp))
+ Ok(PacketParserResult::Some(pp))
} else {
// `bio` is empty. We're done.
- Ok(None)
+ Ok(PacketParserResult::EOF(PacketParserEOF::default()))
}
}
}
diff --git a/openpgp/src/parse/packet_pile_parser.rs b/openpgp/src/parse/packet_pile_parser.rs
index 146d673b..5517cb8c 100644
--- a/openpgp/src/parse/packet_pile_parser.rs
+++ b/openpgp/src/parse/packet_pile_parser.rs
@@ -8,7 +8,12 @@ use {
Container,
PacketPile,
};
-use parse::{PacketParserBuilder, PacketParser, Cookie};
+use parse::{
+ PacketParserBuilder,
+ PacketParserResult,
+ PacketParser,
+ Cookie
+};
use buffered_reader::{BufferedReader, BufferedReaderGeneric,
BufferedReaderMemory};
@@ -68,7 +73,7 @@ fn path_to(artifact: &str) -> PathBuf {
/// # fn f(message_data: &[u8]) -> Result<()> {
/// let mut ppp = PacketPileParser::from_bytes(message_data)?;
/// while ppp.recurse() {
-/// let pp = ppp.ppo.as_mut().unwrap();
+/// let pp = ppp.ppr.as_mut().unwrap();
/// eprintln!("{:?}", pp);
/// }
/// let message = ppp.finish();
@@ -79,7 +84,7 @@ fn path_to(artifact: &str) -> PathBuf {
#[derive(Debug)]
pub struct PacketPileParser<'a> {
/// The current packet.
- pub ppo: Option<PacketParser<'a>>,
+ pub ppr: PacketParserResult<'a>,
/// Whether the first packet has been returned.
returned_first: bool,
@@ -99,11 +104,12 @@ impl<'a> PacketParserBuilder<'a> {
impl<'a> PacketPileParser<'a> {
/// Creates a `PacketPileParser` from a *fresh* `PacketParser`.
- fn from_packet_parser(ppo: Option<PacketParser<'a>>)
- -> Result<PacketPileParser<'a>> {
+ fn from_packet_parser(ppr: PacketParserResult<'a>)
+ -> Result<PacketPileParser<'a>>
+ {
Ok(PacketPileParser {
pile: PacketPile { top_level: Container::new() },
- ppo: ppo,
+ ppr: ppr,
returned_first: false,
})
}
@@ -183,19 +189,21 @@ impl<'a> PacketPileParser<'a> {
/// `PacketParser` can be accessed as `self.ppo`.
pub fn recurse(&mut self) -> bool {
if self.returned_first {
- match self.ppo.take() {
- Some (pp) => {
+ match self.ppr.take() {
+ PacketParserResult::Some(pp) => {
match pp.recurse() {
- Ok((packet, position, ppo, _)) => {
+ Ok((packet, position, ppr, _)) => {
self.insert_packet(packet, position);
- self.ppo = ppo;
- },
+ self.ppr = ppr;
+ }
Err(_) => {
- self.ppo = None;
+ // XXX: What should we do with the error?
}
}
- },
- None => {},
+ }
+ eof @ PacketParserResult::EOF(_) => {
+ self.ppr = eof;
+ }
}
} else {
self.returned_first = true;
@@ -219,19 +227,21 @@ impl<'a> PacketPileParser<'a> {
/// `PacketParser` can be accessed as `self.ppo`.
pub fn next(&mut self) -> bool {
if self.returned_first {
- match self.ppo.take() {
- Some (pp) => {
+ match self.ppr.take() {
+ PacketParserResult::Some(pp) => {
match pp.next() {
- Ok((packet, position, ppo, _)) => {
+ Ok((packet, position, ppr, _)) => {
self.insert_packet(packet, position);
- self.ppo = ppo;
- },
+ self.ppr = ppr;
+ }
Err(_) => {
- self.ppo = None;
+ // XXX: What should we do with the error?
}
}
},
- None => {},
+ eof @ PacketParserResult::EOF(_) => {
+ self.ppr = eof
+ },
}
} else {
self.returned_first = true;
@@ -245,7 +255,7 @@ impl<'a> PacketPileParser<'a> {
/// A top-level packet has a recursion depth of 0. Packets in a
/// top-level container have a recursion depth of 1. Etc.
pub fn recursion_depth(&self) -> Option<u8> {
- if let Some(ref pp) = self.ppo {
+ if let PacketParserResult::Some(ref pp) = self.ppr {
Some(pp.recursion_depth)
} else {
None
@@ -254,7 +264,7 @@ impl<'a> PacketPileParser<'a> {
/// Returns whether the message has been completely parsed.
pub fn is_done(&self) -> bool {
- self.ppo.is_none()
+ self.ppr.is_none()
}
/// Finishes parsing the message and returns the assembled
@@ -296,7 +306,7 @@ fn message_parser_reader_interface() {
let mut mp = PacketPileParser::from_file(path).unwrap();
let mut count = 0;
while mp.recurse() {
- let pp = mp.ppo.as_mut().unwrap();
+ let pp = mp.ppr.as_mut().unwrap();
count += 1;
if let Packet::Literal(_) = pp.packet {
assert_eq!(count, 2);
diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs
index ebe78830..ab4eb537 100644
--- a/openpgp/src/parse/parse.rs
+++ b/openpgp/src/parse/parse.rs
@@ -926,17 +926,17 @@ fn one_pass_sig_test () {
for test in tests.iter() {
eprintln!("Trying {}...", test.filename);
- let mut pp = PacketParserBuilder::from_file(path_to(test.filename))
+ let mut ppr = PacketParserBuilder::from_file(path_to(test.filename))
.expect(&format!("Reading {}", test.filename)[..])
.finalize().unwrap();
let mut one_pass_sigs = 0;
let mut sigs = 0;
- while let Some(tmp) = pp {
- if let Packet::OnePassSig(_) = tmp.packet {
+ while let PacketParserResult::Some(pp) = ppr {
+ if let Packet::OnePassSig(_) = pp.packet {
one_pass_sigs += 1;
- } else if let Packet::Signature(ref sig) = tmp.packet {
+ } else if let Packet::Signature(ref sig) = pp.packet {
eprintln!(" {}:\n prefix: expected: {}, in sig: {}",
test.filename,
::to_hex(&test.hash_prefix[sigs][..], false),
@@ -955,8 +955,8 @@ fn one_pass_sig_test () {
number of expected OnePassSig packets.");
}
- let (_, _, tmp, _) = tmp.recurse().expect("Parsing message");
- pp = tmp;
+ let (_, _, tmp, _) = pp.recurse().expect("Parsing message");
+ ppr = tmp;
}
assert_eq!(one_pass_sigs, sigs,
"Number of OnePassSig packets does not match \
@@ -1603,12 +1603,12 @@ impl PKESK {
/// ```rust
/// # use openpgp::Result;
/// # use openpgp::Packet;
-/// # use openpgp::parse::PacketParser;
+/// # use openpgp::parse::{PacketParserResult, PacketParser};
/// # let _ = f(include_bytes!("../../tests/data/messages/public-key.gpg"));
/// #
/// # fn f(message_data: &[u8]) -> Result<()> {
-/// let mut ppo = PacketParser::from_bytes(message_data)?;
-/// while let Some(mut pp) = ppo {
+/// let mut ppr = PacketParser::from_bytes(message_data)?;
+/// while let PacketParserResult::Some(mut pp) = ppr {
/// // Process the packet.
///
/// if let Packet::Literal(_) = pp.packet {
@@ -1618,7 +1618,7 @@ impl PKESK {
///
/// // Get the next packet.
/// let (_packet, _packet_depth, tmp, _pp_depth) = pp.recurse()?;
-/// ppo = tmp;
+/// ppr = tmp;
/// }
/// # return Ok(());
/// # }
@@ -1674,6 +1674,120 @@ enum ParserResult<'a> {
EOF(Box<BufferedReader<Cookie> + 'a>),
}
+/// Information about the stream of packets parsed by the
+/// `PacketParser`.
+#[derive(Debug, Clone)]
+pub struct PacketParserEOF {
+}
+
+impl Default for PacketParserEOF {
+ fn default() -> Self {
+ PacketParserEOF {
+ }
+ }
+}
+
+impl PacketParserEOF {
+ /// Copies the important information in `pp` into a new
+ /// `PacketParserEOF` instance.
+ fn new(_pp: &PacketParser) -> Self {
+ PacketParserEOF {
+ }
+ }
+}
+
+/// The return type of `PacketParser::next`() and
+/// `PacketParser::recurse`().
+///
+/// We don't use an `Option`, because when we reach the end of the
+/// packet sequence, some information about the message needs to
+/// remain accessible.
+#[derive(Debug)]
+pub enum PacketParserResult<'a> {
+ /// A `PacketParser` for the next packet.
+ Some(PacketParser<'a>),
+ /// Information about a fully parsed packet sequence.
+ EOF(PacketParserEOF),
+}
+
+impl<'a> PacketParserResult<'a> {
+ /// Like `Option::is_none`().
+ pub fn is_none(&self) -> bool {
+ if let PacketParserResult::EOF(_) = self {
+ true
+ } else {
+ false
+ }
+ }
+
+ /// An alias for `is_none`().
+ pub fn is_eof(&self) -> bool {
+ Self::is_none(self)
+ }
+
+ /// Like `Option::is_some`().
+ pub fn is_some(&self) -> bool {
+ ! Self::is_none(self)
+ }
+
+ /// Like `Option::expect`().
+ pub fn expect(self, msg: &str) -> PacketParser<'a> {
+ if let PacketParserResult::Some(pp) = self {
+ return pp;
+ } else {
+ panic!("{}", msg);
+ }
+ }
+
+ /// Like `Option::unwrap`().
+ pub fn unwrap(self) -> PacketParser<'a> {
+ self.expect("called `PacketParserResult::unwrap()` on a \
+ `PacketParserResult::PacketParserEOF` value")
+ }
+
+ /// Like `Option::as_ref`().
+ pub fn as_ref(&self) -> Option<&PacketParser<'a>> {
+ if let PacketParserResult::Some(ref pp) = self {
+ Some(pp)
+ } else {
+ None
+ }
+ }
+
+ /// Like `Option::as_mut`().
+ pub fn as_mut(&mut self) -> Option<&mut PacketParser<'a>> {
+ if let PacketParserResult::Some(ref mut pp) = self {
+ Some(pp)
+ } else {
+ None
+ }
+ }
+
+ /// Like `Option::take`().
+ ///
+ /// If `self` is a `PacketParserEOF`, then a copy of that value,
+ /// not the default `PacketParserEOF`, is returned.
+ pub fn take(&mut self) -> Self {
+ match self {
+ PacketParserResult::Some(_) =>
+ mem::replace(self, PacketParserResult::EOF(
+ PacketParserEOF::default())),
+ PacketParserResult::EOF(ref eof) =>
+ PacketParserResult::EOF(eof.clone())
+ }
+ }
+
+ /// Like `Option::map`().
+ pub fn map<U, F>(self, f: F) -> Option<U>
+ where F: FnOnce(PacketParser<'a>) -> U
+ {
+ match self {
+ PacketParserResult::Some(x) => Some(f(x)),
+ PacketParserResult::EOF(_) => None,
+ }
+ }
+}
+
impl <'a> PacketParser<'a> {
/// Starts parsing an OpenPGP message stored in a `BufferedReader`
/// object.
@@ -1681,7 +1795,7 @@ impl <'a> PacketParser<'a> {
/// This function returns a `PacketParser` for the first packet in
/// the stream.
pub(crate) fn from_buffered_reader(bio: Box<BufferedReader<Cookie> + 'a>)
- -> Result<Option<PacketParser<'a>>> {
+ -> Result<PacketParserResult<'a>> {
PacketParserBuilder::from_buffered_reader(bio)?.finalize()
}
@@ -1690,7 +1804,7 @@ impl <'a> PacketParser<'a> {
/// This function returns a `PacketParser` for the first packet in
/// the stream.
pub fn from_reader<R: io::Read + 'a>(reader: R)
- -> Result<Option<PacketParser<'a>>> {
+ -> Result<PacketParserResult<'a>> {
PacketParserBuilder::from_reader(reader)?.finalize()
}
@@ -1699,7 +1813,7 @@ impl <'a> PacketParser<'a> {
/// This function returns a `PacketParser` for the first packet in
/// the stream.
pub fn from_file<P: AsRef<Path>>(path: P)
- -> Result<Option<PacketParser<'a>>> {
+ -> Result<PacketParserResult<'a>> {
PacketParserBuilder::from_file(path)?.finalize()
}
@@ -1708,7 +1822,7 @@ impl <'a> PacketParser<'a> {
/// This function returns a `PacketParser` for the first packet in
/// the stream.
pub fn from_bytes(bytes: &'a [u8])
- -> Result<Option<PacketParser<'a>>> {
+ -> Result<PacketParserResult<'a>> {
PacketParserBuilder::from_bytes(bytes)?.finalize()
}
@@ -2002,7 +2116,8 @@ impl <'a> PacketParser<'a> {
/// container off the container stack, and returns the following
/// packet in the parent container.
pub fn next(mut self)
- -> Result<(Packet, isize, Option<PacketParser<'a>>, isize)> {
+ -> Result<(Packet, isize, PacketParserResult<'a>, isize)>
+ {
if self.settings.trace {
eprintln!("{}PacketParser::next({:?}, depth: {}, level: {:?}).",
indent(self.recursion_depth),
@@ -2014,14 +2129,17 @@ impl <'a> PacketParser<'a> {
self.finish()?;
let mut reader = buffered_reader_stack_pop(
- self.reader, self.recursion_depth as isize)?;
+ mem::replace(&mut self.reader,
+ Box::new(BufferedReaderEOF::with_cookie(
+ Default::default()))),
+ self.recursion_depth as isize)?;
// Now read the next packet.
loop {
// Parse the next packet.
- let pp = PacketParser::parse(reader, &self.settings,
- self.recursion_depth as usize)?;
- match pp {
+ let ppr = PacketParser::parse(reader, &self.settings,
+ self.recursion_depth as usize)?;
+ match ppr {
ParserResult::EOF(reader_) => {
// We got EOF on the current container. The
// container at recursion depth n is empty. Pop
@@ -2044,21 +2162,23 @@ impl <'a> PacketParser<'a> {
reading message.",
indent(self.recursion_depth));