sixbit: move methods into struct

This commit is contained in:
Matt Bilker
2018-09-03 00:02:29 -04:00
parent 7ba2293151
commit d0e712e319
5 changed files with 69 additions and 65 deletions

View File

@@ -44,7 +44,7 @@ mod ser;
use byte_buffer::ByteBufferWrite;
use node_types::StandardType;
use reader::Reader;
use sixbit::pack_sixbit;
use sixbit::Sixbit;
// Public exports
pub use encoding_type::EncodingType;
@@ -236,7 +236,7 @@ impl KbinXml {
count);
node_buf.write_u8(node_type.id | array_mask).context(KbinErrorKind::DataWrite(node_type.name))?;
pack_sixbit(&mut **node_buf, input.name())?;
Sixbit::pack(&mut **node_buf, input.name())?;
match node_type {
StandardType::NodeStart => {},
@@ -281,7 +281,7 @@ impl KbinXml {
let node_type = StandardType::Attribute;
node_buf.write_u8(node_type.id).context(KbinErrorKind::DataWrite(node_type.name))?;
pack_sixbit(&mut **node_buf, key)?;
Sixbit::pack(&mut **node_buf, key)?;
}
for child in input.children() {

View File

@@ -8,7 +8,7 @@ use compression::Compression;
use encoding_type::EncodingType;
use error::{KbinErrorKind, Result};
use node_types::StandardType;
use sixbit::unpack_sixbit;
use sixbit::Sixbit;
use super::{ARRAY_MASK, SIGNATURE, SIG_COMPRESSED};
pub struct Reader<'buf> {
@@ -122,7 +122,7 @@ impl<'buf> Reader<'buf> {
pub fn peek_node_identifier(&mut self) -> Result<String> {
let old_pos = self.node_buf.position();
let _raw_node_type = self.node_buf.read_u8().context(KbinErrorKind::NodeTypeRead)?;
let value = unpack_sixbit(&mut *self.node_buf)?;
let value = Sixbit::unpack(&mut *self.node_buf)?;
let size = self.node_buf.position() - old_pos;
self.node_buf.seek(SeekFrom::Start(old_pos)).context(KbinErrorKind::DataRead(size as usize))?;
@@ -139,7 +139,7 @@ impl<'buf> Reader<'buf> {
}
pub fn read_node_identifier(&mut self) -> Result<String> {
let value = unpack_sixbit(&mut *self.node_buf)?;
let value = Sixbit::unpack(&mut *self.node_buf)?;
debug!("Reader::read_node_identifier() => value: {:?}", value);
self.last_node_identifier = Some(value.clone());

View File

@@ -5,7 +5,7 @@ use serde::ser::{Serialize, SerializeMap};
use error::{Error, KbinErrorKind};
use node_types::StandardType;
use ser::{Result, Serializer, TypeHint, WriteMode, ARRAY_MASK};
use sixbit::pack_sixbit;
use sixbit::Sixbit;
pub struct Map<'a> {
ser: &'a mut Serializer,
@@ -29,7 +29,7 @@ impl<'a> Map<'a> {
let node_type = StandardType::NodeStart;
ser.node_buf.write_u8(node_type.id).context(KbinErrorKind::DataWrite(node_type.name))?;
pack_sixbit(&mut *ser.node_buf, name)?;
Sixbit::pack(&mut *ser.node_buf, name)?;
}
Ok(Self { ser })

View File

@@ -9,7 +9,7 @@ use byte_buffer::ByteBufferWrite;
use encoding_type::EncodingType;
use node_types::StandardType;
use error::{Error, KbinError, KbinErrorKind};
use sixbit::pack_sixbit;
use sixbit::Sixbit;
use super::{ARRAY_MASK, SIGNATURE, SIG_COMPRESSED};
mod buffer;
@@ -114,7 +114,7 @@ impl Serializer {
}
fn write_identifier(&mut self, key: &str) -> Result<()> {
pack_sixbit(&mut *self.node_buf, key)?;
Sixbit::pack(&mut *self.node_buf, key)?;
Ok(())
}
}

View File

@@ -21,63 +21,67 @@ lazy_static! {
};
}
pub fn pack_sixbit<T>(writer: &mut T, input: &str) -> Result<(), KbinError>
where T: Write
{
let sixbit_chars = input
.bytes()
.map(|ch| {
*BYTE_MAP.get(&ch).expect("Character must be a valid sixbit character")
});
let len = input.len() as usize;
let padding = 8 - len * 6 % 8;
let padding = if padding == 8 { 0 } else { padding };
let real_len = (len * 6 + padding) / 8;
debug!("sixbit_len: {}, real_len: {}, padding: {}", len, real_len, padding);
pub struct Sixbit;
let mut bits = BigUint::new(vec![0; real_len]);
for ch in sixbit_chars {
bits <<= 6;
bits |= BigUint::from_u8(ch).unwrap();
impl Sixbit {
pub fn pack<T>(writer: &mut T, input: &str) -> Result<(), KbinError>
where T: Write
{
let sixbit_chars = input
.bytes()
.map(|ch| {
*BYTE_MAP.get(&ch).expect("Character must be a valid sixbit character")
});
let len = input.len() as usize;
let padding = 8 - len * 6 % 8;
let padding = if padding == 8 { 0 } else { padding };
let real_len = (len * 6 + padding) / 8;
debug!("sixbit_len: {}, real_len: {}, padding: {}", len, real_len, padding);
let mut bits = BigUint::new(vec![0; real_len]);
for ch in sixbit_chars {
bits <<= 6;
bits |= BigUint::from_u8(ch).unwrap();
}
bits <<= padding;
let bytes = bits.to_bytes_be();
writer.write_u8(len as u8).context(KbinErrorKind::SixbitLengthWrite)?;
writer.write(&bytes).context(KbinErrorKind::SixbitWrite)?;
Ok(())
}
bits <<= padding;
let bytes = bits.to_bytes_be();
writer.write_u8(len as u8).context(KbinErrorKind::SixbitLengthWrite)?;
writer.write(&bytes).context(KbinErrorKind::SixbitWrite)?;
pub fn unpack<T>(reader: &mut T) -> Result<String, KbinError>
where T: Read
{
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);
Ok(())
}
pub fn unpack_sixbit<T>(reader: &mut T) -> Result<String, KbinError>
where T: Read
{
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);
let mut buf = vec![0; real_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..=len).map(|i| {
// Get the current sixbit part starting from the the left most bit in
// big endian order
let shift = ((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();
debug!("result: {}", result);
Ok(result)
let mut buf = vec![0; real_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..=len).map(|i| {
// Get the current sixbit part starting from the the left most bit in
// big endian order
let shift = ((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();
debug!("result: {}", result);
Ok(result)
}
}