mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-08 18:45:18 -05:00
Decoding now fully implemented
This commit is contained in:
@@ -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();
|
||||
|
||||
84
src/lib.rs
84
src/lib.rs
@@ -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")
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user