Rework read_sized_string(): truncate null bytes

This commit is contained in:
Matteo Cypriani 2016-12-07 17:51:59 -05:00
parent 4b92eb0239
commit 00c88153b2
3 changed files with 35 additions and 7 deletions

View File

@ -23,6 +23,7 @@
//! Error type for NRGrip.
use std::error::Error;
use std::ffi;
use std::fmt;
use std::io;
@ -30,6 +31,7 @@ use std::io;
#[derive(Debug)]
pub enum NrgError {
Io(io::Error),
String(ffi::IntoStringError),
NrgFormat,
NrgFormatV1,
NrgChunkId,
@ -43,6 +45,7 @@ impl fmt::Display for NrgError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
NrgError::Io(ref err) => err.fmt(f),
NrgError::String(ref err) => err.fmt(f),
NrgError::NrgFormat => write!(f, "NRG format unknown."),
NrgError::NrgFormatV1 => write!(f, "NRG v1 format is not handled."),
NrgError::NrgChunkId => write!(f, "NRG chunk ID unknown."),
@ -58,6 +61,7 @@ impl Error for NrgError {
fn description(&self) -> &str {
match *self {
NrgError::Io(ref err) => err.description(),
NrgError::String(ref err) => err.description(),
NrgError::NrgFormat => "NRG format",
NrgError::NrgFormatV1 => "NRG format v1",
NrgError::NrgChunkId => "NRG chunk ID",
@ -71,6 +75,7 @@ impl Error for NrgError {
fn cause(&self) -> Option<&Error> {
match *self {
NrgError::Io(ref err) => Some(err),
NrgError::String(ref err) => Some(err),
NrgError::NrgFormat => None,
NrgError::NrgFormatV1 => None,
NrgError::NrgChunkId => None,
@ -87,3 +92,9 @@ impl From<io::Error> for NrgError {
NrgError::Io(err)
}
}
impl From<ffi::IntoStringError> for NrgError {
fn from(err: ffi::IntoStringError) -> NrgError {
NrgError::String(err)
}
}

View File

@ -139,7 +139,7 @@ fn read_nrg_chunks(fd: &mut File, nm: &mut NrgMetadata) -> Result<(), NrgError>
/// Reads an NRG chunk ID (i.e. a 4-byte string) from `fd`.
fn read_nrg_chunk_id(fd: &File) -> Result<String, NrgError> {
fn read_nrg_chunk_id(fd: &mut File) -> Result<String, NrgError> {
read_sized_string(fd, 4)
}

View File

@ -22,6 +22,7 @@
//! Miscellaneous functions to read fixed-size data from a file.
use std::ffi::CString;
use std::fs::File;
use std::io::Read;
use std::mem;
@ -29,12 +30,28 @@ use std::mem;
use ::error::NrgError;
/// Reads a String of size `size` from `fd`.
pub fn read_sized_string(fd: &File, size: u64) -> Result<String, NrgError> {
let mut handle = fd.take(size);
let mut string = String::new();
try!(handle.read_to_string(&mut string));
Ok(string)
/// Reads a String of `size` bytes from `fd`.
///
/// The string will be truncated at the first null byte encountered; therefore,
/// its length may be less than `size` characters.
pub fn read_sized_string(fd: &mut File, size: usize)
-> Result<String, NrgError> {
// Read size bytes
let mut bytes = vec!(0u8; size);
try!(fd.read_exact(&mut bytes));
// Truncate the vector at the first null byte
let mut i: usize = 0;
for b in bytes.iter() {
if *b == 0 { break; }
i += 1;
}
bytes.truncate(i);
let cstring = CString::new(bytes)
.expect("This Vec wasn't supposed to contain any null byte!");
cstring.into_string().map_err(NrgError::String)
}