Skip to content

Commit

Permalink
Switch over to the nom based parser. Fixes datrs#3
Browse files Browse the repository at this point in the history
  • Loading branch information
khernyo committed May 15, 2018
1 parent c293121 commit 6999ef3
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 99 deletions.
7 changes: 1 addition & 6 deletions benches/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
84 changes: 3 additions & 81 deletions src/header.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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<Header, Error> {
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::<BigEndian>().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<u8>`. Use this to persist a header back to
Expand Down
24 changes: 12 additions & 12 deletions tests/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 6999ef3

Please sign in to comment.