use std;
use std::fs::File;
use num::FromPrimitive;
use super::*;
pub mod buffered_reader;
use self::buffered_reader::*;
pub use self::buffered_reader::BufferedReader;
mod buffered_reader_partial_body;
use self::buffered_reader_partial_body::*;
mod buffered_reader_decompress;
use self::buffered_reader_decompress::BufferedReaderDeflate;
use self::buffered_reader_decompress::BufferedReaderZlib;
use self::buffered_reader_decompress::BufferedReaderBzip;
/// The default amount of acceptable nesting. Typically, we expect a
/// message to looking like:
///
/// [ encryption container: [ signature: [ compressioned data: [ literal data ]]]]
///
/// So, this should be more than enough.
const MAX_RECURSION_DEPTH : usize = 16;
// Packet headers.
// Parse a CTB (as described in Section 4.2 of RFC4880) and return a
// 'struct CTB'. This function parses both new and old format ctbs.
//
// Example:
//
// let (input, ctb) = ctb(data).unwrap();
// println!("header: {:?}", ctb);
// assert_eq!(ctb.tag, 11);
named!(
ctb<CTB>,
bits!(
do_parse!(
tag_bits!(u8, 1, 1) >>
r: switch!(take_bits!(u8, 1),
/* New format. */
1 => do_parse!(tag: take_bits!(u8, 6) >>
(CTB::New(CTBNew {
common: CTBCommon {
tag: FromPrimitive::from_u8(tag).unwrap()
},
}))) |
/* Old format packet. */
0 => do_parse!(tag: take_bits!(u8, 4) >>
length_type: take_bits!(u8, 2) >>
(CTB::Old(CTBOld {
common: CTBCommon {
tag: FromPrimitive::from_u8(tag).unwrap()
},
length_type:
FromPrimitive::from_u8(length_type).unwrap(),
})))
) >>
(r))));
/// Decode a new format body length as described in Section 4.2.2 of RFC 4880.
fn body_length_new_format<T: BufferedReader> (bio: &mut T)
-> Result<BodyLength, std::io::Error> {
let octet1 = bio.data_consume_hard(1)?[0];
if octet1 < 192 {
// One octet.
return Ok(BodyLength::Full(octet1 as u32));
}
if 192 <= octet1 && octet1 < 224<