public virtual void WriteHeader(NetBinaryWriter writer, NbtFlags flags) { if (flags.HasFlag(NbtFlags.Typed)) { writer.Write((byte)Type); } }
//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; }
public override void WritePayload(NetBinaryWriter writer, NbtFlags flags) { if (Value == null) { writer.Write((ushort)0); } else { writer.Write((ushort)Value.Length); writer.WriteRaw(Value); } }
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); }
//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 abstract void WritePayload(NetBinaryWriter writer, NbtFlags flags);
public override void WritePayload(NetBinaryWriter writer, NbtFlags flags) { writer.Write(Value); }
public override void WritePayload(NetBinaryWriter writer, NbtFlags flags) { base.WritePayload(writer, flags); writer.Write(Items); }
public override void WritePayload(NetBinaryWriter writer, NbtFlags flags) { writer.Write(Items.Length); writer.Write(Items.Span); }