public void ReaderCorefxlab() { var json = new JsonLab.Utf8JsonReader(_data); while (json.Read()) { ; } }
public JsonObject Parse() { var database = new CustomDb(_pool, DbRow.Size + _utf8Json.Length); var stack = new CustomStack(Utf8JsonReader.MaxDepth * StackRow.Size); var reader = new Utf8JsonReader(_utf8Json); bool inArray = false; int arrayItemsCount = 0; int numberOfRowsForMembers = 0; int numberOfRowsForValues = 0; int parentLocation = -1; while (reader.Read()) { JsonTokenType tokenType = reader.TokenType; if (tokenType == JsonTokenType.StartObject) { if (parentLocation != -1) { database.SetHasChildren(parentLocation); } parentLocation = database.Index; if (inArray) { arrayItemsCount++; } numberOfRowsForValues++; database.Append(JsonValueType.Object, reader.StartLocation); var row = new StackRow(numberOfRowsForMembers + 1); stack.Push(row); numberOfRowsForMembers = 0; } else if (tokenType == JsonTokenType.EndObject) { parentLocation = -1; int rowIndex = reader.NoMoreData ? 0 : database.FindIndexOfFirstUnsetSizeOrLength(JsonValueType.Object); database.SetLength(rowIndex, numberOfRowsForMembers); if (numberOfRowsForMembers != 0) { database.SetNumberOfRows(rowIndex, numberOfRowsForMembers); } StackRow row = stack.Pop(); numberOfRowsForMembers += row.SizeOrLength; } else if (tokenType == JsonTokenType.StartArray) { if (parentLocation != -1) { database.SetHasChildren(parentLocation); } parentLocation = database.Index; if (inArray) { arrayItemsCount++; } numberOfRowsForMembers++; database.Append(JsonValueType.Array, reader.StartLocation); var row = new StackRow(arrayItemsCount, numberOfRowsForValues + 1); stack.Push(row); arrayItemsCount = 0; numberOfRowsForValues = 0; } else if (tokenType == JsonTokenType.EndArray) { parentLocation = -1; int rowIndex = reader.NoMoreData ? 0 : database.FindIndexOfFirstUnsetSizeOrLength(JsonValueType.Array); database.SetLength(rowIndex, arrayItemsCount); if (numberOfRowsForValues != 0) { database.SetNumberOfRows(rowIndex, numberOfRowsForValues); } StackRow row = stack.Pop(); arrayItemsCount = row.SizeOrLength; numberOfRowsForValues += row.NumberOfRows; } else { Debug.Assert(tokenType == JsonTokenType.PropertyName || tokenType == JsonTokenType.Value); numberOfRowsForValues++; numberOfRowsForMembers++; database.Append(reader.ValueType, reader.StartLocation, reader.Value.Length); if (tokenType == JsonTokenType.Value && inArray) { arrayItemsCount++; } } inArray = reader.InArray; } stack.Dispose(); database.Resize(); return(new JsonObject(_utf8Json, database)); }
public static T Deserialize <T>(ReadOnlySpan <byte> utf8) { if (!TypeCache.TryGetValue(typeof(T), out Dictionary <int, PropertyInfoLinkedList> dictionary)) { dictionary = GetTypeMap(typeof(T)); TypeCache.Add(typeof(T), dictionary); } T instance = Create <T> .CreateInstanceOfType(utf8); var reader = new Utf8JsonReader(utf8); while (reader.Read()) { switch (reader.TokenType) { case JsonTokenType.PropertyName: int key = GetHashCode(reader.Value); reader.Read(); // Move to the value token JsonValueType type = reader.ValueType; switch (type) { case JsonValueType.String: PropertyInfo pi = GetPropertyInfo(dictionary, key, reader.Value); pi.SetValue(instance, new Utf8String(reader.Value)); // TODO: Use Ref.Emit instead of Reflection break; case JsonValueType.Object: // TODO: could this be lazy? Could this reuse the root JsonObject (which would store non-allocating JsonDom)? throw new NotImplementedException("object support not implemented yet."); case JsonValueType.True: pi = GetPropertyInfo(dictionary, key, reader.Value); pi.SetValue(instance, true); break; case JsonValueType.False: pi = GetPropertyInfo(dictionary, key, reader.Value); pi.SetValue(instance, false); break; case JsonValueType.Null: pi = GetPropertyInfo(dictionary, key, reader.Value); pi.SetValue(instance, null); break; case JsonValueType.Number: pi = GetPropertyInfo(dictionary, key, reader.Value); // TODO: Add support for other numeric types like double, long, etc. if (!Utf8Parser.TryParse(reader.Value, out int result, out _)) { throw new InvalidCastException(); } pi.SetValue(instance, result); break; case JsonValueType.Array: throw new NotImplementedException("array support not implemented yet."); default: throw new NotSupportedException(); } break; case JsonTokenType.StartObject: break; case JsonTokenType.EndObject: break; case JsonTokenType.StartArray: throw new NotImplementedException("array support not implemented yet."); case JsonTokenType.EndArray: case JsonTokenType.Value: break; default: throw new NotSupportedException(); } } return(instance); }
public static JsonDynamicObject Parse(ReadOnlySpan <byte> utf8, int expectedNumberOfProperties = -1) { Stack <JsonDynamicObject> stack = new Stack <JsonDynamicObject>(); if (expectedNumberOfProperties == -1) { expectedNumberOfProperties = utf8.Length >> 3; } var properties = new Dictionary <JsonProperty, JsonValue>(expectedNumberOfProperties); stack.Push(new JsonDynamicObject(properties)); var reader = new Utf8JsonReader(utf8); while (reader.Read()) { switch (reader.TokenType) { case JsonTokenType.PropertyName: var name = new Utf8String(reader.Value); reader.Read(); // Move to the value token var type = reader.TokenType; var current = stack.Peek(); var property = new JsonProperty(current, name); switch (type) { case JsonTokenType.String: current._properties[property] = new JsonValue(new Utf8String(reader.Value)); break; case JsonTokenType.StartObject: // TODO: could this be lazy? Could this reuse the root JsonObject (which would store non-allocating JsonDom)? var newObj = new JsonDynamicObject(properties); current._properties[property] = new JsonValue(newObj); stack.Push(newObj); break; case JsonTokenType.True: current._properties[property] = new JsonValue(type); break; case JsonTokenType.False: current._properties[property] = new JsonValue(type); break; case JsonTokenType.Null: current._properties[property] = new JsonValue(type); break; case JsonTokenType.Number: current._properties[property] = new JsonValue(new Utf8String(reader.Value), type); break; case JsonTokenType.StartArray: throw new NotImplementedException("array support not implemented yet."); default: throw new NotSupportedException(); } break; case JsonTokenType.StartObject: break; case JsonTokenType.EndObject: if (stack.Count != 1) { stack.Pop(); } break; case JsonTokenType.StartArray: throw new NotImplementedException("array support not implemented yet."); case JsonTokenType.EndArray: case JsonTokenType.String: case JsonTokenType.True: case JsonTokenType.False: case JsonTokenType.Null: case JsonTokenType.Number: break; default: throw new NotSupportedException(); } } return(stack.Peek()); }