diff --git a/.vscode/settings.json b/.vscode/settings.json index 5658043..d8da082 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,7 @@ "crates/shen-nbt1/Cargo.toml", "crates/shen-nbt2/Cargo.toml", "crates/shen-nbt3/Cargo.toml", + "crates/shen-nbt4/Cargo.toml", + "crates/nbt-test/Cargo.toml", ] } \ No newline at end of file diff --git a/crates/nbt-test/Cargo.toml b/crates/nbt-test/Cargo.toml new file mode 100644 index 0000000..69c1419 --- /dev/null +++ b/crates/nbt-test/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "nbt-test" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +default = [] +debug = [] +core_debug = [] +internal_opt = [] + + +[dependencies] +fastnbt = "2.4.4" +shen-nbt1 = { path = "../shen-nbt1" } +shen-nbt2 = { path = "../shen-nbt2" } +shen-nbt3 = { path = "../shen-nbt3" } +shen-nbt4 = { path = "../shen-nbt4" } + diff --git a/crates/shen-nbt1/src/main.rs b/crates/nbt-test/src/main.rs similarity index 81% rename from crates/shen-nbt1/src/main.rs rename to crates/nbt-test/src/main.rs index db7c5a7..d02a2cf 100644 --- a/crates/shen-nbt1/src/main.rs +++ b/crates/nbt-test/src/main.rs @@ -1,41 +1,23 @@ -#![feature(buf_read_has_data_left)] - -use crate::data::Reader; -use std::io::Read; - -mod data; -mod read; - fn main() { - println!("Hello, world!"); + println!("Hello, nbt!"); // sleep 1s - std::thread::sleep(std::time::Duration::from_secs(2)); + println!("====== small test ======"); small_read_test(); - std::thread::sleep(std::time::Duration::from_secs(2)); + println!("====== big test ======"); big_read_test(); - std::thread::sleep(std::time::Duration::from_secs(2)); + println!("====== cli test ======"); cli_read_test(); - std::thread::sleep(std::time::Duration::from_secs(2)); } -// bincode-org/bincode: A binary encoder / decoder implementation in Rust. -// https://github.com/bincode-org/bincode - fn cli_read_test() { - let mut buff: Vec = Vec::new(); - // 从 CLI 读取文件名 - let filename = std::env::args().nth(1).unwrap(); - // 打开文件 - { - let mut file = std::fs::File::open(filename).unwrap(); - // 转为 &[u8] - std::thread::sleep(std::time::Duration::from_secs(2)); - println!("file size: {}", file.metadata().unwrap().len()); - _ = file.read_to_end(&mut buff).unwrap(); - std::thread::sleep(std::time::Duration::from_secs(2)); + let mut args = std::env::args(); + // 如果有, 取出 + if let Some(arg) = args.nth(1) { + let data = std::fs::read(arg).unwrap(); + read_test(data); + } else { + println!("Usage: cargo run --release -- "); } - // 读取数据 - read_test(buff); } fn small_read_test() { @@ -156,44 +138,68 @@ fn big_read_test() { read_test(data.to_vec()); } -fn read_test(data: Vec) { - let len = data.len(); + +macro_rules! test_lib { + ($func: block, $name: expr, $len: expr) => { + std::thread::sleep(std::time::Duration::from_secs(1)); + let start_time = std::time::Instant::now(); + $func + let end_time = std::time::Instant::now(); + println!("=== {} ===", $name); + print!("time: {:?}", end_time - start_time); + println!(" speed: {:?} (bytes/sec)", $len as f64 / (end_time - start_time).as_secs_f64()); + println!("{:?} (kb/sec)", $len as f64 / (end_time - start_time).as_secs_f64() / 1024.0); + println!( + "{:?} (mb/sec)", + $len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0 + ); + println!( + "{:?} (gb/sec)", + $len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0 / 1024.0 + ); + #[cfg(feature = "core_debug")] + println!("nbt_data: {:#?}", nbt_data); + }; +} + +fn read_test(in_data: Vec) { + let len = in_data.len(); #[cfg(feature = "debug")] println!("data: {:?}", data); - let cursor: Reader = std::io::Cursor::new(data.as_slice()); - std::thread::sleep(std::time::Duration::from_secs(2)); - let start_time = std::time::Instant::now(); - - let nbt_data = data::NbtItem::try_from(cursor).unwrap(); - - let end_time = std::time::Instant::now(); - println!("===local nbt==="); - println!("time: {:?}", end_time - start_time); - println!("speed: {:?} (bytes/sec)", len as f64 / (end_time - start_time).as_secs_f64()); - println!("{:?} (kb/sec)", len as f64 / (end_time - start_time).as_secs_f64() / 1024.0); - println!( - "{:?} (mb/sec)", - len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0 - ); - #[cfg(feature = "core_debug")] - println!("nbt_data: {:#?}", nbt_data); - - std::thread::sleep(std::time::Duration::from_secs(2)); - let start_time = std::time::Instant::now(); - - let nbt_data: fastnbt::Value = fastnbt::from_bytes(data.as_slice()).unwrap(); - - let end_time = std::time::Instant::now(); - println!("===fastnbt==="); - println!("time: {:?}", end_time - start_time); - println!("speed: {:?} (bytes/sec)", len as f64 / (end_time - start_time).as_secs_f64()); - println!("{:?} (kb/sec)", len as f64 / (end_time - start_time).as_secs_f64() / 1024.0); - println!( - "{:?} (mb/sec)", - len as f64 / (end_time - start_time).as_secs_f64() / 1024.0 / 1024.0 + let data = in_data.clone(); + let data2 = in_data.clone(); + let data3 = in_data.clone(); + let data4 = in_data.clone(); + std::thread::sleep(std::time::Duration::from_secs(1)); + test_lib!( + { + let cursor: shen_nbt1::data::Reader = std::io::Cursor::new(data.as_slice()); + let _nbt_data = shen_nbt1::data::NbtItem::try_from(cursor).unwrap(); + }, "nbt v1", len ); - #[cfg(feature = "core_debug")] - println!("nbt_data: {:#?}", nbt_data); + test_lib!( + { + let _nbt_data = shen_nbt2::Value::from_vec(data2); + }, "nbt v2", len + ); + + test_lib!( + { + let _nbt_data = shen_nbt3::Value::from_vec(data3); + }, "nbt v3", len + ); + + test_lib!( + { + let _nbt_data = shen_nbt4::Value::from_vec(data4); + }, "nbt v4", len + ); + + test_lib!( + { + let _nbt_data: fastnbt::Value = fastnbt::from_bytes(data.as_slice()).unwrap(); + }, "fastnbt", len + ); } diff --git a/crates/shen-nbt1/Cargo.toml b/crates/shen-nbt1/Cargo.toml index 8ec312f..b2b2df6 100644 --- a/crates/shen-nbt1/Cargo.toml +++ b/crates/shen-nbt1/Cargo.toml @@ -1,13 +1,10 @@ [package] -name = "nbt-rust" +name = "shen-nbt1" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[dependencies] -fastnbt = "2.4.4" - [features] default = [] debug = [] diff --git a/crates/shen-nbt1/src/lib.rs b/crates/shen-nbt1/src/lib.rs new file mode 100644 index 0000000..aa95f8f --- /dev/null +++ b/crates/shen-nbt1/src/lib.rs @@ -0,0 +1,4 @@ +#![feature(buf_read_has_data_left)] + +pub mod data; +pub mod read; diff --git a/crates/shen-nbt4/src/lib.rs b/crates/shen-nbt4/src/lib.rs index 0f85f0b..92dd783 100644 --- a/crates/shen-nbt4/src/lib.rs +++ b/crates/shen-nbt4/src/lib.rs @@ -182,7 +182,7 @@ pub enum Value<'value> { /// 12 LongArray(Vec), /// 9 - List(Vec), + List(Vec>), /// 10 Compound(Vec<(String, Value<'value>)>), } @@ -216,31 +216,37 @@ impl<'value> Value<'value> { 1 => { let raw_data = data.read_bytes(length as usize); let list = raw_reading::slice_as_byte_array(raw_data.as_slice()); + let list = list.iter().map(|x| Self::Byte(*x)).collect(); Self::List(list) } 2 => { let raw_data = data.read_bytes(length as usize * 2); let list = raw_reading::slice_as_short_array(raw_data.as_slice()).unwrap(); + let list = list.iter().map(|x| Self::Short(*x)).collect(); Self::List(list) } 3 => { let raw_data = data.read_bytes(length as usize * 4); let list = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap(); + let list = list.iter().map(|x| Self::Int(*x)).collect(); Self::List(list) } 4 => { let raw_data = data.read_bytes(length as usize * 8); let list = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap(); + let list = list.iter().map(|x| Self::Long(*x)).collect(); Self::List(list) } 5 => { let raw_data = data.read_bytes(length as usize * 4); let list = raw_reading::slice_as_float_array(raw_data.as_slice()).unwrap(); + let list = list.iter().map(|x| Self::Float(*x)).collect(); Self::List(list) } 6 => { let raw_data = data.read_bytes(length as usize * 8); let list = raw_reading::slice_as_double_array(raw_data.as_slice()).unwrap(); + let list = list.iter().map(|x| Self::Double(*x)).collect(); Self::List(list) } 7 => { @@ -249,6 +255,7 @@ impl<'value> Value<'value> { let length = data.read_int(); let raw_data = data.read_bytes(length as usize); let value = raw_reading::slice_as_byte_array(raw_data.as_slice()); + let value = Self::ByteArray(value); list.push(value); } Self::List(list) @@ -260,6 +267,7 @@ impl<'value> Value<'value> { let value = std::str::from_utf8(data.read_bytes(length as usize).as_slice()) .unwrap() .to_owned(); + let value = Self::String(value.into()); list.push(value); } Self::List(list) @@ -270,6 +278,7 @@ impl<'value> Value<'value> { for _ in 0..length { let inner_list = Self::read_list(data); let value = inner_list.into_list().unwrap(); + let value = Self::List(value); list.push(value); } Self::List(list) @@ -279,6 +288,7 @@ impl<'value> Value<'value> { for _ in 0..length { let inner_compound = Self::read_compound(data); let value = inner_compound.into_compound().unwrap(); + let value = Self::Compound(value); list.push(value); } Self::List(list) @@ -289,6 +299,7 @@ impl<'value> Value<'value> { let length = data.read_int(); let raw_data = data.read_bytes(length as usize * 4); let value = raw_reading::slice_as_int_array(raw_data.as_slice()).unwrap(); + let value = Self::IntArray(value); list.push(value); } Self::List(list) @@ -299,6 +310,7 @@ impl<'value> Value<'value> { let length = data.read_int(); let raw_data = data.read_bytes(length as usize * 8); let value = raw_reading::slice_as_long_array(raw_data.as_slice()).unwrap(); + let value = Self::LongArray(value); list.push(value); } Self::List(list) @@ -409,7 +421,7 @@ impl<'value> Value<'value> { _ => None, } } - pub fn as_list(&self) -> Option<&ListContent> { + pub fn as_list(&self) -> Option<&Vec>> { match self { Self::List(value) => Some(value), _ => None, @@ -440,7 +452,7 @@ impl<'value> Value<'value> { } } #[inline(always)] - pub fn into_list(self) -> Option> { + pub fn into_list(self) -> Option>> { match self { Self::List(value) => Some(value), _ => None,