diff options
author | Paul Masurel <paul.masurel@gmail.com> | 2018-12-17 19:06:37 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-17 19:06:37 +0900 |
commit | b48f81c0517363e3d8f417c3ad732e94495083aa (patch) | |
tree | a3d2c0004f32abb810f807b4be60cc3ca898daa4 | |
parent | a3042e956be9f0d34216b3948835674eaf1e8108 (diff) |
Removing unsafe from bitpacking code (#455)
-rw-r--r-- | src/common/bitpacker.rs | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/src/common/bitpacker.rs b/src/common/bitpacker.rs index 593e36f..4b776ac 100644 --- a/src/common/bitpacker.rs +++ b/src/common/bitpacker.rs @@ -1,9 +1,6 @@ -use common::serialize::BinarySerializable; use std::io; -use std::io::Write; -use std::mem; use std::ops::Deref; -use std::ptr; +use byteorder::{WriteBytesExt, ByteOrder, LittleEndian}; pub(crate) struct BitPacker { mini_buffer: u64, @@ -18,7 +15,7 @@ impl BitPacker { } } - pub fn write<TWrite: Write>( + pub fn write<TWrite: io::Write>( &mut self, val: u64, num_bits: u8, @@ -28,14 +25,14 @@ impl BitPacker { let num_bits = num_bits as usize; if self.mini_buffer_written + num_bits > 64 { self.mini_buffer |= val_u64.wrapping_shl(self.mini_buffer_written as u32); - self.mini_buffer.serialize(output)?; + output.write_u64::<LittleEndian>(self.mini_buffer)?; self.mini_buffer = val_u64.wrapping_shr((64 - self.mini_buffer_written) as u32); self.mini_buffer_written = self.mini_buffer_written + num_bits - 64; } else { self.mini_buffer |= val_u64 << self.mini_buffer_written; self.mini_buffer_written += num_bits; if self.mini_buffer_written == 64 { - self.mini_buffer.serialize(output)?; + output.write_u64::<LittleEndian>(self.mini_buffer)?; self.mini_buffer_written = 0; self.mini_buffer = 0u64; } @@ -43,17 +40,18 @@ impl BitPacker { Ok(()) } - pub fn flush<TWrite: Write>(&mut self, output: &mut TWrite) -> io::Result<()> { + pub fn flush<TWrite: io::Write>(&mut self, output: &mut TWrite) -> io::Result<()> { if self.mini_buffer_written > 0 { let num_bytes = (self.mini_buffer_written + 7) / 8; - let arr: [u8; 8] = unsafe { mem::transmute::<u64, [u8; 8]>(self.mini_buffer.to_le()) }; + let mut arr: [u8; 8] = [0u8; 8]; + LittleEndian::write_u64(&mut arr, self.mini_buffer); output.write_all(&arr[..num_bytes])?; self.mini_buffer_written = 0; } Ok(()) } - pub fn close<TWrite: Write>(&mut self, output: &mut TWrite) -> io::Result<()> { + pub fn close<TWrite: io::Write>(&mut self, output: &mut TWrite) -> io::Result<()> { self.flush(output)?; // Padding the write file to simplify reads. output.write_all(&[0u8; 7])?; @@ -102,9 +100,7 @@ where addr + 8 <= data.len(), "The fast field field should have been padded with 7 bytes." ); - #[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))] - let val_unshifted_unmasked: u64 = - u64::from_le(unsafe { ptr::read_unaligned(data[addr..].as_ptr() as *const u64) }); + let val_unshifted_unmasked: u64 = LittleEndian::read_u64(&data[addr..]); let val_shifted = (val_unshifted_unmasked >> bit_shift) as u64; val_shifted & mask } @@ -126,9 +122,7 @@ where for output_val in output.iter_mut() { let addr = addr_in_bits >> 3; let bit_shift = addr_in_bits & 7; - #[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))] - let val_unshifted_unmasked: u64 = - unsafe { ptr::read_unaligned(data[addr..].as_ptr() as *const u64) }; + let val_unshifted_unmasked: u64 = LittleEndian::read_u64(&data[addr..]); let val_shifted = (val_unshifted_unmasked >> bit_shift) as u64; *output_val = val_shifted & mask; addr_in_bits += num_bits; |