mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-09 19:15:27 -05:00
reader: support deserialization of decompressed identifiers
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use error::{KbinError, KbinErrorKind};
|
||||
use super::{SIG_COMPRESSED, SIG_UNCOMPRESSED};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Compression {
|
||||
@@ -9,16 +10,16 @@ pub enum Compression {
|
||||
impl Compression {
|
||||
pub fn from_byte(byte: u8) -> Result<Self, KbinError> {
|
||||
match byte {
|
||||
0x42 => Ok(Compression::Compressed),
|
||||
0x45 => Ok(Compression::Uncompressed),
|
||||
SIG_COMPRESSED => Ok(Compression::Compressed),
|
||||
SIG_UNCOMPRESSED => Ok(Compression::Uncompressed),
|
||||
_ => Err(KbinErrorKind::UnknownCompression.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _to_byte(&self) -> u8 {
|
||||
match *self {
|
||||
Compression::Compressed => 0x42,
|
||||
Compression::Uncompressed => 0x45,
|
||||
Compression::Compressed => SIG_COMPRESSED,
|
||||
Compression::Uncompressed => SIG_UNCOMPRESSED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#![feature(int_to_from_bytes)]
|
||||
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate encoding;
|
||||
extern crate indexmap;
|
||||
@@ -13,9 +15,6 @@ extern crate serde_bytes;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate serde;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
@@ -60,6 +59,7 @@ pub use value::Value;
|
||||
const SIGNATURE: u8 = 0xA0;
|
||||
|
||||
const SIG_COMPRESSED: u8 = 0x42;
|
||||
const SIG_UNCOMPRESSED: u8 = 0x45;
|
||||
|
||||
const ARRAY_MASK: u8 = 1 << 6; // 1 << 6 = 64
|
||||
|
||||
@@ -81,7 +81,7 @@ impl KbinXml {
|
||||
}
|
||||
|
||||
pub fn is_binary_xml(input: &[u8]) -> bool {
|
||||
input.len() > 2 && input[0] == SIGNATURE && input[1] == SIG_COMPRESSED
|
||||
input.len() > 2 && input[0] == SIGNATURE && (input[1] == SIG_COMPRESSED || input[1] == SIG_UNCOMPRESSED)
|
||||
}
|
||||
|
||||
fn from_binary_internal(&mut self, stack: &mut Vec<Element>, input: &[u8]) -> Result<(Element, EncodingType)> {
|
||||
@@ -235,6 +235,7 @@ impl KbinXml {
|
||||
array_mask,
|
||||
count);
|
||||
|
||||
// TODO: support uncompressed
|
||||
node_buf.write_u8(node_type.id | array_mask).context(KbinErrorKind::DataWrite(node_type.name))?;
|
||||
Sixbit::pack(&mut **node_buf, input.name())?;
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@ use encoding_type::EncodingType;
|
||||
use error::{KbinErrorKind, Result};
|
||||
use node_types::StandardType;
|
||||
use sixbit::Sixbit;
|
||||
use super::{ARRAY_MASK, SIGNATURE, SIG_COMPRESSED};
|
||||
use super::{ARRAY_MASK, SIGNATURE};
|
||||
|
||||
pub struct Reader<'buf> {
|
||||
compression: Compression,
|
||||
encoding: EncodingType,
|
||||
|
||||
pub(crate) node_buf: ByteBufferRead<'buf>,
|
||||
@@ -34,13 +35,8 @@ impl<'buf> Reader<'buf> {
|
||||
return Err(KbinErrorKind::HeaderValue("signature").into());
|
||||
}
|
||||
|
||||
// TODO: support uncompressed
|
||||
let compress_byte = node_buf.read_u8().context(KbinErrorKind::HeaderRead("compression"))?;
|
||||
if compress_byte != SIG_COMPRESSED {
|
||||
return Err(KbinErrorKind::HeaderValue("compression").into());
|
||||
}
|
||||
|
||||
let compressed = Compression::from_byte(compress_byte)?;
|
||||
let compression = Compression::from_byte(compress_byte)?;
|
||||
|
||||
let encoding_byte = node_buf.read_u8().context(KbinErrorKind::HeaderRead("encoding"))?;
|
||||
let encoding_negation = node_buf.read_u8().context(KbinErrorKind::HeaderRead("encoding negation"))?;
|
||||
@@ -49,7 +45,7 @@ impl<'buf> Reader<'buf> {
|
||||
return Err(KbinErrorKind::HeaderValue("encoding negation").into());
|
||||
}
|
||||
|
||||
info!("signature: 0x{:X}, compression: 0x{:X} ({:?}), encoding: 0x{:X} ({:?})", signature, compress_byte, compressed, encoding_byte, encoding);
|
||||
info!("signature: 0x{:X}, compression: 0x{:X} ({:?}), encoding: 0x{:X} ({:?})", signature, compress_byte, compression, encoding_byte, encoding);
|
||||
|
||||
let len_node = node_buf.read_u32::<BigEndian>().context(KbinErrorKind::LenNodeRead)?;
|
||||
info!("len_node: {0} (0x{0:x})", len_node);
|
||||
@@ -62,13 +58,10 @@ impl<'buf> Reader<'buf> {
|
||||
let len_data = data_buf.read_u32::<BigEndian>().context(KbinErrorKind::LenDataRead)?;
|
||||
info!("len_data: {0} (0x{0:x})", len_data);
|
||||
|
||||
//let node_buf_end = data_buf_start.into();
|
||||
|
||||
Ok(Self {
|
||||
compression,
|
||||
encoding,
|
||||
//read_mode: ReadMode::Single,
|
||||
//first_struct: true,
|
||||
//node_buf_end,
|
||||
|
||||
node_buf,
|
||||
data_buf,
|
||||
|
||||
@@ -139,7 +132,14 @@ impl<'buf> Reader<'buf> {
|
||||
}
|
||||
|
||||
pub fn read_node_identifier(&mut self) -> Result<String> {
|
||||
let value = Sixbit::unpack(&mut *self.node_buf)?;
|
||||
let value = match self.compression {
|
||||
Compression::Compressed => Sixbit::unpack(&mut *self.node_buf)?,
|
||||
Compression::Uncompressed => {
|
||||
let length = (self.node_buf.read_u8().context(KbinErrorKind::DataRead(1))? & !ARRAY_MASK) + 1;
|
||||
let bytes = self.node_buf.get(length as u32)?;
|
||||
self.encoding.decode_bytes(bytes)?
|
||||
},
|
||||
};
|
||||
debug!("Reader::read_node_identifier() => value: {:?}", value);
|
||||
|
||||
self.last_node_identifier = Some(value.clone());
|
||||
|
||||
Reference in New Issue
Block a user