use data::{NBT, NBTFile};
use byteorder::WriteBytesExt;
use std::io;
use std::io::Write;
pub fn write_file<W: Write>(w: &mut W, file: &NBTFile) -> io::Result<()> {
write!(w, "{}", file.compression.to_str())?;
write_tag(w, &file.root, 0, true)?;
Ok(())
}
fn write_tag<W: Write>(w: &mut W,
tag: &NBT,
indent: u64,
compound: bool)
-> io::Result<()> {
match tag {
&NBT::End => (),
&NBT::Byte(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::Short(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::Int(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::Long(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::Float(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::Double(x) => {
if compound {
write!(w, " ")?;
}
writeln!(w, "{}", x)?;
},
&NBT::ByteArray(ref x) => {
writeln!(w, " {}", x.len())?;
for val in x {
write_indent(w, indent)?;
writeln!(w, "{}", val)?;
}
},
&NBT::String(ref x) => {
if compound {
write!(w, " ")?;
}
writeln!(w,
r#""{}""#,
x.replace(r"\", r"\\").replace(r#"""#, r#"\""#))?
},
&NBT::List(ref x) => {
let tag_type = if x.len() > 0 {
x[0].type_string()
} else {
"End"
};
writeln!(w, " {} {}", tag_type, x.len())?;
for val in x {
match val {
&NBT::Compound(..) => (),
_ => write_indent(w, indent)?,
}
write_tag(w, val, indent + 1, false)?;
}
},
&NBT::Compound(ref x) => {
if compound {
writeln!(w, "")?;
}
for &(ref key, ref val) in x {
write_indent(w, indent)?;
w.write_all(val.type_string().as_bytes())?;
write!(w,
r#" "{}""#,
key.replace(r"\", r"\\").replace(r#"""#, r#"\""#))?;
write_tag(w, val, indent + 1, true)?;
}
write_indent(w, indent)?;
writeln!(w, "End")?;
},
&NBT::IntArray(ref x) => {
writeln!(w, " {}", x.len())?;
for val in x {
write_indent(w, indent)?;
writeln!(w, "{}", val)?;
}
},
}
Ok(())
}
fn write_indent<W: Write>(w: &mut W, indent: u64) -> io::Result<()> {
for _ in 0..indent {
w.write_u8(9)?;
}
Ok(())
}