private static JsonDocument CreateForLiteral(JsonTokenType tokenType) { switch (tokenType) { case JsonTokenType.False: s_falseLiteral ??= Create(JsonConstants.FalseValue.ToArray()); return(s_falseLiteral); case JsonTokenType.True: s_trueLiteral ??= Create(JsonConstants.TrueValue.ToArray()); return(s_trueLiteral); default: Debug.Assert(tokenType == JsonTokenType.Null); s_nullLiteral ??= Create(JsonConstants.NullValue.ToArray()); return(s_nullLiteral); } JsonDocument Create(byte[] utf8Json) { MetadataDb database = MetadataDb.CreateLocked(utf8Json.Length); database.Append(tokenType, startLocation: 0, utf8Json.Length); return(new JsonDocument(utf8Json, database)); } }
//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(); }