示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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
                }
            }
        }
示例#5
0
        /// <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);
        }