/// <summary> Writes a NbtTag object, and all of its child tags, to stream. /// Use this method sparingly with NbtWriter -- constructing NbtTag objects defeats the purpose of this class. /// If you already have lots of NbtTag objects, you might as well use NbtFile to write them all at once. </summary> /// <param name="tag"> Tag to write. Must not be null. </param> /// <exception cref="NbtFormatException"> No more tags can be written -OR- given tag is unacceptable at this time. </exception> /// <exception cref="ArgumentNullException"> <paramref name="tag"/> is null </exception> public void WriteTag([NotNull] NbtTag tag) { if (tag == null) { throw new ArgumentNullException("tag"); } EnforceConstraints(tag.Name, tag.TagType); if (tag.Name != null) { tag.WriteTag(writer); } else { tag.WriteData(writer); } }
private void AddToParent([NotNull] NbtTag thisTag, [NotNull] NbtTag parent) { if (parent is NbtList parentAsList) { parentAsList.Add(thisTag); } else { if (parent is NbtCompound parentAsCompound) { parentAsCompound.Add(thisTag); } else { // cannot happen unless NbtReader is bugged throw new NbtFormatException(InvalidParentTagError); } } }
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); }