// 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 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."); } }
public static NbtTag ReadFromStream(Stream inputStream, Endian endianness) { NbtByteReader reader = new NbtByteReader(inputStream, endianness); TagType firstTagType = reader.ReadTagType(); // first byte should always be the TAG_Compound ID or TAG_List ID switch (firstTagType) { case TagType.Compound: return(ParseNbtCompound(reader)); case TagType.List: return(ParseNbtList(reader)); default: throw new Exception("Unknown first byte."); } }