// get the next long array, prefixed by array length (signed int, 4 bytes) public static NbtLongArray ParseNbtLongArray(NbtByteReader reader, bool parseName = true) { NbtLongArray longArray = new NbtLongArray(parseName ? ParseString(reader) : ""); int arrayLength = reader.ReadInt(); for (int i = 0; i < arrayLength; i++) { longArray.Value.Add(reader.ReadLong()); } return(longArray); }
// get the next list, prefixed by tag type (1 byte) and array length (signed int, 4 bytes). all elements of TAG_List are not prefixed by tag type or name public static NbtList ParseNbtList(NbtByteReader reader, bool parseName = true) { NbtList list = new NbtList(parseName ? ParseString(reader) : "", reader.ReadTagType()); int listLength = reader.ReadInt(); for (int i = 0; i < listLength; i++) { list.Value.Add(ParseNextValueType(reader, list.Type)); // we know the tag type of each element in the list, so we can just pass it in as an argument here } return(list); }
// get the next compound public static NbtCompound ParseNbtCompound(NbtByteReader reader, bool parseName = true) { NbtCompound compound = new NbtCompound(parseName ? ParseString(reader) : ""); int nextType = reader.PeekNext(); // loop until we find TAG_End while (nextType != 0x00) { compound.Value.Add(ParseNextValueType(reader)); nextType = reader.PeekNext(); } reader.ReadByte(); //throw away this byte because we know its TAG_End return(compound); }
// get the next value prefixed by tag type (1 byte) and name length (unsigned short, 2 bytes) public static NbtTag ParseNextValueType(NbtByteReader reader) { TagType nextTagType = reader.ReadTagType(); switch (nextTagType) { case TagType.Byte: return(new NbtByte(ParseString(reader), reader.ReadSByte())); case TagType.Short: return(new NbtShort(ParseString(reader), reader.ReadShort())); case TagType.Int: return(new NbtInt(ParseString(reader), reader.ReadInt())); case TagType.Long: return(new NbtLong(ParseString(reader), reader.ReadLong())); case TagType.Float: return(new NbtFloat(ParseString(reader), reader.ReadFloat())); case TagType.Double: return(new NbtDouble(ParseString(reader), reader.ReadDouble())); case TagType.ByteArray: return(ParseNbtByteArray(reader)); case TagType.String: return(new NbtString(ParseString(reader), ParseString(reader))); case TagType.List: return(ParseNbtList(reader)); case TagType.Compound: return(ParseNbtCompound(reader)); case TagType.IntArray: return(ParseNbtIntArray(reader)); case TagType.LongArray: return(ParseNbtLongArray(reader)); default: throw new Exception("Should never get here."); } }
// strings are prefixed by an unsigned short signifying the length of the string public static string ParseString(NbtByteReader reader) { ushort nameLength = reader.ReadUShort(); return(reader.ReadString(nameLength)); }