From cf09020aca6bb626e8f5fe4ca1a113e619b24b3d Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Mon, 3 Sep 2018 22:43:56 -0400 Subject: [PATCH] sixbit: unpack strings without BigUint --- Cargo.toml | 1 - src/lib.rs | 1 - src/sixbit.rs | 35 +++++++++++++---------------------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e23745..c214243 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ indexmap = { version = "1.0.1", features = ["serde-1"] } lazy_static = "1.0.0" log = "0.4.1" minidom = "0.9.0" -num = "0.2.0" pretty_env_logger = "0.2.3" quick-xml = "0.12.1" rustc-hex = "2.0.1" diff --git a/src/lib.rs b/src/lib.rs index 1fe32f1..ddf96b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,6 @@ extern crate byteorder; extern crate encoding; extern crate indexmap; extern crate minidom; -extern crate num; extern crate rustc_hex; extern crate serde_bytes; diff --git a/src/sixbit.rs b/src/sixbit.rs index d4cbf01..9ca27aa 100644 --- a/src/sixbit.rs +++ b/src/sixbit.rs @@ -3,7 +3,6 @@ use std::io::{Read, Write}; use byteorder::{ReadBytesExt, WriteBytesExt}; use failure::ResultExt; -use num::{BigUint, FromPrimitive, ToPrimitive}; use error::{KbinError, KbinErrorKind}; @@ -21,7 +20,7 @@ lazy_static! { }; } -pub type SixbitSize = (u8, usize, usize); +pub type SixbitSize = (u8, usize); pub struct Sixbit; @@ -32,11 +31,9 @@ impl Sixbit { let len = reader.read_u8().context(KbinErrorKind::SixbitLengthRead)?; let real_len = (f32::from(len * 6) / 8f32).ceil(); let real_len = (real_len as u32) as usize; - let padding = (8 - ((len * 6) % 8)) as usize; - let padding = if padding == 8 { 0 } else { padding }; - debug!("sixbit_len: {}, real_len: {}, padding: {}", len, real_len, padding); + debug!("sixbit_len: {}, real_len: {}", len, real_len); - Ok((len, real_len, padding)) + Ok((len, real_len)) } pub fn pack(writer: &mut T, input: &str) -> Result<(), KbinError> @@ -71,26 +68,20 @@ impl Sixbit { pub fn unpack(reader: &mut T) -> Result where T: Read { - let (sixbit_len, len, padding) = Sixbit::size(reader)?; + let (sixbit_len, len) = Sixbit::size(reader)?; let mut buf = vec![0; len]; reader.read_exact(&mut buf).context(KbinErrorKind::SixbitRead)?; - let bits = BigUint::from_bytes_be(&buf); - let bits = bits >> padding; - debug!("bits: 0b{:b}", bits); - - let mask = BigUint::from_u8(0b111111).unwrap(); - let result = (1..=sixbit_len).map(|i| { - // Get the current sixbit part starting from the the left most bit in - // big endian order - let shift = ((sixbit_len - i) * 6) as usize; - let bits = bits.clone(); - let mask = mask.clone(); - let current = (bits >> shift) & mask; - - CHAR_MAP[current.to_usize().unwrap()] as char - }).collect(); + let mut result = String::with_capacity(sixbit_len as usize); + for i in 0..=len { + let mut current = 0u8; + for j in 0..6 { + let k = (i * 6) + j; + current |= (buf[k / 8] >> (7 - (k % 8)) & 1) << (5 - (k % 6)); + } + result.push(CHAR_MAP[current as usize] as char); + } debug!("result: {}", result); Ok(result)