From a539b123d2cfa2cd66844b07754e87d10d028e7a Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Thu, 19 Jul 2018 03:08:04 +0000 Subject: [PATCH] bin: add an attribute field and display hierarchy using Printer --- src/bin/kbinxml.rs | 14 +++++++++++--- src/lib.rs | 10 +++------- src/printer.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 src/printer.rs diff --git a/src/bin/kbinxml.rs b/src/bin/kbinxml.rs index ee1935a..90ed660 100644 --- a/src/bin/kbinxml.rs +++ b/src/bin/kbinxml.rs @@ -15,7 +15,7 @@ use std::net::Ipv4Addr; use std::str; use failure::Fail; -use kbinxml::{Ip4Addr, KbinXml, Options, from_bytes, to_bytes}; +use kbinxml::{Ip4Addr, KbinXml, Options, Printer, from_bytes, to_bytes}; use minidom::Element; use quick_xml::Writer; @@ -33,6 +33,7 @@ pub struct Testing2 { #[derive(Debug, Deserialize, Serialize)] #[serde(rename = "test")] pub struct Testing { + #[serde(rename = "attr_the_attr")] the_attr: String, hi: u8, ok: [u8; 3], hhh: (u8, u8), @@ -128,6 +129,7 @@ fn main() -> std::io::Result<()> { //println!("element: {:#?}", element); let text_original = to_text(&element)?; display_buf(&text_original)?; + Printer::run(&contents).unwrap(); let options = Options::with_encoding(encoding_original); let buf = KbinXml::to_binary_with_options(options, &element).map_err(display_err)?; @@ -139,6 +141,7 @@ fn main() -> std::io::Result<()> { let options = Options::default(); let buf = KbinXml::to_binary_with_options(options, &element).map_err(display_err)?; eprintln!("data: {:02x?}", buf); + Printer::run(&buf).unwrap(); let mut stdout = stdout(); stdout.lock().write_all(&buf)?; @@ -152,6 +155,7 @@ fn main() -> std::io::Result<()> { */ } else { let obj = Testing { + the_attr: "the_value".to_string(), hi: 12, ok: [12, 24, 48], hhh: (55, 66), @@ -172,8 +176,12 @@ fn main() -> std::io::Result<()> { let mut file = File::create("testing.kbin")?; file.write_all(&bytes)?; - let obj2: Testing = from_bytes(&bytes).unwrap(); - eprintln!("obj2: {:#?}", obj2); + match from_bytes::(&bytes) { + Ok(obj2) => eprintln!("obj2: {:#?}", obj2), + Err(e) => eprintln!("Unable to parse generated kbin back to struct: {:#?}", e), + }; + + Printer::run(&bytes).unwrap(); } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 53d1b62..707ecab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ mod error; mod ip4; mod node_types; mod options; +mod printer; mod reader; mod sixbit; @@ -42,6 +43,7 @@ use sixbit::pack_sixbit; // Public exports pub use encoding_type::EncodingType; +pub use printer::Printer; pub use error::{KbinError, KbinErrorKind, Result}; pub use options::Options; pub use de::from_bytes; @@ -120,13 +122,7 @@ impl KbinXml { StandardType::Binary => { to.set_attr("__type", xml_type.name); - /* - let size = reader.data_buf.read_u32::().context(KbinErrorKind::BinaryLengthRead)?; - let data = reader.data_buf.get(size)?; - reader.data_buf.realign_reads(None)?; - */ let data = reader.read_bytes().context(KbinErrorKind::BinaryLengthRead)?; - to.set_attr("__size", data.len()); let len = data.len() * 2; @@ -215,7 +211,7 @@ impl KbinXml { let (array_mask, count) = match input.attr("__count") { Some(count) => { - let count = count.parse::().context(KbinErrorKind::StringParse("array count"))?; + let count = count.parse::().context(KbinErrorKind::StringParse("array count"))?; debug!("write_node => __count = {}", count); (ARRAY_MASK, count) }, diff --git a/src/printer.rs b/src/printer.rs new file mode 100644 index 0000000..1bf6920 --- /dev/null +++ b/src/printer.rs @@ -0,0 +1,42 @@ +use error::Result; +use node_types::StandardType; +use reader::Reader; + +pub struct Printer; + +impl Printer { + pub fn run(input: &[u8]) -> Result<()> { + let mut reader = Reader::new(input)?; + let mut nodes = Vec::new(); + + while let Ok((node_type, is_array)) = reader.read_node_type() { + let identifier = match node_type { + StandardType::NodeEnd | + StandardType::FileEnd => None, + _ => Some(reader.read_node_identifier()?), + }; + nodes.push((node_type, is_array, identifier)); + + if node_type == StandardType::FileEnd { + break; + } + } + + let mut indent = 0; + for (node_type, is_array, identifier) in nodes { + eprint!("{:indent$} - {:?} (is_array: {}", "", node_type, is_array, indent = indent); + if let Some(identifier) = identifier { + eprint!(", identifier: {}", identifier); + } + eprintln!(")"); + + match node_type { + StandardType::Attribute => {}, + StandardType::NodeEnd => indent -= 2, + _ => indent += 2, + }; + } + + Ok(()) + } +}