diff --git a/src/libraries/Common/src/System/Text/ValueStringBuilder.cs b/src/libraries/Common/src/System/Text/ValueStringBuilder.cs index 966f1c8cfc5edc..a0844b04664248 100644 --- a/src/libraries/Common/src/System/Text/ValueStringBuilder.cs +++ b/src/libraries/Common/src/System/Text/ValueStringBuilder.cs @@ -251,7 +251,7 @@ public unsafe void Append(char* value, int length) _pos += length; } - public void Append(ReadOnlySpan value) + public void Append(scoped ReadOnlySpan value) { int pos = _pos; if (pos > _chars.Length - value.Length) diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index d54af79674c43c..4d6087c22e4866 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -23,6 +23,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs index cbdaaed8a3e298..bf337233af319a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -74,6 +74,7 @@ internal static partial class JsonConstants public const int MaximumFormatBooleanLength = 5; public const int MaximumFormatInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) + public const int MaximumFormatUInt32Length = 10; // i.e. 4294967295 public const int MaximumFormatUInt64Length = 20; // i.e. 18446744073709551615 public const int MaximumFormatDoubleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. public const int MaximumFormatSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs index 9ae40a15ea66f6..085f49d1cfd56a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs @@ -202,15 +202,26 @@ internal void SetItem(int index, JsonNode? value) List[index] = value; } - internal override void GetPath(List path, JsonNode? child) + internal override void GetPath(ref ValueStringBuilder path, JsonNode? child) { + Parent?.GetPath(ref path, this); + if (child != null) { int index = List.IndexOf(child); - path.Add($"[{index}]"); + Debug.Assert(index >= 0); + + path.Append('['); +#if NETCOREAPP + Span chars = stackalloc char[JsonConstants.MaximumFormatUInt32Length]; + bool formatted = ((uint)index).TryFormat(chars, out int charsWritten); + Debug.Assert(formatted); + path.Append(chars.Slice(0, charsWritten)); +#else + path.Append(index.ToString()); +#endif + path.Append(']'); } - - Parent?.GetPath(path, this); } /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs index 1d38e494da611c..1fd16bb56a8a6c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs @@ -131,19 +131,13 @@ public string GetPath() return "$"; } - var path = new List(); - GetPath(path, null); - - var sb = new StringBuilder("$"); - for (int i = path.Count - 1; i >= 0; i--) - { - sb.Append(path[i]); - } - - return sb.ToString(); + var path = new ValueStringBuilder(stackalloc char[JsonConstants.StackallocCharThreshold]); + path.Append('$'); + GetPath(ref path, null); + return path.ToString(); } - internal abstract void GetPath(List path, JsonNode? child); + internal abstract void GetPath(ref ValueStringBuilder path, JsonNode? child); /// /// Gets the root . diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs index 043b2e246035e0..749f5d8d07d886 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs @@ -196,22 +196,25 @@ internal override bool DeepEqualsCore(JsonNode? node) return null; } - internal override void GetPath(List path, JsonNode? child) + internal override void GetPath(ref ValueStringBuilder path, JsonNode? child) { + Parent?.GetPath(ref path, this); + if (child != null) { string propertyName = Dictionary.FindValue(child)!.Value.Key; if (propertyName.AsSpan().ContainsSpecialCharacters()) { - path.Add($"['{propertyName}']"); + path.Append("['"); + path.Append(propertyName); + path.Append("']"); } else { - path.Add($".{propertyName}"); + path.Append('.'); + path.Append(propertyName); } } - - Parent?.GetPath(path, this); } internal void SetItem(string propertyName, JsonNode? value) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValue.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValue.cs index 0ece122dbea171..5aeb3300590569 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValue.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValue.cs @@ -90,11 +90,11 @@ private protected JsonValue(JsonNodeOptions? options = null) : base(options) { } return new JsonValueCustomized(value, jsonTypeInfo, options); } - internal override void GetPath(List path, JsonNode? child) + internal override void GetPath(ref ValueStringBuilder path, JsonNode? child) { Debug.Assert(child == null); - Parent?.GetPath(path, this); + Parent?.GetPath(ref path, this); } ///