From 6999ef3141085d6bd2d2486babfd15b8a4c3542b Mon Sep 17 00:00:00 2001 From: Szabolcs Berecz Date: Tue, 15 May 2018 22:10:14 +0200 Subject: [PATCH] Switch over to the nom based parser. Fixes #3 --- benches/parser.rs | 7 +--- src/header.rs | 84 ++--------------------------------------------- tests/header.rs | 24 +++++++------- 3 files changed, 16 insertions(+), 99 deletions(-) diff --git a/benches/parser.rs b/benches/parser.rs index bd11c5c..2f451b0 100644 --- a/benches/parser.rs +++ b/benches/parser.rs @@ -9,11 +9,6 @@ use test::Bencher; const HEADER: &[u8; 32] = b"\x05\x02W\x01\x00\x00\x28\x07BLAKE2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; #[bench] -fn hand_rolled(b: &mut Bencher) { - b.iter(|| Header::from_vec(HEADER)); -} - -#[bench] -fn nom(b: &mut Bencher) { +fn header_parsing(b: &mut Bencher) { b.iter(|| Header::from_bytes(HEADER)); } diff --git a/src/header.rs b/src/header.rs index e96aea0..ce22e5c 100644 --- a/src/header.rs +++ b/src/header.rs @@ -1,10 +1,9 @@ extern crate byteorder; -use self::byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use self::byteorder::{BigEndian, WriteBytesExt}; use failure::Error; use nom; use parsers; -use std::io::Cursor; /// Algorithm used for hashing the data. #[derive(Debug, PartialEq)] @@ -84,86 +83,9 @@ impl Header { } /// Parse a 32 byte buffer slice into a valid Header. + #[deprecated(note = "Use from_bytes")] pub fn from_vec(buffer: &[u8]) -> Result { - ensure!(buffer.len() == 32, "buffer should be 32 bytes"); - - let mut rdr = Cursor::new(buffer); - let byte = rdr.read_u8().unwrap(); - ensure!( - byte == 5, - format!( - "The first byte of a SLEEP header should be '5', found {}", - byte - ) - ); - - let byte = rdr.read_u8().unwrap(); - ensure!( - byte == 2, - format!( - "The second byte of a SLEEP header should be '2', found {}", - byte - ) - ); - - let byte = rdr.read_u8().unwrap(); - ensure!( - byte == 87, - format!( - "The third byte of a SLEEP header should be '87', found {}", - byte - ) - ); - - let file_type = match rdr.read_u8().unwrap() { - 0 => FileType::BitField, - 1 => FileType::Signatures, - 2 => FileType::Tree, - num => bail!(format!( - "The fourth byte '{}' does not belong to any known SLEEP file type", - num - )), - }; - - let protocol_version = match rdr.read_u8().unwrap() { - 0 => ProtocolVersion::V0, - num => bail!(format!( - "The fifth byte '{}' does not belong to any known SLEEP protocol protocol_version", - num - )), - }; - - // Read entry size which will inform how many bytes to read next. - let entry_size = rdr.read_u16::().unwrap(); - - // Read out the "entry_size" bytes into a string. - // NOTE(yw): there should be a more concise way of doing this. - let hash_name_len = rdr.read_u8().unwrap() as usize; - let current = rdr.position() as usize; - - let hash_name_upper = current + hash_name_len; - let buf_slice = &buffer[current..hash_name_upper]; - rdr.set_position(hash_name_upper as u64 + 1); - let algo = ::std::str::from_utf8(buf_slice) - .expect("The algorithm string was invalid utf8 encoded"); - - let hash_type = match algo { - "BLAKE2b" => HashType::BLAKE2b, - "Ed25519" => HashType::Ed25519, - _ => HashType::None, - }; - - for index in rdr.position()..32 { - let byte = rdr.read_u8().unwrap(); - ensure!(byte == 0, format!("The remainder of the header should be zero-filled. Found byte '{}' at position '{}'.", byte, index)); - } - - Ok(Header { - protocol_version, - entry_size, - file_type, - hash_type, - }) + Header::from_bytes(buffer) } /// Convert a `Header` into a `Vec`. Use this to persist a header back to diff --git a/tests/header.rs b/tests/header.rs index 48c2b19..bc7792b 100644 --- a/tests/header.rs +++ b/tests/header.rs @@ -16,49 +16,49 @@ fn read_header_bytes(file_name: &str) -> Result<[u8; 32], std::io::Error> { } #[test] -fn from_vec_content_bitfield() { +fn from_bytes_content_bitfield() { let buffer = read_header_bytes("tests/fixtures/content.bitfield").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_bitfield()); assert_eq!(header.to_vec(), buffer); } #[test] -fn from_vec_content_signatures() { +fn from_bytes_content_signatures() { let buffer = read_header_bytes("tests/fixtures/content.signatures").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_signatures()); assert_eq!(header.to_vec(), buffer); } #[test] -fn from_vec_content_tree() { +fn from_bytes_content_tree() { let buffer = read_header_bytes("tests/fixtures/content.tree").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_tree()); assert_eq!(header.to_vec(), buffer); } #[test] -fn from_vec_metadata_bitfield() { +fn from_bytes_metadata_bitfield() { let buffer = read_header_bytes("tests/fixtures/metadata.bitfield").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_bitfield()); assert_eq!(header.to_vec(), buffer); } #[test] -fn from_vec_metadata_signatures() { +fn from_bytes_metadata_signatures() { let buffer = read_header_bytes("tests/fixtures/metadata.signatures").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_signatures()); assert_eq!(header.to_vec(), buffer); } #[test] -fn from_vec_metadata_tree() { +fn from_bytes_metadata_tree() { let buffer = read_header_bytes("tests/fixtures/metadata.tree").unwrap(); - let header = Header::from_vec(&buffer).unwrap(); + let header = Header::from_bytes(&buffer).unwrap(); assert!(header.is_tree()); assert_eq!(header.to_vec(), buffer); }