diff --git a/src/endian.rs b/src/endian.rs index 178b436..1260052 100644 --- a/src/endian.rs +++ b/src/endian.rs @@ -46,12 +46,8 @@ pub struct LittleEndian; macro_rules! generate_load { ($name:ident, $int_type:ident, $from_func:ident) => ( fn $name(buf: &[u8], offset: usize) -> $int_type { - // Check if the specified range of the slice is valid - // before transmute(). This will also detect the - // wrap-around of (offset + size_of) in the release mode. - let buf = &buf[offset .. offset + mem::size_of::<$int_type>()]; - let ptr = buf.as_ptr() as *const $int_type; - let num = unsafe { mem::transmute(*ptr) }; + let mut num = [0u8; mem::size_of::<$int_type>()]; + num.copy_from_slice(&buf[offset .. offset + mem::size_of::<$int_type>()]); $int_type::$from_func(num) } ) @@ -61,29 +57,28 @@ macro_rules! generate_write { ($name:ident, $int_type:ident, $type_size:expr, $to_func:ident) => ( fn $name(w: &mut W, num: $int_type) -> io::Result<()> where W: io::Write { - let buf: [u8; $type_size] = - unsafe { mem::transmute(num.$to_func()) }; + let buf = num.$to_func(); w.write_all(&buf) } ) } impl Endian for BigEndian { - generate_load!(loadu16, u16, from_be); - generate_load!(loadu32, u32, from_be); - generate_load!(loadu64, u64, from_be); - generate_write!(writeu16, u16, 2, to_be); - generate_write!(writeu32, u32, 4, to_be); - generate_write!(writeu64, u64, 8, to_be); + generate_load!(loadu16, u16, from_be_bytes); + generate_load!(loadu32, u32, from_be_bytes); + generate_load!(loadu64, u64, from_be_bytes); + generate_write!(writeu16, u16, 2, to_be_bytes); + generate_write!(writeu32, u32, 4, to_be_bytes); + generate_write!(writeu64, u64, 8, to_be_bytes); } impl Endian for LittleEndian { - generate_load!(loadu16, u16, from_le); - generate_load!(loadu32, u32, from_le); - generate_load!(loadu64, u64, from_le); - generate_write!(writeu16, u16, 2, to_le); - generate_write!(writeu32, u32, 4, to_le); - generate_write!(writeu64, u64, 8, to_le); + generate_load!(loadu16, u16, from_le_bytes); + generate_load!(loadu32, u32, from_le_bytes); + generate_load!(loadu64, u64, from_le_bytes); + generate_write!(writeu16, u16, 2, to_le_bytes); + generate_write!(writeu32, u32, 4, to_le_bytes); + generate_write!(writeu64, u64, 8, to_le_bytes); } #[cfg(test)] diff --git a/src/util.rs b/src/util.rs index 1226503..5780c51 100644 --- a/src/util.rs +++ b/src/util.rs @@ -34,12 +34,12 @@ const ASCII_A: u8 = 0x41; const ASCII_Z: u8 = 0x5a; pub fn read8(reader: &mut R) -> Result where R: io::Read { - let mut buf: [u8; 1] = unsafe { ::std::mem::uninitialized() }; + let mut buf = [0u8; 1]; reader.read_exact(&mut buf).and(Ok(buf[0])) } pub fn read16(reader: &mut R) -> Result where R: io::Read { - let mut buf: [u8; 2] = unsafe { ::std::mem::uninitialized() }; + let mut buf = [0u8; 2]; reader.read_exact(&mut buf)?; Ok(((buf[0] as u16) << 8) + buf[1] as u16) } diff --git a/src/value.rs b/src/value.rs index fab5484..c8073c9 100644 --- a/src/value.rs +++ b/src/value.rs @@ -357,10 +357,10 @@ fn parse_rational<'a, E>(data: &'a [u8], offset: usize, count: usize) fn parse_sbyte<'a>(data: &'a [u8], offset: usize, count: usize) -> Value<'a> { - let uslice = &data[offset .. offset + count]; - let islice = unsafe { ::std::slice::from_raw_parts( - uslice.as_ptr() as *const i8, count) }; - Value::SByte(islice.to_vec()) + let bytes = data[offset .. offset + count].into_iter() + .map(|x| *x as i8) + .collect(); + Value::SByte(bytes) } fn parse_undefined<'a>(data: &'a [u8], offset: usize, count: usize) diff --git a/src/writer.rs b/src/writer.rs index 2da1ab1..bfdf2ef 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -26,7 +26,6 @@ use std::io; use std::io::{Seek, SeekFrom, Write}; -use std::slice; use endian::{Endian, BigEndian, LittleEndian}; use error::Error; @@ -527,9 +526,10 @@ fn compose_value(value: &Value) Ok((5, vec.len(), buf)) }, Value::SByte(ref vec) => { - let uslice = unsafe { slice::from_raw_parts( - vec.as_ptr() as *const u8, vec.len()) }; - Ok((6, vec.len(), uslice.to_vec())) + let bytes = vec.into_iter() + .map(|x| *x as u8) + .collect(); + Ok((6, vec.len(), bytes)) }, Value::Undefined(ref s, _) => Ok((7, s.len(), s.to_vec())),