Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
Use read_exact (see #18)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed Feb 23, 2016
1 parent 3a1e442 commit c94d0d3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 61 deletions.
32 changes: 16 additions & 16 deletions src/detail/readwrite/commitlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::u32;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

use detail::readwrite::{sum, fill};
use detail::readwrite::{sum};
use detail::{Commit, EltChange, CommitMeta};
use {ElementT, Sum};
use detail::SUM_BYTES;
Expand All @@ -32,7 +32,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
let mut pos: usize = 0;
let mut buf = vec![0; 32];

try!(fill(&mut reader, &mut buf[0..16], pos));
try!(reader.read_exact(&mut buf[0..16]));
if buf[0..16] != *b"COMMIT LOG\x00\x00\x00\x00\x00\x00" {
return ReadError::err("unexpected contents (expected \
COMMIT LOG\\x00\\x00\\x00\\x00\\x00\\x00)", pos, (0, 16));
Expand All @@ -48,7 +48,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E

let l = try!(r.read(&mut buf[0..16]));
if l == 0 { break; /*end of file (EOF)*/ }
if l < 16 { try!(fill(&mut r, &mut buf[l..16], pos)); /*not EOF, buf haven't filled buffer*/ }
if l < 16 { try!(r.read_exact(&mut buf[l..16])); /*not EOF, buf haven't filled buffer*/ }

let n_parents = if buf[0..6] == *b"COMMIT" {
1
Expand All @@ -71,7 +71,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
let secs = try!((&buf[8..16]).read_i64::<BigEndian>());
pos += 16;

try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..4] != *b"CNUM" {
return ReadError::err("unexpected contents (expected CNUM)", pos, (0, 4));
}
Expand All @@ -85,7 +85,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
pos += 16;

let mut xm_data = vec![0; xm_len];
try!(fill(&mut r, &mut xm_data, pos));
try!(r.read_exact(&mut xm_data));
let xm = if xm_type_txt {
Some(try!(String::from_utf8(xm_data)
.map_err(|_| ReadError::new("content not valid UTF-8", pos, (0, xm_len)))))
Expand All @@ -97,7 +97,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
pos += xm_len;
let pad_len = 16 * ((xm_len + 15) / 16) - xm_len;
if pad_len > 0 {
try!(fill(&mut r, &mut buf[0..pad_len], pos));
try!(r.read_exact(&mut buf[0..pad_len]));
pos += pad_len;
}

Expand All @@ -112,12 +112,12 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E

let mut parents = Vec::with_capacity(n_parents);
for _ in 0..n_parents {
try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
parents.push(Sum::load(&buf[0..SUM_BYTES]));
pos += SUM_BYTES;
}

try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] != *b"ELEMENTS" {
return ReadError::err("unexpected contents (expected ELEMENTS)", pos, (0, 8));
}
Expand All @@ -127,7 +127,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
let mut changes = HashMap::new();

for _ in 0..num_elts {
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..4] != *b"ELT " {
return ReadError::err("unexpected contents (expected ELT\\x20)", pos, (0, 4));
}
Expand All @@ -148,25 +148,25 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
let change = match change_t {
Change::Delete => EltChange::deletion(),
Change::Insert | Change::Replace => {
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] != *b"ELT DATA" {
return ReadError::err("unexpected contents (expected ELT DATA)", pos, (0, 8));
}
let data_len = try!((&buf[8..16]).read_u64::<BigEndian>()) as usize; // #0015
pos += 16;

let mut data = vec![0; data_len];
try!(fill(&mut r, &mut data, pos));
try!(r.read_exact(&mut data));
pos += data_len;

let pad_len = 16 * ((data_len + 15) / 16) - data_len;
if pad_len > 0 {
try!(fill(&mut r, &mut buf[0..pad_len], pos));
try!(r.read_exact(&mut buf[0..pad_len]));
pos += pad_len;
}

let data_sum = Sum::calculate(&data);
try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
if !data_sum.eq(&buf[0..SUM_BYTES]) {
return ReadError::err("element checksum mismatch", pos, (0, SUM_BYTES));
}
Expand All @@ -180,7 +180,7 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
}
},
Change::MovedOut | Change::Moved => {
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] != *b"NEW ELT\x00" {
return ReadError::err("unexpected contents (expected NEW ELT)", pos, (0, 8));
}
Expand All @@ -191,13 +191,13 @@ pub fn read_log<E: ElementT>(reader_: &mut Read, receiver: &mut CommitReceiver<E
changes.insert(elt_id, change);
}

try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
let commit_sum = Sum::load(&buf[0..SUM_BYTES]);
pos += SUM_BYTES;

let sum = r.sum();
reader = r.into_inner();
try!(fill(&mut reader, &mut buf[0..SUM_BYTES], pos));
try!(reader.read_exact(&mut buf[0..SUM_BYTES]));
if !sum.eq(&buf[0..SUM_BYTES]) {
return ReadError::err("checksum invalid", pos, (0, SUM_BYTES));
}
Expand Down
22 changes: 10 additions & 12 deletions src/detail/readwrite/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

//! Read and write support for Pippin file headers.

use std::{io};
use std::io::{Read, Write, ErrorKind};
use std::cmp::min;
use std::result::Result as stdResult;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

use PartId;
use detail::readwrite::{sum, fill};
use detail::readwrite::{sum};
use detail::SUM_BYTES;
use error::{Result, ArgError, ReadError, make_io_err};
use util::rtrim;
Expand Down Expand Up @@ -97,14 +97,14 @@ pub fn validate_repo_name(name: &str) -> stdResult<(), ArgError> {
}

/// Read a file header.
pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
pub fn read_head(r: &mut Read) -> Result<FileHeader> {
// A reader which also calculates a checksum:
let mut sum_reader = sum::HashReader::new(r);

let mut pos: usize = 0;
let mut buf = vec![0; 32];

try!(fill(&mut sum_reader, &mut buf[0..16], pos));
try!(sum_reader.read_exact(&mut buf[0..16]));
let head_version = read_head_version(&buf[8..16]);
if !HEAD_VERSIONS.contains(&head_version) {
return ReadError::err("Pippin file of unknown version", pos, (0, 16));
Expand All @@ -118,7 +118,7 @@ pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
};
pos += 16;

try!(fill(&mut sum_reader, &mut buf[0..16], pos));
try!(sum_reader.read_exact(&mut buf[0..16]));
let repo_name = match String::from_utf8(rtrim(&buf, 0).to_vec()) {
Ok(name) => name,
Err(_) => return ReadError::err("repo name not valid UTF-8", pos, (0, 16))
Expand All @@ -134,7 +134,7 @@ pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
};

loop {
try!(fill(&mut sum_reader, &mut buf[0..16], pos));
try!(sum_reader.read_exact(&mut buf[0..16]));
let (block, off): (&[u8], usize) = if buf[0] == b'H' {
pos += 1;
(&buf[1..16], 1)
Expand All @@ -146,7 +146,7 @@ pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
} as usize;
let len = x * 16;
if buf.len() < len { buf.resize(len, 0); }
try!(fill(&mut sum_reader, &mut buf[16..len], pos));
try!(sum_reader.read_exact(&mut buf[16..len]));
pos += 2;
(&buf[2..len], 2)
} else {
Expand Down Expand Up @@ -195,7 +195,7 @@ pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
// Read checksum:
let sum = sum_reader.sum();
let mut r = sum_reader.into_inner();
try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
if !sum.eq(&buf[0..SUM_BYTES]) {
return ReadError::err("header checksum invalid", pos, (0, SUM_BYTES));
}
Expand All @@ -204,9 +204,7 @@ pub fn read_head(r: &mut io::Read) -> Result<FileHeader> {
}

/// Write a file header.
pub fn write_head(header: &FileHeader, writer: &mut io::Write) -> Result<()> {
use std::io::Write;

pub fn write_head(header: &FileHeader, writer: &mut Write) -> Result<()> {
// A writer which calculates the checksum of what was written:
let mut w = sum::HashWriter::new(writer);

Expand Down Expand Up @@ -276,7 +274,7 @@ pub fn write_head(header: &FileHeader, writer: &mut io::Write) -> Result<()> {
let mut n = n1;
while n > 0 {
n -= match try!(w.write(&zeros[0..min(n, zeros.len())])) {
0 => return make_io_err(io::ErrorKind::WriteZero, "write failed"),
0 => return make_io_err(ErrorKind::WriteZero, "write failed"),
x => x
};
}
Expand Down
18 changes: 0 additions & 18 deletions src/detail/readwrite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,6 @@ mod header;
mod snapshot;
mod commitlog;

use std::{io, mem};

pub use self::header::{FileHeader, FileType, read_head, write_head, validate_repo_name};
pub use self::snapshot::{read_snapshot, write_snapshot};
pub use self::commitlog::{CommitReceiver, read_log, start_log, write_commit};

use error::{ReadError, Result};


// Utilities for reading from streams:
// #0018: replace this with Read::read_exact() when it's in stable.
fn fill<R: io::Read>(r: &mut R, mut buf: &mut [u8], pos: usize) -> Result<()> {
let mut p = pos;
while buf.len() > 0 {
match try!(r.read(buf)) {
0 => return ReadError::err("corrupt (file terminates unexpectedly)", p, (0, 0)),
n => { buf = &mut mem::replace(&mut buf, &mut [])[n..]; p += n },
}
}
Ok(())
}
30 changes: 15 additions & 15 deletions src/detail/readwrite/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::u32;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

use detail::readwrite::{sum, fill};
use detail::readwrite::{sum};
use partition::{PartitionState, State};
use {ElementT, PartId, Sum, CommitMeta};
use detail::SUM_BYTES;
Expand All @@ -35,15 +35,15 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
let mut pos: usize = 0;
let mut buf = vec![0; 32];

try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] != *b"SNAPSHOT" {
return ReadError::err("unexpected contents (expected SNAPSHOT)", pos, (0, 8));
}
let secs = try!((&buf[8..16]).read_i64::<BigEndian>());
pos += 16;

let meta = if file_ver >= 2016_02_22 {
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..4] != *b"CNUM" {
return ReadError::err("unexpected contents (expected CNUM)", pos, (0, 4));
}
Expand All @@ -57,7 +57,7 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
pos += 16;

let mut xm_data = vec![0; xm_len];
try!(fill(&mut r, &mut xm_data, pos));
try!(r.read_exact(&mut xm_data));
let xm = if xm_type_txt {
Some(try!(String::from_utf8(xm_data)
.map_err(|_| ReadError::new("content not valid UTF-8", pos, (0, xm_len)))))
Expand All @@ -69,7 +69,7 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
pos += xm_len;
let pad_len = 16 * ((xm_len + 15) / 16) - xm_len;
if pad_len > 0 {
try!(fill(&mut r, &mut buf[0..pad_len], pos));
try!(r.read_exact(&mut buf[0..pad_len]));
pos += pad_len;
}

Expand All @@ -86,7 +86,7 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
}
};

try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] != *b"ELEMENTS" {
return ReadError::err("unexpected contents (expected ELEMENTS)", pos, (0, 8));
}
Expand All @@ -97,7 +97,7 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
// but since we won't be creating a commit from it it doesn't actually matter.
let mut state = PartitionState::new(part_id, meta);
for _ in 0..num_elts {
try!(fill(&mut r, &mut buf[0..32], pos));
try!(r.read_exact(&mut buf[0..32]));
if buf[0..8] != *b"ELEMENT\x00" {
println!("buf: \"{}\", {:?}", String::from_utf8_lossy(&buf[0..8]), &buf[0..8]);
return ReadError::err("unexpected contents (expected ELEMENT\\x00)", pos, (0, 8));
Expand All @@ -112,17 +112,17 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
pos += 16;

let mut data = vec![0; data_len];
try!(fill(&mut r, &mut data, pos));
try!(r.read_exact(&mut data));
pos += data_len;

let pad_len = 16 * ((data_len + 15) / 16) - data_len;
if pad_len > 0 {
try!(fill(&mut r, &mut buf[0..pad_len], pos));
try!(r.read_exact(&mut buf[0..pad_len]));
pos += pad_len;
}

let elt_sum = Sum::calculate(&data);
try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
if !elt_sum.eq(&buf[0..SUM_BYTES]) {
return ReadError::err("element checksum mismatch", pos, (0, SUM_BYTES));
}
Expand All @@ -132,17 +132,17 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
try!(state.insert_with_id(ident, Rc::new(elt)));
}

try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
if buf[0..8] == *b"ELTMOVES" /*versions from 20160201, optional*/ {
let n_moves = try!((&buf[8..16]).read_u64::<BigEndian>()) as usize; // #0015
for _ in 0..n_moves {
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
let id0 = try!((&buf[0..8]).read_u64::<BigEndian>()).into();
let id1 = try!((&buf[8..16]).read_u64::<BigEndian>()).into();
state.set_move(id0, id1);
}
// re-fill buffer for next section:
try!(fill(&mut r, &mut buf[0..16], pos));
try!(r.read_exact(&mut buf[0..16]));
}

if buf[0..8] != *b"STATESUM" {
Expand All @@ -155,15 +155,15 @@ pub fn read_snapshot<T: ElementT>(reader: &mut Read, part_id: PartId,
}
pos += 8;

try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
if !state.statesum().eq(&buf[0..SUM_BYTES]) {
return ReadError::err("state checksum mismatch", pos, (0, SUM_BYTES));
}
pos += SUM_BYTES;

let sum = r.sum();
let mut r = r.into_inner();
try!(fill(&mut r, &mut buf[0..SUM_BYTES], pos));
try!(r.read_exact(&mut buf[0..SUM_BYTES]));
if !sum.eq(&buf[0..SUM_BYTES]) {
return ReadError::err("checksum invalid", pos, (0, SUM_BYTES));
}
Expand Down

0 comments on commit c94d0d3

Please sign in to comment.