Decoding now fully implemented

This commit is contained in:
Matt Bilker
2018-06-01 13:47:56 +00:00
parent 00f5283429
commit d7c82e5b18
3 changed files with 50 additions and 47 deletions

View File

@@ -13,7 +13,7 @@ fn main() -> std::io::Result<()> {
pretty_env_logger::init();
if let Some(file_name) = env::args().skip(1).next() {
println!("file_name: {}", file_name);
eprintln!("file_name: {}", file_name);
let mut file = File::open(file_name)?;
let mut contents = Vec::new();

View File

@@ -53,10 +53,10 @@ impl KbinXml {
}
fn data_buf_read(&mut self, data_buf: &mut Cursor<&[u8]>) -> Vec<u8> {
let size = data_buf.read_i32::<BigEndian>().expect("Unable to read data size");
let size = data_buf.read_u32::<BigEndian>().expect("Unable to read data size");
let mut data = vec![0; size as usize];
data_buf.read_exact(&mut data).expect("Unable to read data");
println!("data_buf_read => size: {}, data: 0x{:02x?}", data.len(), data);
trace!("data_buf_read => size: {}, data: 0x{:02x?}", data.len(), data);
self.data_buf_realign(data_buf, None);
@@ -72,9 +72,8 @@ impl KbinXml {
index -= 1;
}
data.truncate(index + 1);
println!("data_buf_read_str => size: {}, data: 0x{:02x?}", data.len(), data);
trace!("data_buf_read_str => size: {}, data: 0x{:02x?}", data.len(), data);
//String::from_utf8(data).expect("Unable to interpret string node as UTF-8")
encoding.decode_bytes(data)
}
@@ -95,7 +94,7 @@ impl KbinXml {
let old_pos = self.data_buf_offset(data_buf);
let size = data_type.size() * data_type.count();
println!("data_buf_get_aligned => old_pos: {}, size: {}", old_pos, size);
trace!("data_buf_get_aligned => old_pos: {}, size: {}", old_pos, size);
let (check_old, data) = match size {
1 => {
data_buf.seek(SeekFrom::Start(self.offset_1)).expect("Unable to seek data buffer");
@@ -128,7 +127,7 @@ impl KbinXml {
data_buf.seek(SeekFrom::Start(old_pos)).expect("Unable to seek data buffer");
let trailing = max(self.offset_1, self.offset_2);
println!("old_pos: {}, trailing: {}", old_pos, trailing);
trace!("data_buf_get_aligned => old_pos: {}, trailing: {}", old_pos, trailing);
if old_pos < trailing {
data_buf.seek(SeekFrom::Start(trailing)).expect("Unable to seek data buffer");
self.data_buf_realign(data_buf, None);
@@ -140,12 +139,12 @@ impl KbinXml {
fn data_buf_realign(&mut self, data_buf: &mut Cursor<&[u8]>, size: Option<u64>) {
let size = size.unwrap_or(4);
println!("data_buf_realign => position: {}, size: {}", data_buf.position(), size);
trace!("data_buf_realign => position: {}, size: {}", data_buf.position(), size);
while data_buf.position() % size > 0 {
data_buf.seek(SeekFrom::Current(1)).expect("Unable to seek data buffer");
}
println!("data_buf_realign => realigned to: {}", data_buf.position());
trace!("data_buf_realign => realigned to: {}", data_buf.position());
}
fn from_binary_internal(&mut self, input: &[u8]) -> Element {
@@ -163,17 +162,16 @@ impl KbinXml {
let compressed = Compression::from_byte(compress_byte).expect("Unknown compression value");
let encoding_byte = node_buf.read_u8().expect("Unable to read encoding byte");
let encoding = EncodingType::from_byte(encoding_byte).expect("Unknown encoding");
let encoding_negation = node_buf.read_u8().expect("Unable to read encoding negation byte");
let encoding = EncodingType::from_byte(encoding_byte).expect("Unknown encoding");
assert_eq!(encoding_negation, 0xFF ^ encoding_byte);
println!("signature: 0x{:x}", signature);
println!("compression: 0x{:x} ({:?})", compress_byte, compressed);
println!("encoding: 0x{:x} ({:?})", encoding_byte, encoding);
info!("signature: 0x{:x}", signature);
info!("compression: 0x{:x} ({:?})", compress_byte, compressed);
info!("encoding: 0x{:x} ({:?})", encoding_byte, encoding);
let len_node = node_buf.read_u32::<BigEndian>().expect("Unable to read len_node");
println!("len_node: {} (0x{:x})", len_node, len_node);
info!("len_node: {} (0x{:x})", len_node, len_node);
// We have read 8 bytes so far, so offset the start of the data buffer from
// our current position.
@@ -184,11 +182,11 @@ impl KbinXml {
let pos = data_buf.position();
self.offset_1 = pos;
self.offset_2 = pos;
println!("offset_1: {}, offset_2: {}", self.offset_1, self.offset_2);
trace!("offset_1: {}, offset_2: {}", self.offset_1, self.offset_2);
}
let len_data = data_buf.read_u32::<BigEndian>().expect("Unable to read len_data");
println!("len_data: {} (0x{:x})", len_data, len_data);
info!("len_data: {} (0x{:x})", len_data, len_data);
let mut stack: Vec<Element> = Vec::new();
{
@@ -199,31 +197,28 @@ impl KbinXml {
let node_type = raw_node_type & !64;
let xml_type = KbinType::from_u8(node_type);
println!("raw_node_type: {}, node_type: {:?} ({}), is_array: {}", raw_node_type, xml_type, node_type, is_array);
debug!("raw_node_type: {}, node_type: {:?} ({}), is_array: {}", raw_node_type, xml_type, node_type, is_array);
match xml_type {
KbinType::NodeEnd => {
KbinType::NodeEnd | KbinType::FileEnd => {
if stack.len() > 1 {
let node = stack.pop().expect("Stack must have last node");
if let Some(to) = stack.last_mut() {
to.append_child(node);
}
}
continue;
},
KbinType::FileEnd => {
if stack.len() > 1 {
let node = stack.pop().expect("Stack must have last node");
if let Some(to) = stack.last_mut() {
to.append_child(node);
}
if xml_type == KbinType::NodeEnd {
continue;
} else if xml_type == KbinType::FileEnd {
break;
}
break;
},
_ => {},
};
let name = unpack_sixbit(&mut node_buf);
if xml_type == KbinType::NodeStart {
stack.push(Element::bare(name));
} else {
@@ -234,16 +229,26 @@ impl KbinXml {
match xml_type {
KbinType::Attribute => {
let val = self.data_buf_read_str(&mut data_buf, encoding);
println!("attr name: {}, val: {}", name, val);
debug!("attr name: {}, val: {}", name, val);
to.set_attr(name, val);
},
// Removing null bytes is *so much* fun.
//
// Handle String nodes separately to use the string reading logic
// which automatically removes trailing null bytes.
KbinType::String => {
to.set_attr("__type", xml_type.name());
let val = self.data_buf_read_str(&mut data_buf, encoding);
debug!("name: {}, val: {}", name, val);
to.append_text_node(val);
},
_ => {
to.set_attr("__type", xml_type.name());
let type_size = xml_type.size();
let type_count = xml_type.count();
let (is_array, size) = if xml_type.count() == -1 {
println!("xml_type.count() == -1");
let (is_array, size) = if type_count == -1 {
(true, data_buf.read_u32::<BigEndian>().expect("Unable to read binary/string byte length"))
} else if is_array {
let node_size = type_size * type_count;
@@ -256,7 +261,7 @@ impl KbinXml {
(false, 1)
};
println!("type: {:?}, type_size: {}, type_count: {}, is_array: {}, size: {}",
debug!("type: {:?}, type_size: {}, type_count: {}, is_array: {}, size: {}",
xml_type,
type_size,
type_count,
@@ -271,22 +276,21 @@ impl KbinXml {
} else {
self.data_buf_get_aligned(&mut data_buf, xml_type)
};
println!("data: 0x{:02x?}", data);
if xml_type == KbinType::String {
let val = encoding.decode_bytes(data);
println!("name: {}, string: {}", name, val);
to.append_text_node(val);
} else if xml_type == KbinType::Binary {
debug!("data: 0x{:02x?}", data);
if xml_type == KbinType::Binary {
to.set_attr("__size", data.len());
let len = data.len() * 2;
let val = data.into_iter().fold(String::with_capacity(len), |mut val, x| {
write!(val, "{:02x}", x).expect("Failed to append hex char");
val
});
println!("name: {}, string: {}", name, val);
debug!("name: {}, string: {}", name, val);
to.append_text_node(val);
} else {
let inner_value = xml_type.parse_bytes(&data);
println!("name: {}, string: {}", name, inner_value);
debug!("name: {}, string: {}", name, inner_value);
to.append_text_node(inner_value);
}
},
@@ -296,7 +300,7 @@ impl KbinXml {
}
}
if stack.len() > 1 {
println!("stack: {:#?}", stack);
warn!("stack: {:#?}", stack);
}
stack.truncate(1);
stack.pop().expect("Stack must have root node")

View File

@@ -9,7 +9,7 @@ macro_rules! number_impl {
$(
impl KbinWrapperType<$inner_type> for $inner_type {
fn from_kbin_bytes(output: &mut String, input: &[u8]) {
println!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input);
trace!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input);
let mut data = [0; ::std::mem::size_of::<$inner_type>()];
data.clone_from_slice(input);
@@ -23,7 +23,7 @@ macro_rules! number_impl {
$(
impl KbinWrapperType<$inner_type> for $inner_type {
fn from_kbin_bytes(output: &mut String, input: &[u8]) {
println!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input);
trace!("KbinWrapperType<{}> => input: {:02x?}", stringify!($inner_type), input);
let mut data = [0; ::std::mem::size_of::<$inner_type>()];
data.clone_from_slice(input);
@@ -42,8 +42,7 @@ number_impl!(float; u32 => f32, u64 => f64);
impl KbinWrapperType<bool> for bool {
fn from_kbin_bytes(output: &mut String, input: &[u8]) {
println!("KbinWrapperType<bool> => input: {:02x?}", input);
//String::from("bool")
trace!("KbinWrapperType<bool> => input: {:02x?}", input);
let value = match input[0] {
0x00 => "0",
@@ -57,7 +56,7 @@ impl KbinWrapperType<bool> for bool {
struct Ip4;
impl KbinWrapperType<Ip4> for Ip4 {
fn from_kbin_bytes(output: &mut String, input: &[u8]) {
println!("KbinWrapperType<Ip4> => input: {:02x?}", input);
trace!("KbinWrapperType<Ip4> => input: {:02x?}", input);
if input.len() < 4 {
panic!("Ip4 type requires 4 bytes of data, input: {:02x?}", input);
@@ -159,7 +158,7 @@ macro_rules! construct_types {
{
let type_size = (size as usize) * (count as usize);
let arr_count = input.len() / type_size;
println!("parse_bytes({}) => size: {}, count: {}, input_len: {}, arr_count: {}", name, size, count, input.len(), arr_count);
debug!("parse_bytes({}) => size: {}, count: {}, input_len: {}, arr_count: {}", name, size, count, input.len(), arr_count);
let mut result = String::new();