feat: add support for compressed NBT
this switches from hematite_nbt to fastnbt.
This commit is contained in:
parent
0abae7876f
commit
e30765f7c1
2 changed files with 48 additions and 5 deletions
|
@ -12,7 +12,8 @@ serde = "1.0"
|
||||||
serde-value = "0.7"
|
serde-value = "0.7"
|
||||||
|
|
||||||
ciborium = "0.2.0"
|
ciborium = "0.2.0"
|
||||||
hematite-nbt = "0.5.2"
|
fastnbt = "2.1.0"
|
||||||
|
flate2 = "1.0.23"
|
||||||
ron = "0.7.0"
|
ron = "0.7.0"
|
||||||
serde-lexpr = "0.1.2"
|
serde-lexpr = "0.1.2"
|
||||||
serde-xml-rs = "0.5.1"
|
serde-xml-rs = "0.5.1"
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
use flate2::{
|
||||||
|
bufread::{GzDecoder, ZlibDecoder},
|
||||||
|
write::GzEncoder,
|
||||||
|
Compression,
|
||||||
|
};
|
||||||
use miette::{Context, IntoDiagnostic};
|
use miette::{Context, IntoDiagnostic};
|
||||||
use sercon_base::Backend;
|
use sercon_base::Backend;
|
||||||
use serde_value::Value;
|
use serde_value::Value;
|
||||||
|
@ -9,16 +14,53 @@ pub struct NbtBackend;
|
||||||
|
|
||||||
impl Backend for NbtBackend {
|
impl Backend for NbtBackend {
|
||||||
fn serialize(&self, out: &mut dyn Write, data: Value) -> miette::Result<()> {
|
fn serialize(&self, out: &mut dyn Write, data: Value) -> miette::Result<()> {
|
||||||
nbt::to_writer(out, &data, None)
|
let gz = GzEncoder::new(out, Compression::new(5));
|
||||||
|
fastnbt::to_writer(gz, &data)
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
.wrap_err("NBT serialization error")
|
.wrap_err("failed to serialize NBT data")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(&self, data: &mut dyn Read) -> miette::Result<Value> {
|
fn deserialize(&self, data: &mut dyn Read) -> miette::Result<Value> {
|
||||||
nbt::from_reader(data)
|
let mut vec = vec![];
|
||||||
|
data.read_to_end(&mut vec).into_diagnostic()?;
|
||||||
|
|
||||||
|
let compression = vec
|
||||||
|
.get(0..2)
|
||||||
|
.map(|m| match m {
|
||||||
|
[0x1f, 0x8b] => CompressionType::Gzip,
|
||||||
|
[0x78, 0x01] | [0x78, 0x9C] | [0x78, 0xDA] => CompressionType::Zlib,
|
||||||
|
_ => CompressionType::None,
|
||||||
|
})
|
||||||
|
.unwrap_or(CompressionType::None);
|
||||||
|
let mut decomp = vec![];
|
||||||
|
match compression {
|
||||||
|
CompressionType::Gzip => {
|
||||||
|
GzDecoder::new(&vec[..])
|
||||||
|
.read_to_end(&mut decomp)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("data gz decompression failed")?;
|
||||||
|
},
|
||||||
|
CompressionType::Zlib => {
|
||||||
|
ZlibDecoder::new(&vec[..])
|
||||||
|
.read_to_end(&mut decomp)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("data zlib decompression failed")?;
|
||||||
|
},
|
||||||
|
CompressionType::None => decomp.copy_from_slice(&vec),
|
||||||
|
}
|
||||||
|
|
||||||
|
fastnbt::from_bytes(&decomp)
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
.wrap_err("NBT deserialization error")
|
.wrap_err("NBT deserialization failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_filetype_backend!(NbtBackend, ["nbt"]);
|
impl_filetype_backend!(NbtBackend, ["nbt"]);
|
||||||
|
|
||||||
|
enum CompressionType {
|
||||||
|
Gzip,
|
||||||
|
Zlib,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue