public NbtTag ReadAsTag() { switch (state) { case NbtParseState.Error: throw new InvalidReaderStateException(ErroneousStateError); case NbtParseState.AtStreamEnd: throw new EndOfStreamException(); case NbtParseState.AtStreamBeginning: case NbtParseState.AtCompoundEnd: ReadToFollowing(); break; } // get this tag NbtTag parent; if (TagType == NbtTagType.Compound) { parent = new NbtCompound(TagName); } else if (TagType == NbtTagType.List) { parent = new NbtList(TagName, ListType); } else if (atValue) { NbtTag result = ReadValueAsTag(); ReadToFollowing(); // if we're at a value tag, there are no child tags to read return(result); } else { // end tags cannot be read-as-tags (there is no corresponding NbtTag object) throw new InvalidOperationException(NoValueToReadError); } int startingDepth = Depth; int parentDepth = Depth; do { ReadToFollowing(); // Going up the file tree, or end of document: wrap up while (Depth <= parentDepth && parent.Parent != null) { parent = parent.Parent; parentDepth--; } if (Depth <= startingDepth) { break; } NbtTag thisTag; if (TagType == NbtTagType.Compound) { thisTag = new NbtCompound(TagName); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType == NbtTagType.List) { thisTag = new NbtList(TagName, ListType); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType != NbtTagType.End) { thisTag = ReadValueAsTag(); AddToParent(thisTag, parent); } } while (true); return(parent); }
internal override void SkipTag(NbtBinaryReader readStream) { while (true) { NbtTagType nextTag = readStream.ReadTagType(); NbtTag newTag; switch (nextTag) { case NbtTagType.End: return; case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; default: throw new NbtFormatException("Unsupported tag type found in NBT_Compound: " + nextTag); } readStream.SkipString(); newTag.SkipTag(readStream); } }
internal override bool ReadTag(NbtBinaryReader readStream) { if (readStream.Selector != null && !readStream.Selector(this)) { SkipTag(readStream); return(false); } ListType = readStream.ReadTagType(); int length = readStream.ReadInt32(); if (length < 0) { throw new NbtFormatException("Negative list size given."); } for (int i = 0; i < length; i++) { NbtTag newTag; switch (ListType) { case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; default: // should never happen, since ListType is checked beforehand throw new NbtFormatException("Unsupported tag type found in a list: " + ListType); } newTag.Parent = this; if (newTag.ReadTag(readStream)) { tags.Add(newTag); } } return(true); }
internal override bool ReadTag(NbtBinaryReader readStream) { if (Parent != null && readStream.Selector != null && !readStream.Selector(this)) { SkipTag(readStream); return(false); } while (true) { NbtTagType nextTag = readStream.ReadTagType(); NbtTag newTag; switch (nextTag) { case NbtTagType.End: return(true); case NbtTagType.Byte: newTag = new NbtByte(); break; case NbtTagType.Short: newTag = new NbtShort(); break; case NbtTagType.Int: newTag = new NbtInt(); break; case NbtTagType.Long: newTag = new NbtLong(); break; case NbtTagType.Float: newTag = new NbtFloat(); break; case NbtTagType.Double: newTag = new NbtDouble(); break; case NbtTagType.ByteArray: newTag = new NbtByteArray(); break; case NbtTagType.String: newTag = new NbtString(); break; case NbtTagType.List: newTag = new NbtList(); break; case NbtTagType.Compound: newTag = new NbtCompound(); break; case NbtTagType.IntArray: newTag = new NbtIntArray(); break; default: throw new NbtFormatException("Unsupported tag type found in NBT_Compound: " + nextTag); } newTag.Parent = this; newTag.Name = readStream.ReadString(); if (newTag.ReadTag(readStream)) { // ReSharper disable AssignNullToNotNullAttribute // newTag.Name is never null tags.Add(newTag.Name, newTag); // ReSharper restore AssignNullToNotNullAttribute } } }
/// <summary> Reads the entirety of the current tag, including any descendants, /// and constructs an NbtTag object of the appropriate type. </summary> /// <returns> Constructed NbtTag object; /// <c>null</c> if <c>SkipEndTags</c> is <c>true</c> and trying to read an End tag. </returns> /// <exception cref="NbtFormatException"> If an error occured while parsing data in NBT format. </exception> /// <exception cref="InvalidReaderStateException"> If NbtReader cannot recover from a previous parsing error. </exception> /// <exception cref="EndOfStreamException"> End of stream has been reached (no more tags can be read). </exception> /// <exception cref="InvalidOperationException"> Tag value has already been read, and CacheTagValues is false. </exception> public NbtTag ReadAsTag() { switch (state) { case NbtParseState.Error: throw new InvalidReaderStateException(ErroneousStateError); case NbtParseState.AtStreamEnd: throw new EndOfStreamException(); case NbtParseState.AtStreamBeginning: case NbtParseState.AtCompoundEnd: ReadToFollowing(); break; } NbtTag parent; if (TagType == NbtTagType.Compound) { parent = new NbtCompound(TagName); } else if (TagType == NbtTagType.List) { parent = new NbtList(TagName, ListType); } else if (atValue) { NbtTag result = ReadValueAsTag(); ReadToFollowing(); return(result); } else { throw new InvalidOperationException(NoValueToReadError); } int startingDepth = Depth; int lastDepth = Depth; do { bool end = !ReadToFollowing(); if (end || Depth < lastDepth) { // Going up the file tree, or end of document: wrap up while (Depth <= lastDepth && parent.Parent != null) { parent = parent.Parent; lastDepth--; } } if (end || Depth <= startingDepth) { break; } NbtTag thisTag; if (TagType == NbtTagType.Compound) { thisTag = new NbtCompound(TagName); AddToParent(thisTag, parent); parent = thisTag; } else if (TagType == NbtTagType.List) { thisTag = new NbtList(TagName, ListType); AddToParent(thisTag, parent); parent = thisTag; } else { thisTag = ReadValueAsTag(); AddToParent(thisTag, parent); } lastDepth = Depth; } while(true); return(parent); }