Пример #1
0
        /// <summary>
        /// Gets whether the type is a data primitive (not collection).
        /// </summary>
        public static bool IsPrimitive(this NbtType tagType)
        {
            if (tagType == NbtType.Undefined)
            {
                return(false);
            }

            return(!tagType.IsCollection());
        }
        //public static NbtDocument ParseValue(ref NbtReader reader)
        //{
        //
        //}
        //
        //public static bool TryParseValue(ref NbtReader reader, out NbtDocument document)
        //{
        //}

        private static void Parse(
            ref NbtReader reader,
            ref MetadataDb database,
            ref ByteStack <ContainerFrame> stack)
        {
            int rowCount = 0;

            MetadataDb.Accessor accessor = new(ref database);

            NbtReadStatus status;

            while ((status = reader.TryRead()) == NbtReadStatus.Done)
            {
                int      location = reader.TagLocation;
                NbtType  type     = reader.TagType;
                NbtFlags flags    = reader.TagFlags;

PeekStack:
                ref ContainerFrame frame = ref stack.TryPeek();
                if (!Unsafe.IsNullRef(ref frame))
                {
                    if (frame.ListEntriesRemaining == 0)
                    {
                        stack.TryPop();

                        int totalRowCount = rowCount - frame.InitialRowCount;
                        accessor.GetRow(frame.ContainerRow).RowCount = totalRowCount;
                        goto PeekStack;
                    }
                    else if (frame.ListEntriesRemaining != -1)
                    {
                        frame.ListEntriesRemaining--;
                    }
                    else
                    {
                        frame.CompoundEntryCounter++;
                    }
                }

                switch (type)
                {
                case NbtType.End:
                {
                    // Documents with a single End tag (no Compound root) are valid.
                    if (stack.TryPop(out ContainerFrame compoundFrame))
                    {
                        int totalRowCount  = rowCount - compoundFrame.InitialRowCount;
                        int compoundLength = compoundFrame.CompoundEntryCounter - 1;     // -1 to exclude End

                        ref DbRow row = ref accessor.GetRow(compoundFrame.ContainerRow);
                        row.RowCount         = totalRowCount;
                        row.CollectionLength = compoundLength;
                    }
                    continue;     // Continue to not increment row count
                }
            public DbRow(int location, int collectionLength, int rowCount, NbtType type, NbtFlags flags)
            {
                Debug.Assert(location >= 0);
                Debug.Assert(type >= NbtType.End && type <= NbtType.LongArray);

                Location         = location;
                CollectionLength = collectionLength;
                RowCount         = rowCount;
                Type             = type;
                Flags            = flags;
            }
Пример #4
0
        public override void ReadStream(Stream s)
        {
            listtagtype = NbtReader.TagType(s);
            Int32 size = NbtReader.TagInt(s);

            for (int idx = 0; idx < size; idx++)
            {
                NbtBase n = createtag(listtagtype);
                n.ReadStream(s);
                tagvalue.Add(n);
            }
        }
Пример #5
0
        /// <summary>
        /// Gets whether the type is a compound or list.
        /// </summary>
        public static bool IsContainer(this NbtType tagType)
        {
            switch (tagType)
            {
            case NbtType.List:
            case NbtType.Compound:
                return(true);

            default:
                return(false);
            }
        }
Пример #6
0
        public static NbtBase createtag(Stream s)
        {
            NbtType T = NbtReader.TagType(s);

            if (T == NbtType.TAG_end)
            {
                return(new NbtEnd());
            }

            NbtBase n = createtag(T);

            n.tagname = NbtReader.TagString(s);
            return(n);
        }
Пример #7
0
        /// <summary>
        /// Gets whether the type is an array or string (not list).
        /// </summary>
        public static bool IsArray(this NbtType tagType)
        {
            switch (tagType)
            {
            case NbtType.String:
            case NbtType.ByteArray:
            case NbtType.IntArray:
            case NbtType.LongArray:
                return(true);

            default:
                return(false);
            }
        }
Пример #8
0
        public NbtType GetBaseType()
        {
            AssertValidInstance();

            NbtType type = Type;

            return(type switch
            {
                NbtType.List => _parent.GetListType(_index),
                NbtType.ByteArray => NbtType.Byte,
                NbtType.IntArray => NbtType.Int,
                NbtType.LongArray => NbtType.Long,
                _ => type,
            });
            public int Append(
                int location, int collectionLength, int rowCount, NbtType type, NbtFlags flags)
            {
                if (ByteLength >= _data.Length - DbRow.Size)
                {
                    Enlarge();
                }

                var row = new DbRow(location, collectionLength, rowCount, type, flags);

                MemoryMarshal.Write(_data.AsSpan(ByteLength), ref row);
                int index = ByteLength;

                ByteLength += DbRow.Size;
                return(index);
            }
Пример #10
0
        public static INbtNode CreateNode(NbtType type)
        {
            switch (type)
            {
            case NbtType.Byte:
                return(new NbtByte());

            case NbtType.Short:
                return(new NbtShort());

            case NbtType.Int:
                return(new NbtInt());

            case NbtType.Long:
                return(new NbtLong());

            case NbtType.Float:
                return(new NbtFloat());

            case NbtType.Double:
                return(new NbtDouble());

            case NbtType.String:
                return(new NbtString());

            case NbtType.Compound:
                return(new NbtCompound());

            case NbtType.List:
                return(new NbtList());

            case NbtType.ByteArray:
                return(new NbtByteArray());

            case NbtType.IntArray:
                return(new NbtIntArray());
            }
            return(null);
        }
Пример #11
0
        //public static NbtDocument ParseValue(ref NbtReader reader)
        //{
        //
        //}
        //
        //public static bool TryParseValue(ref NbtReader reader, out NbtDocument document)
        //{
        //}

        private static void Parse(
            ref NbtReader reader,
            ref MetadataDb database,
            ref ByteStack <ContainerFrame> stack)
        {
            int rowCount = 0;

            while (reader.Read())
            {
                int      location = reader.TagLocation;
                NbtType  type     = reader.TagType;
                NbtFlags flags    = reader.TagFlags;

PeekStack:
                ref ContainerFrame frame = ref stack.TryPeek();
                if (!Unsafe.IsNullRef(ref frame))
                {
                    if (frame.ListEntriesRemaining == 0)
                    {
                        stack.TryPop();

                        int totalRowCount = rowCount - frame.InitialRowCount;
                        database.SetRowCount(frame.ContainerRow, totalRowCount);
                        goto PeekStack;
                    }
                    else if (frame.ListEntriesRemaining != -1)
                    {
                        frame.ListEntriesRemaining--;
                    }
                    else
                    {
                        frame.CompoundEntryCounter++;
                    }
                }

                switch (type)
                {
                case NbtType.End:
                {
                    // Documents with a single End tag (no Compound root) are valid.
                    if (stack.TryPop(out var compoundFrame))
                    {
                        int totalRowCount  = rowCount - compoundFrame.InitialRowCount;
                        int compoundLength = compoundFrame.CompoundEntryCounter - 1;     // -1 to exclude End

                        database.SetRowCount(compoundFrame.ContainerRow, totalRowCount);
                        database.SetLength(compoundFrame.ContainerRow, compoundLength);
                    }
                    continue;     // Continue to not increment row count
                }

                case NbtType.Compound:
                {
                    int containerRow = database.Append(
                        location, collectionLength: 0, rowCount: 1, type, flags);

                    stack.Push(new ContainerFrame(containerRow, rowCount)
                        {
                            ListEntriesRemaining = -1
                        });
                    break;
                }

                case NbtType.List:
                {
                    int listLength   = reader.TagCollectionLength;
                    int containerRow = database.Append(
                        location, listLength, rowCount: 1, type, flags);

                    stack.Push(new ContainerFrame(containerRow, rowCount)
                        {
                            ListEntriesRemaining = listLength
                        });
                    break;
                }

                default:
                    database.Append(location, reader.TagCollectionLength, rowCount: 1, type, flags);
                    break;
                }

                rowCount++;
            }

            database.TrimExcess();
        }
 public void WriteListStart(int length, NbtType type)
 {
 }
Пример #13
0
 public void Write(NbtType n)
 {
     BaseStream.WriteByte((byte)n);
 }
Пример #14
0
        public static NbtBase createtag(NbtType tag)
        {
            NbtBase n = null;


            switch (tag)
            {
            case NbtType.TAG_byte:
                n = new NbtByte();
                break;

            case NbtType.TAG_short:
                n = new NbtShort();
                break;

            case NbtType.TAG_int:
                n = new NbtInt();
                break;

            case NbtType.TAG_long:
                n = new NbtLong();
                break;

            case NbtType.TAG_string:
                n = new NbtString();
                break;

            case NbtType.TAG_float:
                n = new NbtFloat();
                break;

            case NbtType.TAG_double:
                n = new NbtDouble();
                break;

            case NbtType.TAG_array_byte:
                n = new NbtByteArray();
                break;

            case NbtType.TAG_array_int:
                n = new NbtIntArray();
                break;

            case NbtType.TAG_array_long:
                n = new NbtLongArray();
                break;

            case NbtType.TAG_compound:
                n = new NbtCompound();
                break;

            case NbtType.TAG_list:
                n = new NbtList();
                break;

            default:
                throw new Exception("NBT Tag Invalid");
            }


            n.endpos = 0;

            return(n);
        }
Пример #15
0
 public static void TagType(NbtType t, Stream s)
 {
     s.WriteByte((byte)t);
 }
Пример #16
0
 /// <summary>
 /// Gets whether the type is a container or array.
 /// </summary>
 public static bool IsCollection(this NbtType tagType)
 {
     return(tagType.IsContainer() || tagType.IsArray());
 }