I found that short, int and long tags will not always be parsed correctly, but an minimal integer type that can represent its value. For example, int 10
will be parsed into byte, while int -2147483648
will be parsed into int. Besides, a list of int will be parsed into int array
.
I don't understand why, but I think tags are not parsed with incorrect types. I added a test to check how tags are parsed, and that's the result:
Type of "byte" is TAG_Byte
Type of "short" is TAG_Byte, expected TAG_Short
Type of "int" is TAG_Byte, expected TAG_Int
Type of "long" is TAG_Byte, expected TAG_Long
Type of "float" is TAG_Float
Type of "double" is TAG_Float, expected TAG_Double
Type of "string" is TAG_String
Type of "byte array" is TAG_ByteArray
Type of "int array" is TAG_ByteArray, expected TAG_IntArray
Type of "long array" is TAG_ByteArray, expected TAG_LongArray
Type of "compound" is TAG_Compound
Type of "list of byte" is TAG_ByteArray, expected TAG_List
Type of "list of int" is TAG_ByteArray, expected TAG_List
Type of "list of long" is TAG_ByteArray, expected TAG_List
I'm sorry to say that 9 types of tags are parsed with incorrect type.
This test can be found at my fork of this repo. The nbt file is at https://github.com/ToKiNoBug/hematite_nbt/blob/fix-type-parsing/tests/types.nbt.
Here is a copy of the test code:
#[test]
fn test_types() {
let file = File::open("tests/types.nbt").unwrap();
let nbt:Result<nbt::Map<String,nbt::Value>,nbt::Error>=nbt::from_gzip_reader(file);
let nbt=nbt.unwrap();
let type_lut=[
("byte","TAG_Byte"),
("short","TAG_Short"),
("int","TAG_Int"),
("long","TAG_Long"),
("float","TAG_Float"),
("double","TAG_Double"),
("string","TAG_String"),
("byte array","TAG_ByteArray"),
("int array","TAG_IntArray"),
("long array","TAG_LongArray"),
("compound","TAG_Compound"),
("list of byte","TAG_List"),
("list of int","TAG_List"),
("list of long","TAG_List"),
];
let mut mismatch_counter=0;
for (key,expected_type) in type_lut {
let tag:&nbt::Value=nbt.get(key).unwrap();
let mut correct=true;
if tag.tag_name()!=expected_type {
mismatch_counter += 1;
correct=false;
}
if correct {
println!("Type of \"{}\" is {}",key,tag.tag_name());
}
else {
eprintln!("Type of \"{}\" is {}, expected {}",key,tag.tag_name(),expected_type);
}
}
if mismatch_counter>0 {
panic!("{} types mismatched",mismatch_counter);
}
}