Rework read_sized_string(): truncate null bytes
This commit is contained in:
parent
4b92eb0239
commit
00c88153b2
11
src/error.rs
11
src/error.rs
|
@ -23,6 +23,7 @@
|
||||||
//! Error type for NRGrip.
|
//! Error type for NRGrip.
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::ffi;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ use std::io;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum NrgError {
|
pub enum NrgError {
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
|
String(ffi::IntoStringError),
|
||||||
NrgFormat,
|
NrgFormat,
|
||||||
NrgFormatV1,
|
NrgFormatV1,
|
||||||
NrgChunkId,
|
NrgChunkId,
|
||||||
|
@ -43,6 +45,7 @@ impl fmt::Display for NrgError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
NrgError::Io(ref err) => err.fmt(f),
|
NrgError::Io(ref err) => err.fmt(f),
|
||||||
|
NrgError::String(ref err) => err.fmt(f),
|
||||||
NrgError::NrgFormat => write!(f, "NRG format unknown."),
|
NrgError::NrgFormat => write!(f, "NRG format unknown."),
|
||||||
NrgError::NrgFormatV1 => write!(f, "NRG v1 format is not handled."),
|
NrgError::NrgFormatV1 => write!(f, "NRG v1 format is not handled."),
|
||||||
NrgError::NrgChunkId => write!(f, "NRG chunk ID unknown."),
|
NrgError::NrgChunkId => write!(f, "NRG chunk ID unknown."),
|
||||||
|
@ -58,6 +61,7 @@ impl Error for NrgError {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
NrgError::Io(ref err) => err.description(),
|
NrgError::Io(ref err) => err.description(),
|
||||||
|
NrgError::String(ref err) => err.description(),
|
||||||
NrgError::NrgFormat => "NRG format",
|
NrgError::NrgFormat => "NRG format",
|
||||||
NrgError::NrgFormatV1 => "NRG format v1",
|
NrgError::NrgFormatV1 => "NRG format v1",
|
||||||
NrgError::NrgChunkId => "NRG chunk ID",
|
NrgError::NrgChunkId => "NRG chunk ID",
|
||||||
|
@ -71,6 +75,7 @@ impl Error for NrgError {
|
||||||
fn cause(&self) -> Option<&Error> {
|
fn cause(&self) -> Option<&Error> {
|
||||||
match *self {
|
match *self {
|
||||||
NrgError::Io(ref err) => Some(err),
|
NrgError::Io(ref err) => Some(err),
|
||||||
|
NrgError::String(ref err) => Some(err),
|
||||||
NrgError::NrgFormat => None,
|
NrgError::NrgFormat => None,
|
||||||
NrgError::NrgFormatV1 => None,
|
NrgError::NrgFormatV1 => None,
|
||||||
NrgError::NrgChunkId => None,
|
NrgError::NrgChunkId => None,
|
||||||
|
@ -87,3 +92,9 @@ impl From<io::Error> for NrgError {
|
||||||
NrgError::Io(err)
|
NrgError::Io(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ffi::IntoStringError> for NrgError {
|
||||||
|
fn from(err: ffi::IntoStringError) -> NrgError {
|
||||||
|
NrgError::String(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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`.
|
/// 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)
|
read_sized_string(fd, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
//! Miscellaneous functions to read fixed-size data from a file.
|
//! Miscellaneous functions to read fixed-size data from a file.
|
||||||
|
|
||||||
|
use std::ffi::CString;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -29,12 +30,28 @@ use std::mem;
|
||||||
use ::error::NrgError;
|
use ::error::NrgError;
|
||||||
|
|
||||||
|
|
||||||
/// Reads a String of size `size` from `fd`.
|
/// Reads a String of `size` bytes from `fd`.
|
||||||
pub fn read_sized_string(fd: &File, size: u64) -> Result<String, NrgError> {
|
///
|
||||||
let mut handle = fd.take(size);
|
/// The string will be truncated at the first null byte encountered; therefore,
|
||||||
let mut string = String::new();
|
/// its length may be less than `size` characters.
|
||||||
try!(handle.read_to_string(&mut string));
|
pub fn read_sized_string(fd: &mut File, size: usize)
|
||||||
Ok(string)
|
-> 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue