use std::fmt;
use std::slice;
use std::vec;
use std::io;
use std::path::Path;
use buffered_reader::BufferedReader;
use crate::Result;
use crate::Error;
use crate::Packet;
use crate::packet::{Container, PacketIter};
use crate::PacketPile;
use crate::parse::PacketParserResult;
use crate::parse::PacketParserBuilder;
use crate::parse::Parse;
use crate::parse::Cookie;
impl fmt::Debug for PacketPile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("PacketPile")
.field("packets", &self.top_level.packets)
.finish()
}
}
impl<'a> Parse<'a, PacketPile> for PacketPile {
/// Deserializes the OpenPGP message stored in a `std::io::Read`
/// object.
///
/// Although this method is easier to use to parse a sequence of
/// OpenPGP packets than a [`PacketParser`] or a
/// [`PacketPileParser`], this interface buffers the whole message
/// in memory. Thus, the caller must be certain that the
/// *deserialized* message is not too large.
///
/// Note: this interface *does* buffer the contents of packets.
///
/// [`PacketParser`]: parse/struct.PacketParser.html
/// [`PacketPileParser`]: parse/struct.PacketPileParser.html
fn from_reader<R: 'a + io::Read>(reader: R) -> Result<PacketPile> {
let bio = buffered_reader::Generic::with_cookie(
reader, None, Cookie::default());
PacketPile::from_buffered_reader(Box::new(bio))
}
/// Deserializes the OpenPGP message stored in the file named by
/// `path`.
///
/// See `from_reader` for more details and caveats.
fn from_file<P: AsRef<Path>>(path: P) -> Result<PacketPile> {
PacketPile::from_buffered_reader(
Box::new(buffered_reader::File::with_cookie(path, Cookie::default())?))
}
/// Deserializes the OpenPGP message stored in the provided buffer.
///
/// See `from_reader` for more details and caveats.
fn from_bytes(data: &'a [u8]) -> Result<PacketPile> {
let bio = buffered_reader::Memory::with_cookie(
data, Cookie::default());
PacketPile::from_buffered_reader(Box::new(bio))
}
}
impl From<Vec<Packet>> for PacketPile {
fn from(p: Vec<Packet>) -> Self {
PacketPile { top_level: Container { packets: p } }
}
}
impl From<Packet> for PacketPile {
fn from(p: Packet) -> Self {
Self::from(vec![p])
}
}
impl PacketPile {
/// Pretty prints the message to stderr.
///
/// This function is primarily intended for debugging purposes.
pub fn pretty_print(&self) {
self.top_level.pretty_print(0);
}
/// Returns a reference to the packet at the location described by
/// `pathspec`.
///
/// `pathspec` is a slice of the form `[ 0, 1, 2 ]`. Each element
/// is the index of packet in a container. Thus, the previous
/// path specification means: return the third child of the second
/// child of the first top-level packet. In other words, the
/// starred packet in the following tree:
///
/// ```text
/// PacketPile
/// / | \
/// 0 1 2 ...
/// / \
/// / \
/// 0 1 ...
/// / | \ ...
/// 0 1 2
/// *