mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-15 05:55:09 -05:00
sixbit: move methods into struct
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
114
src/sixbit.rs
114
src/sixbit.rs
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user