<PackageReference Include="System.ClientModel" Version="1.8.0" />

JsonPatch

public struct JsonPatch
A struct representing a JSON patch for partial updates to a JSON structure.
using System.Buffers; using System.Buffers.Text; using System.ClientModel.Internal; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; namespace System.ClientModel.Primitives { [System.Diagnostics.CodeAnalysis.Experimental("SCME0001")] public struct JsonPatch { [EditorBrowsable(EditorBrowsableState.Never)] public delegate bool PropagatorSetter (ReadOnlySpan<byte> jsonPath, EncodedValue value); [EditorBrowsable(EditorBrowsableState.Never)] public delegate bool PropagatorGetter (ReadOnlySpan<byte> jsonPath, out EncodedValue value); public struct EncodedValue { private const byte MaxInt32Utf8Bytes = 11; private const byte MaxInt64Utf8Bytes = 20; private const byte MaxDecimalUtf8Bytes = 64; private const byte MaxGuidUtf8Bytes = 48; private const byte MaxDateTimeUtf8Bytes = 64; private const byte MaxTimeSpanUtf8Bytes = 64; private static readonly ReadOnlyMemory<byte> s_null; private static readonly ReadOnlyMemory<byte> s_true; private static readonly ReadOnlyMemory<byte> s_false; internal static readonly EncodedValue Empty; internal static readonly EncodedValue Removed; internal static readonly EncodedValue Null; internal ValueKind Kind { [System.Runtime.CompilerServices.IsReadOnly] get; set; } internal ReadOnlyMemory<byte> Value { [System.Runtime.CompilerServices.IsReadOnly] get; } private EncodedValue(ValueKind kind) { Value = default(ReadOnlyMemory<byte>); Kind = kind; } internal EncodedValue(ValueKind kind, ReadOnlyMemory<byte> value) { Kind = kind; Value = value; } internal EncodedValue(bool value) { if (value) { Kind = ValueKind.BooleanTrue; Value = s_true; } else { Kind = ValueKind.BooleanFalse; Value = s_false; } } internal unsafe EncodedValue(byte value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(DateTime value, StandardFormat format = default(StandardFormat)) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.DateTime; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); if (Utf8Formatter.TryFormat(value, destination, out int bytesWritten, format)) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(DateTimeOffset value, StandardFormat format = default(StandardFormat)) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.DateTime; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); if (Utf8Formatter.TryFormat(value, destination, out int bytesWritten, format)) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(decimal value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(double value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(float value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(Guid value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Guid; Span<byte> destination = new Span<byte>(stackalloc byte[48], 48); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(int value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(long value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[20], 20); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(sbyte value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(short value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(TimeSpan value, StandardFormat format = default(StandardFormat)) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.TimeSpan; Span<byte> destination = new Span<byte>(stackalloc byte[64], 64); if (Utf8Formatter.TryFormat(value, destination, out int bytesWritten, format)) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(uint value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(ulong value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[20], 20); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } internal unsafe EncodedValue(ushort value) { Value = default(ReadOnlyMemory<byte>); Kind = ValueKind.Number; Span<byte> destination = new Span<byte>(stackalloc byte[11], 11); int bytesWritten = default(int); if (Utf8Formatter.TryFormat(value, destination, out bytesWritten, default(StandardFormat))) Value = destination.Slice(0, bytesWritten).ToArray(); } [System.Runtime.CompilerServices.NullableContext(1)] internal EncodedValue(string value) { Kind = ValueKind.Utf8String; Value = Encoding.UTF8.GetBytes(value); } [System.Runtime.CompilerServices.NullableContext(1)] internal EncodedValue(BinaryData value) { this = new EncodedValue(value.ToMemory()); } internal EncodedValue(ReadOnlySpan<byte> value) { if (value.SequenceEqual(s_null.Span)) { Kind = ValueKind.Null; Value = s_null; } else if (value.SequenceEqual(s_false.Span)) { Kind = ValueKind.BooleanFalse; Value = s_false; } else if (value.SequenceEqual(s_true.Span)) { Kind = ValueKind.BooleanTrue; Value = s_true; } else { Kind = ValueKind.Json; Value = value.ToArray(); } } [System.Runtime.CompilerServices.NullableContext(1)] internal EncodedValue(byte[] value) { this = new EncodedValue((ReadOnlyMemory<byte>)value); } internal EncodedValue(ReadOnlyMemory<byte> value) { ReadOnlySpan<byte> span = value.Span; if (span.SequenceEqual(s_null.Span)) { Kind = ValueKind.Null; Value = s_null; } else if (span.SequenceEqual(s_false.Span)) { Kind = ValueKind.BooleanFalse; Value = s_false; } else if (span.SequenceEqual(s_true.Span)) { Kind = ValueKind.BooleanTrue; Value = s_true; } else { Kind = ValueKind.Json; Value = value; } } internal bool TryDecodeValue(out bool value) { if (Utf8Parser.TryParse(Value.Span, out bool value2, out int _, '')) { value = value2; return true; } value = false; return false; } internal bool TryDecodeValue(out byte value) { if (Utf8Parser.TryParse(Value.Span, out byte value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out DateTime value, StandardFormat format = default(StandardFormat)) { if (Utf8Parser.TryParse(Value.Span, out DateTime value2, out int _, format.Symbol)) { value = value2; return true; } value = default(DateTime); return false; } internal bool TryDecodeValue(out DateTimeOffset value, StandardFormat format = default(StandardFormat)) { if (Utf8Parser.TryParse(Value.Span, out DateTimeOffset value2, out int _, format.Symbol)) { value = value2; return true; } value = default(DateTimeOffset); return false; } internal bool TryDecodeValue(out decimal value) { if (Utf8Parser.TryParse(Value.Span, out decimal value2, out int _, '')) { value = value2; return true; } value = default(decimal); return false; } internal bool TryDecodeValue(out double value) { if (Utf8Parser.TryParse(Value.Span, out double value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out float value) { if (Utf8Parser.TryParse(Value.Span, out float value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out Guid value) { if (Utf8Parser.TryParse(Value.Span, out Guid value2, out int _, '')) { value = value2; return true; } value = default(Guid); return false; } internal bool TryDecodeValue(out int value) { if (Utf8Parser.TryParse(Value.Span, out int value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out long value) { if (Utf8Parser.TryParse(Value.Span, out long value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out sbyte value) { if (Utf8Parser.TryParse(Value.Span, out sbyte value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out short value) { if (Utf8Parser.TryParse(Value.Span, out short value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out TimeSpan value, StandardFormat format = default(StandardFormat)) { if (Utf8Parser.TryParse(Value.Span, out TimeSpan value2, out int _, format.Symbol)) { value = value2; return true; } value = default(TimeSpan); return false; } internal bool TryDecodeValue(out uint value) { if (Utf8Parser.TryParse(Value.Span, out uint value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out ulong value) { if (Utf8Parser.TryParse(Value.Span, out ulong value2, out int _, '')) { value = value2; return true; } value = 0; return false; } internal bool TryDecodeValue(out ushort value) { if (Utf8Parser.TryParse(Value.Span, out ushort value2, out int _, '')) { value = value2; return true; } value = 0; return false; } [System.Runtime.CompilerServices.NullableContext(2)] internal bool TryDecodeValue(out string value) { ReadOnlySpan<byte> other = Value.Span; if (s_null.Span.SequenceEqual(other)) { value = null; return true; } if (other.Length >= 2 && other[0] == 34 && other[other.Length - 1] == 34) other = other.Slice(1, other.Length - 2); value = Encoding.UTF8.GetString(other.ToArray()); return true; } internal bool TryDecodeNullableValue<T>(out T? value, out bool supportedType) where T : struct { value = null; supportedType = true; ReadOnlyMemory<byte> value2 = Value; if (value2.Span.SequenceEqual(s_null.Span)) return true; Type typeFromHandle = typeof(T); int bytesConsumed; if (typeFromHandle == typeof(bool)) { value2 = Value; bool value3; bool flag = Utf8Parser.TryParse(value2.Span, out value3, out bytesConsumed, ''); value = (flag ? ((T?)(object)value3) : null); return flag; } if (typeFromHandle == typeof(byte)) { value2 = Value; byte value4; bool flag = Utf8Parser.TryParse(value2.Span, out value4, out bytesConsumed, ''); value = (flag ? ((T?)(object)value4) : null); return flag; } if (typeFromHandle == typeof(sbyte)) { value2 = Value; sbyte value5; bool flag = Utf8Parser.TryParse(value2.Span, out value5, out bytesConsumed, ''); value = (flag ? ((T?)(object)value5) : null); return flag; } if (typeFromHandle == typeof(short)) { value2 = Value; short value6; bool flag = Utf8Parser.TryParse(value2.Span, out value6, out bytesConsumed, ''); value = (flag ? ((T?)(object)value6) : null); return flag; } if (typeFromHandle == typeof(ushort)) { value2 = Value; ushort value7; bool flag = Utf8Parser.TryParse(value2.Span, out value7, out bytesConsumed, ''); value = (flag ? ((T?)(object)value7) : null); return flag; } if (typeFromHandle == typeof(int)) { value2 = Value; int value8; bool flag = Utf8Parser.TryParse(value2.Span, out value8, out bytesConsumed, ''); value = (flag ? ((T?)(object)value8) : null); return flag; } if (typeFromHandle == typeof(uint)) { value2 = Value; uint value9; bool flag = Utf8Parser.TryParse(value2.Span, out value9, out bytesConsumed, ''); value = (flag ? ((T?)(object)value9) : null); return flag; } if (typeFromHandle == typeof(long)) { value2 = Value; long value10; bool flag = Utf8Parser.TryParse(value2.Span, out value10, out bytesConsumed, ''); value = (flag ? ((T?)(object)value10) : null); return flag; } if (typeFromHandle == typeof(ulong)) { value2 = Value; ulong value11; bool flag = Utf8Parser.TryParse(value2.Span, out value11, out bytesConsumed, ''); value = (flag ? ((T?)(object)value11) : null); return flag; } if (typeFromHandle == typeof(float)) { value2 = Value; float value12; bool flag = Utf8Parser.TryParse(value2.Span, out value12, out bytesConsumed, ''); value = (flag ? ((T?)(object)value12) : null); return flag; } if (typeFromHandle == typeof(double)) { value2 = Value; double value13; bool flag = Utf8Parser.TryParse(value2.Span, out value13, out bytesConsumed, ''); value = (flag ? ((T?)(object)value13) : null); return flag; } if (typeFromHandle == typeof(decimal)) { value2 = Value; decimal value14; bool flag = Utf8Parser.TryParse(value2.Span, out value14, out bytesConsumed, ''); value = (flag ? ((T?)(object)value14) : null); return flag; } if (typeFromHandle == typeof(DateTime)) { value2 = Value; DateTime value15; bool flag = Utf8Parser.TryParse(value2.Span, out value15, out bytesConsumed, ''); value = (flag ? ((T?)(object)value15) : null); return flag; } if (typeFromHandle == typeof(DateTimeOffset)) { value2 = Value; DateTimeOffset value16; bool flag = Utf8Parser.TryParse(value2.Span, out value16, out bytesConsumed, ''); value = (flag ? ((T?)(object)value16) : null); return flag; } if (typeFromHandle == typeof(Guid)) { value2 = Value; Guid value17; bool flag = Utf8Parser.TryParse(value2.Span, out value17, out bytesConsumed, ''); value = (flag ? ((T?)(object)value17) : null); return flag; } if (typeFromHandle == typeof(TimeSpan)) { value2 = Value; TimeSpan value18; bool flag = Utf8Parser.TryParse(value2.Span, out value18, out bytesConsumed, ''); value = (flag ? ((T?)(object)value18) : null); return flag; } supportedType = false; return false; } unsafe static EncodedValue() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.97CCCB1B1197F11C6EDBB0D93975220592EF8FAF618C8770A131E4F7DFE567CC, 4); s_null = readOnlySpan.ToArray(); readOnlySpan = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.DEBC2F07DB78D52D2DEF07B7BC620D7042367501D9439A62BA09B559A98E0957, 4); s_true = readOnlySpan.ToArray(); readOnlySpan = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.98151954F217A510702D236DE168CC35D0AB2F99C4479CC9B07EEEDE7EF73A66, 5); s_false = readOnlySpan.ToArray(); Empty = new EncodedValue(ValueKind.None, Array.Empty<byte>()); Removed = new EncodedValue(ValueKind.Removed); Null = new EncodedValue(ValueKind.Null, s_null); } } private class SpanDictionary { [System.Runtime.CompilerServices.Nullable(1)] private readonly Dictionary<byte[], EncodedValue> _inner; public int MaxKeyLength { get; set; } public SpanDictionary() { _inner = new Dictionary<byte[], EncodedValue>(JsonPathComparer.Default); } public unsafe bool TryGetValue(ReadOnlySpan<byte> key, out EncodedValue value) { int length = key.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); ReadOnlySpan<byte> normalizedKey = GetNormalizedKey(key, buffer); return _inner.TryGetValue(normalizedKey.ToArray(), out value); } public unsafe void Set(ReadOnlySpan<byte> key, EncodedValue value) { int length = key.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); ReadOnlySpan<byte> normalizedKey = GetNormalizedKey(key, buffer); MaxKeyLength = Math.Max(MaxKeyLength, normalizedKey.Length); _inner[normalizedKey.ToArray()] = value; } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] public Dictionary<byte[], EncodedValue>.Enumerator GetEnumerator() { return _inner.GetEnumerator(); } public unsafe void TryUpdateValueKind(ReadOnlySpan<byte> key, ValueKind kind) { int length = key.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); byte[] key2 = GetNormalizedKey(key, buffer).ToArray(); if (_inner.TryGetValue(key2, out EncodedValue value)) { value.Kind = kind; _inner[key2] = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReadOnlySpan<byte> GetNormalizedKey(ReadOnlySpan<byte> key, Span<byte> buffer) { JsonPathComparer.Default.Normalize(key, buffer, out int bytesWritten); return buffer.Slice(0, bytesWritten); } } private class SpanHashSet { [System.Runtime.CompilerServices.Nullable(1)] private HashSet<byte[]> _inner; public SpanHashSet() { _inner = new HashSet<byte[]>(JsonPathComparer.Default); } public unsafe bool Contains(ReadOnlySpan<byte> item) { int length = item.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); JsonPathComparer.Default.Normalize(item, buffer, out int bytesWritten); buffer = buffer.Slice(0, bytesWritten); return _inner.Contains(buffer.ToArray()); } public unsafe bool Add(ReadOnlySpan<byte> item) { int length = item.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); JsonPathComparer.Default.Normalize(item, buffer, out int bytesWritten); buffer = buffer.Slice(0, bytesWritten); return _inner.Add(buffer.ToArray()); } } [Flags] internal enum ValueKind : short { None = 0, Json = 1, Number = 2, Utf8String = 4, Removed = 8, Null = 16, BooleanTrue = 32, BooleanFalse = 64, ArrayItemAppend = 128, ModelOwned = 256, DateTime = 512, Guid = 1024, TimeSpan = 2048 } [System.Runtime.CompilerServices.Nullable(2)] private SpanDictionary _properties; private readonly EncodedValue _rawJson; [System.Runtime.CompilerServices.Nullable(2)] private PropagatorSetter _propagatorSetter; [System.Runtime.CompilerServices.Nullable(2)] private PropagatorGetter _propagatorGetter; public JsonPatch(ReadOnlyMemory<byte> utf8Json) { _properties = null; _propagatorSetter = null; _propagatorGetter = null; _rawJson = new EncodedValue(ValueKind.Json, utf8Json); } [System.Runtime.CompilerServices.NullableContext(1)] [EditorBrowsable(EditorBrowsableState.Never)] public void SetPropagators(PropagatorSetter setter, PropagatorGetter getter) { _propagatorSetter = setter; _propagatorGetter = getter; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(ReadOnlySpan<byte> jsonPath) { if (_properties == null) return false; if (_properties.TryGetValue(jsonPath, out EncodedValue value)) return !value.Kind.HasFlag(ValueKind.ArrayItemAppend); return false; } public void Set(ReadOnlySpan<byte> jsonPath, bool value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, byte value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, DateTime value, StandardFormat format = default(StandardFormat)) { SetInternal(jsonPath, new EncodedValue(value, format)); } public void Set(ReadOnlySpan<byte> jsonPath, DateTimeOffset value, StandardFormat format = default(StandardFormat)) { SetInternal(jsonPath, new EncodedValue(value, format)); } public void Set(ReadOnlySpan<byte> jsonPath, decimal value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, double value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, float value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, Guid value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, int value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, long value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, sbyte value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, short value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, TimeSpan value, StandardFormat format = default(StandardFormat)) { SetInternal(jsonPath, new EncodedValue(value, format)); } public void Set(ReadOnlySpan<byte> jsonPath, uint value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, ulong value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, ushort value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, [System.Runtime.CompilerServices.Nullable(1)] string value) { SetInternal(jsonPath, new EncodedValue(value)); } public void Set(ReadOnlySpan<byte> jsonPath, [System.Runtime.CompilerServices.Nullable(1)] byte[] utf8Json) { SetInternal(jsonPath, new EncodedValue(utf8Json)); } public void Set(ReadOnlySpan<byte> jsonPath, [System.Runtime.CompilerServices.Nullable(1)] BinaryData utf8Json) { SetInternal(jsonPath, new EncodedValue(utf8Json)); } public void Set(ReadOnlySpan<byte> jsonPath, ReadOnlySpan<byte> utf8Json) { SetInternal(jsonPath, new EncodedValue(utf8Json)); } [EditorBrowsable(EditorBrowsableState.Never)] public void Set(ReadOnlySpan<byte> jsonPath, EncodedValue value) { SetInternal(jsonPath, value); } public void SetNull(ReadOnlySpan<byte> jsonPath) { SetInternal(jsonPath, EncodedValue.Null); } public bool GetBoolean(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out bool value2)) return value2; return ThrowFormatException<bool>(jsonPath); } public byte GetByte(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out byte value2)) return value2; return ThrowFormatException<byte>(jsonPath); } public DateTime GetDateTime(ReadOnlySpan<byte> jsonPath, StandardFormat format = default(StandardFormat)) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out DateTime value2, format)) return value2; return ThrowFormatException<DateTime>(jsonPath); } public DateTimeOffset GetDateTimeOffset(ReadOnlySpan<byte> jsonPath, StandardFormat format = default(StandardFormat)) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out DateTimeOffset value2, format)) return value2; return ThrowFormatException<DateTimeOffset>(jsonPath); } public decimal GetDecimal(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out decimal value2)) return value2; return ThrowFormatException<decimal>(jsonPath); } public double GetDouble(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out double value2)) return value2; return ThrowFormatException<double>(jsonPath); } public float GetFloat(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out float value2)) return value2; return ThrowFormatException<float>(jsonPath); } public Guid GetGuid(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out Guid value2)) return value2; return ThrowFormatException<Guid>(jsonPath); } public int GetInt32(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out int value2)) return value2; return ThrowFormatException<int>(jsonPath); } public long GetInt64(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out long value2)) return value2; return ThrowFormatException<long>(jsonPath); } public sbyte GetInt8(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out sbyte value2)) return value2; return ThrowFormatException<sbyte>(jsonPath); } public short GetInt16(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out short value2)) return value2; return ThrowFormatException<short>(jsonPath); } public TimeSpan GetTimeSpan(ReadOnlySpan<byte> jsonPath, StandardFormat format = default(StandardFormat)) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out TimeSpan value2, format)) return value2; return ThrowFormatException<TimeSpan>(jsonPath); } public uint GetUInt32(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out uint value2)) return value2; return ThrowFormatException<uint>(jsonPath); } public ulong GetUInt64(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out ulong value2)) return value2; return ThrowFormatException<ulong>(jsonPath); } public ushort GetUInt16(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeValue(out ushort value2)) return value2; return ThrowFormatException<ushort>(jsonPath); } [return: System.Runtime.CompilerServices.Nullable(2)] public string GetString(ReadOnlySpan<byte> jsonPath) { EncodedValue value; if (TryGetEncodedValueInternal(jsonPath, out value) && value.Kind != ValueKind.Removed && value.TryDecodeValue(out string value2)) return value2; ThrowKeyNotFoundException(jsonPath); return null; } [return: System.Runtime.CompilerServices.Nullable(1)] public BinaryData GetJson(ReadOnlySpan<byte> jsonPath) { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); return new BinaryData(value.Value); } public T? GetNullableValue<T>(ReadOnlySpan<byte> jsonPath) where T : struct { if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value) || value.Kind == ValueKind.Removed) ThrowKeyNotFoundException(jsonPath); if (value.TryDecodeNullableValue(out T? value2, out bool supportedType)) return value2; if (supportedType) return ThrowFormatException<T?>(jsonPath); return NullableTypeNotSupported<T>(); } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out bool value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out bool value3)) { value = value3; return true; } value = false; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out byte value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out byte value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out DateTime value, StandardFormat format = default(StandardFormat)) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out DateTime value3, format.Symbol)) { value = value3; return true; } value = default(DateTime); return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out DateTimeOffset value, StandardFormat format = default(StandardFormat)) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out DateTimeOffset value3, format.Symbol)) { value = value3; return true; } value = default(DateTimeOffset); return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out decimal value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out decimal value3)) { value = value3; return true; } value = default(decimal); return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out double value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out double value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out float value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out float value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out Guid value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out Guid value3)) { value = value3; return true; } value = default(Guid); return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out int value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out int value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out long value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out long value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out sbyte value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out sbyte value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out short value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out short value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out TimeSpan value, StandardFormat format = default(StandardFormat)) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out TimeSpan value3, format.Symbol)) { value = value3; return true; } value = default(TimeSpan); return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out uint value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out uint value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out ulong value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out ulong value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, out ushort value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2) && value2.TryDecodeValue(out ushort value3)) { value = value3; return true; } value = 0; return false; } public bool TryGetValue(ReadOnlySpan<byte> jsonPath, [System.Runtime.CompilerServices.Nullable(2)] out string value) { if (TryGetEncodedValueInternal(jsonPath, out EncodedValue value2)) { value2.TryDecodeValue(out string value3); value = value3; return true; } value = null; return false; } public bool TryGetNullableValue<T>(ReadOnlySpan<byte> jsonPath, out T? value) where T : struct { value = null; if (!TryGetEncodedValueInternal(jsonPath, out EncodedValue value2)) return false; if (value2.Kind.HasFlag(ValueKind.Null)) return true; if (value2.TryDecodeNullableValue(out T? value3, out bool _)) { value = value3; return true; } return false; } [EditorBrowsable(EditorBrowsableState.Never)] public bool TryGetEncodedValue(ReadOnlySpan<byte> jsonPath, out EncodedValue value) { return TryGetEncodedValueInternal(jsonPath, out value); } public bool TryGetJson(ReadOnlySpan<byte> jsonPath, out ReadOnlyMemory<byte> value) { EncodedValue value2; bool result = TryGetEncodedValueInternal(jsonPath, out value2); value = value2.Value; return result; } public void Append(ReadOnlySpan<byte> arrayPath, bool value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, byte value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, DateTime value, StandardFormat format = default(StandardFormat)) { EncodedValue encodedValue = new EncodedValue(value, format); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, DateTimeOffset value, StandardFormat format = default(StandardFormat)) { EncodedValue encodedValue = new EncodedValue(value, format); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, decimal value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, double value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, float value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, Guid value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, int value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, long value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, sbyte value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, short value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, TimeSpan value, StandardFormat format = default(StandardFormat)) { EncodedValue encodedValue = new EncodedValue(value, default(StandardFormat)); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, uint value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, ulong value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, ushort value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, [System.Runtime.CompilerServices.Nullable(1)] string value) { EncodedValue encodedValue = new EncodedValue(value); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, [System.Runtime.CompilerServices.Nullable(1)] byte[] utf8Json) { EncodedValue encodedValue = new EncodedValue(utf8Json); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, [System.Runtime.CompilerServices.Nullable(1)] BinaryData utf8Json) { EncodedValue encodedValue = new EncodedValue(utf8Json); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void Append(ReadOnlySpan<byte> arrayPath, ReadOnlySpan<byte> utf8Json) { EncodedValue encodedValue = new EncodedValue(utf8Json); encodedValue.Kind |= ValueKind.ArrayItemAppend; SetInternal(arrayPath, encodedValue); } public void AppendNull(ReadOnlySpan<byte> arrayPath) { SetInternal(arrayPath, new EncodedValue(ValueKind.ArrayItemAppend, EncodedValue.Null.Value)); } public void Remove(ReadOnlySpan<byte> jsonPath) { SetInternal(jsonPath, EncodedValue.Removed); } public bool IsRemoved(ReadOnlySpan<byte> jsonPath) { if (_properties == null) return false; if (_properties.TryGetValue(jsonPath, out EncodedValue value)) return value.Kind == ValueKind.Removed; return false; } [EditorBrowsable(EditorBrowsableState.Never)] public unsafe bool Contains(ReadOnlySpan<byte> prefix, ReadOnlySpan<byte> property) { if (_properties == null) return false; int length = prefix.Length; Span<byte> span = new Span<byte>(stackalloc byte[(int)(uint)length], length); JsonPathComparer.Default.Normalize(prefix, span, out int bytesWritten); span = span.Slice(0, bytesWritten); foreach (KeyValuePair<byte[], EncodedValue> property2 in _properties) { ReadOnlySpan<byte> span2 = property2.Key; if (span2.StartsWith(span) && property.SequenceEqual(span2.Slice(span.Length).GetPropertyNameFromSlice())) return true; } return false; } [System.Runtime.CompilerServices.NullableContext(1)] public override string ToString() { return ToString("JP"); } [System.Runtime.CompilerServices.NullableContext(1)] public string ToString(string format) { ThrowIfNull(format, "format"); if (format == "J") return SerializeToJson(); if (format == "JP") return SerializeToJsonPatch(); return ThrowFormatNotSupportedException(format); } private unsafe bool TryGetEncodedValueInternal(ReadOnlySpan<byte> jsonPath, out EncodedValue value) { value = EncodedValue.Empty; if (jsonPath.IsRoot()) return TryGetExactMatch(jsonPath, out value); if (_propagatorGetter != null && _propagatorGetter(jsonPath, out value)) return true; ReadOnlySpan<byte> parentPath; EncodedValue encodedValue; if (_properties == null) { if (TryGetParentMatch(jsonPath, true, out parentPath, out encodedValue)) { value = new EncodedValue(encodedValue.Kind, encodedValue.Value.GetJson(jsonPath)); return true; } return false; } if (TryGetExactMatch(jsonPath, out value)) return true; int length = jsonPath.Length; Span<byte> subPath = new Span<byte>(stackalloc byte[(int)(uint)length], length); ReadOnlySpan<byte> parent = jsonPath.GetParent(); EncodedValue value2; if (jsonPath.IsArrayIndex() && _properties.TryGetValue(parent, out value2) && !value2.Kind.HasFlag(ValueKind.ArrayItemAppend)) { GetSubPath(parent, jsonPath, ref subPath); value = new EncodedValue(value2.Kind, value2.Value.GetJson(subPath)); return true; } if (TryGetParentMatch(jsonPath, true, out ReadOnlySpan<byte> parentPath2, out encodedValue)) { length = jsonPath.Length; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)length], length); JsonPathComparer.Default.Normalize(jsonPath, buffer, out int bytesWritten); ReadOnlySpan<byte> readOnlySpan = buffer.Slice(0, bytesWritten); JsonPathReader reader = new JsonPathReader(readOnlySpan); reader.Advance(parentPath2); ReadOnlySpan<byte> nextArray = reader.GetNextArray(); if (nextArray.IsEmpty) { GetSubPath(parentPath2, readOnlySpan, ref subPath); value = new EncodedValue(encodedValue.Kind, encodedValue.Value.GetJson(subPath)); return true; } length = readOnlySpan.Length; Span<byte> span = new Span<byte>(stackalloc byte[(int)(uint)length], length); readOnlySpan.CopyTo(span); int length2 = readOnlySpan.Length; while (!nextArray.IsEmpty) { if (TryGetArrayItemFromRoot(nextArray, reader, out int indexRequested, out int length3, out ReadOnlyMemory<byte> arrayItem)) { GetSubPath(nextArray, jsonPath, ref subPath); value = new EncodedValue(ValueKind.Json, GetCombinedArray(jsonPath, arrayItem.GetJson(subPath), EncodedValue.Empty)); return true; } int newIndex = indexRequested - Math.Max(length3, GetMaxSibling(nextArray) + 1); JsonPathToken current = reader.Current; parentPath = current.ValueSpan; int length4 = parentPath.Length; current = reader.Current; AdjustJsonPath(newIndex, length4, current.TokenStartIndex, span, ref length2); nextArray = reader.GetNextArray(); } GetSubPath(parentPath2, span.Slice(0, length2), ref subPath); value = new EncodedValue(encodedValue.Kind, encodedValue.Value.GetJson(subPath)); return true; } return false; } [System.Runtime.CompilerServices.IsReadOnly] private int GetMaxSibling(ReadOnlySpan<byte> normalizedArrayPath) { int num = -1; ReadOnlySpan<byte> parent = normalizedArrayPath.GetParent(); foreach (KeyValuePair<byte[], EncodedValue> property in _properties) { EncodedValue value = property.Value; if (value.Kind != ValueKind.Removed) { value = property.Value; if (!value.Kind.HasFlag(ValueKind.ModelOwned)) { ReadOnlySpan<byte> readOnlySpan = property.Key; if (readOnlySpan.StartsWith(parent)) { readOnlySpan = readOnlySpan.Slice(parent.Length); if (readOnlySpan.IsArrayWrapped() && Utf8Parser.TryParse(readOnlySpan.Slice(1, readOnlySpan.Length - 2), out int value2, out int _, '')) num = Math.Max(num, value2); } } } } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool TryGetExactMatch(ReadOnlySpan<byte> jsonPath, out EncodedValue value) { if (_properties != null && _properties.TryGetValue(jsonPath, out EncodedValue value2)) { if (value2.Kind.HasFlag(ValueKind.ArrayItemAppend)) value = new EncodedValue(value2.Kind, GetCombinedArray(jsonPath, value2)); else value = value2; return true; } value = EncodedValue.Empty; return false; } private static void AdjustJsonPath(int newIndex, int indexLength, int indexStart, Span<byte> buffer, ref int length) { int bytesWritten = default(int); Utf8Formatter.TryFormat(newIndex, buffer.Slice(indexStart), out bytesWritten, default(StandardFormat)); int num = indexLength - bytesWritten; if (num > 0) { buffer.Slice(indexStart + indexLength).CopyTo(buffer.Slice(indexStart + bytesWritten)); length -= num; } } private bool TryGetArrayItemFromRoot(ReadOnlySpan<byte> jsonPath, JsonPathReader reader, out int indexRequested, out int length, out ReadOnlyMemory<byte> arrayItem) { length = 0; indexRequested = 0; arrayItem = ReadOnlyMemory<byte>.Empty; if (!Utf8Parser.TryParse(jsonPath.GetIndexSpan(), out indexRequested, out int _, '')) return false; if (!TryGetRootJson(out ReadOnlyMemory<byte> value)) return false; Utf8JsonReader jsonReader = new Utf8JsonReader(value.Span, default(JsonReaderOptions)); if (!ref jsonReader.Advance(jsonPath.GetParent())) return false; if (jsonReader.TokenType == JsonTokenType.PropertyName) jsonReader.Read(); if (jsonReader.TokenType != JsonTokenType.StartArray) return false; if (!ref jsonReader.SkipToIndex(indexRequested, out length)) return false; long tokenStartIndex = jsonReader.TokenStartIndex; jsonReader.Skip(); long bytesConsumed2 = jsonReader.BytesConsumed; arrayItem = value.Slice((int)tokenStartIndex, (int)(bytesConsumed2 - tokenStartIndex)); return true; } private ReadOnlyMemory<byte> GetCombinedArray(ReadOnlySpan<byte> jsonPath, EncodedValue encodedValue) { TryGetRootJson(out ReadOnlyMemory<byte> value); value.TryGetJson(jsonPath, out ReadOnlyMemory<byte> target); return GetCombinedArray(jsonPath, target, encodedValue); } private unsafe ReadOnlyMemory<byte> GetCombinedArray(ReadOnlySpan<byte> jsonPath, ReadOnlyMemory<byte> existingArray, EncodedValue encodedValue) { int length = jsonPath.Length; Span<byte> span = new Span<byte>(stackalloc byte[(int)(uint)length], length); byte[] array = new byte[_properties.MaxKeyLength]; JsonPathComparer.Default.Normalize(jsonPath, span, out int bytesWritten); span = span.Slice(0, bytesWritten); foreach (KeyValuePair<byte[], EncodedValue> property in _properties) { EncodedValue value = property.Value; if (value.Kind != ValueKind.Removed) { value = property.Value; if (!value.Kind.HasFlag(ValueKind.ModelOwned)) { ReadOnlySpan<byte> span2 = property.Key; if (span2.StartsWith(span)) { ReadOnlyMemory<byte> value2; if (existingArray.IsEmpty) { ReadOnlyMemory<byte> readOnlyMemory; if (!span2.SequenceEqual(span)) { byte b = 91; value = property.Value; value2 = value.Value; ReadOnlySpan<byte> span3 = value2.Span; length = 0; byte[] array2 = new byte[2 + span3.Length]; array2[length] = b; length++; span3.CopyTo(new Span<byte>(array2).Slice(length, span3.Length)); length += span3.Length; array2[length] = 93; readOnlyMemory = new ReadOnlyMemory<byte>(array2); } else readOnlyMemory = encodedValue.Value; existingArray = readOnlyMemory; } else { GetSubPath(span, property.Key, array, out int bytesWritten2); ReadOnlySpan<byte> readOnlySpan = array.AsSpan(0, bytesWritten2); if (readOnlySpan.IsArrayIndex()) { ReadOnlyMemory<byte> json = existingArray; ReadOnlySpan<byte> arrayPath = readOnlySpan; value = property.Value; existingArray = json.InsertAt(arrayPath, value.Value); } else { ReadOnlyMemory<byte> json2 = existingArray; ReadOnlySpan<byte> arrayPath2 = readOnlySpan; value = property.Value; value2 = value.Value; value = property.Value; existingArray = json2.Append(arrayPath2, value2.Slice(1, value.Value.Length - 2)); } } } } } } if (!existingArray.IsEmpty) return existingArray; return encodedValue.Value; } private bool TryGetRootJson(out ReadOnlyMemory<byte> value) { value = ReadOnlyMemory<byte>.Empty; if (_rawJson.Value.IsEmpty) return false; value = _rawJson.Value; return !value.IsEmpty; } private unsafe bool TryGetParentMatch(ReadOnlySpan<byte> jsonPath, bool includeRoot, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out ReadOnlySpan<byte> parentPath, out EncodedValue encodedValue) { parentPath = default(ReadOnlySpan<byte>); encodedValue = EncodedValue.Empty; ReadOnlyMemory<byte> value; if (_properties == null) { if (includeRoot) { value = _rawJson.Value; if (!value.IsEmpty) { encodedValue = _rawJson; parentPath = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1); return true; } } return false; } parentPath = jsonPath.GetParent(); while (parentPath.Length > 0) { if (_properties.TryGetValue(parentPath, out encodedValue)) return true; parentPath = parentPath.GetParent(); if (parentPath.IsRoot()) break; } if (parentPath.IsRoot() & includeRoot) { if (_properties.TryGetValue(parentPath, out encodedValue)) return true; value = _rawJson.Value; if (!value.IsEmpty) { encodedValue = _rawJson; return true; } } return false; } private unsafe void SetInternal(ReadOnlySpan<byte> jsonPath, EncodedValue encodedValue) { if (_propagatorSetter == null || !_propagatorSetter(jsonPath, encodedValue)) { EncodedValue value = EncodedValue.Empty; if (_properties != null && _properties.TryGetValue(jsonPath, out value)) _properties.Set(jsonPath, new EncodedValue(encodedValue.Kind, ModifyJson(value, new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1), encodedValue))); else { ReadOnlySpan<byte> readOnlySpan = jsonPath; byte[] array = new byte[jsonPath.Length]; int bytesConsumed = readOnlySpan.Length; Span<byte> subPath = new Span<byte>(stackalloc byte[(int)(uint)bytesConsumed], bytesConsumed); ReadOnlyMemory<byte> value2 = _rawJson.Value; if (!value2.IsEmpty && encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { value2 = _rawJson.Value; Utf8JsonReader jsonReader = new Utf8JsonReader(value2.Span, default(JsonReaderOptions)); JsonPathReader pathReader = new JsonPathReader(jsonPath); if (ref jsonReader.Advance(ref pathReader)) { if (_properties == null) _properties = new SpanDictionary(); _properties.Set(jsonPath, new EncodedValue(encodedValue.Kind, GetNewJson(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1), encodedValue))); return; } JsonPathToken current = pathReader.Current; if (current.TokenType != JsonPathTokenType.End) { ReadOnlySpan<byte> parsedPath = pathReader.GetParsedPath(); if (parsedPath.IsArrayIndex()) { value2 = _rawJson.Value; jsonReader = new Utf8JsonReader(value2.Span, default(JsonReaderOptions)); int arrayLength = ref jsonReader.GetArrayLength(parsedPath.GetParent()); current = pathReader.Current; Utf8Parser.TryParse(current.ValueSpan, out int value3, out bytesConsumed, ''); int length = parsedPath.Length; parsedPath.CopyTo(array); int newIndex = value3 - arrayLength; current = pathReader.Current; int length2 = current.ValueSpan.Length; current = pathReader.Current; AdjustJsonPath(newIndex, length2, current.TokenStartIndex, array, ref length); current = pathReader.Current; ReadOnlySpan<byte> readOnlySpan2 = jsonPath.Slice(current.TokenStartIndex + 2); readOnlySpan2.CopyTo(array.AsSpan(length)); readOnlySpan = array.AsSpan(0, length + readOnlySpan2.Length); } } } ReadOnlySpan<byte> readOnlySpan3 = readOnlySpan.SequenceEqual(jsonPath) ? readOnlySpan : readOnlySpan.GetParent(); ReadOnlySpan<byte> readOnlySpan4 = readOnlySpan; if (_properties != null) { while (true) { if (_properties.TryGetValue(readOnlySpan3, out value)) { GetSubPath(readOnlySpan3, readOnlySpan, ref subPath); ValueKind kind = subPath.IsRoot() ? encodedValue.Kind : value.Kind; _properties.Set(readOnlySpan3, new EncodedValue(kind, ModifyJson(value, subPath, encodedValue))); return; } if (readOnlySpan3.IsRoot()) break; readOnlySpan4 = readOnlySpan3; readOnlySpan3 = readOnlySpan3.GetParent(); } } if (encodedValue.Kind == ValueKind.Removed && jsonPath.IsArrayIndex()) { value2 = _rawJson.Value; Utf8JsonReader jsonReader2 = new Utf8JsonReader(value2.Span, default(JsonReaderOptions)); JsonPathReader pathReader2 = new JsonPathReader(jsonPath); if (ref jsonReader2.Advance(ref pathReader2)) { if (_properties == null) _properties = new SpanDictionary(); _properties.Set(jsonPath, new EncodedValue(encodedValue.Kind, GetNewJson(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1), encodedValue))); return; } ThrowIndexOutOfRangeException(jsonPath); } ValueKind valueKind = ValueKind.Json; ReadOnlySpan<byte> parent = readOnlySpan.GetParent(); if (parent.IsRoot()) { readOnlySpan4 = readOnlySpan; readOnlySpan3 = parent; } else { value2 = _rawJson.Value; if (value2.IsEmpty) { if (_properties == null) { readOnlySpan4 = readOnlySpan.GetFirstProperty(); readOnlySpan3 = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1); } if (readOnlySpan4.IsArrayIndex() && !encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { readOnlySpan4 = readOnlySpan3; valueKind |= ValueKind.ArrayItemAppend; } } else { JsonPathReader pathReader3 = new JsonPathReader(jsonPath); value2 = _rawJson.Value; Utf8JsonReader jsonReader3 = new Utf8JsonReader(value2.Span, default(JsonReaderOptions)); if (ref jsonReader3.Advance(ref pathReader3)) { readOnlySpan4 = jsonPath; readOnlySpan3 = parent; } else { readOnlySpan4 = pathReader3.GetParsedPath(); readOnlySpan3 = readOnlySpan4.GetParent(); if (readOnlySpan4.IsArrayIndex() && !encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { readOnlySpan4 = readOnlySpan3; valueKind |= ValueKind.ArrayItemAppend; } } } } if (readOnlySpan4.SequenceEqual(readOnlySpan)) valueKind = encodedValue.Kind; GetSubPath(readOnlySpan4, readOnlySpan, ref subPath); if (_properties == null) _properties = new SpanDictionary(); _properties.Set(readOnlySpan4, new EncodedValue(valueKind, GetNewJson(subPath, encodedValue))); } } } private static void GetSubPath(ReadOnlySpan<byte> parentPath, ReadOnlySpan<byte> fullPath, Span<byte> subPath, out int bytesWritten) { if (parentPath.IsRoot()) { fullPath.CopyTo(subPath); bytesWritten = fullPath.Length; } else { ReadOnlySpan<byte> readOnlySpan = fullPath.Slice(parentPath.Length); subPath[0] = 36; readOnlySpan.CopyTo(subPath.Slice(1)); bytesWritten = readOnlySpan.Length + 1; } } private static void GetSubPath(ReadOnlySpan<byte> parentPath, ReadOnlySpan<byte> fullPath, ref Span<byte> subPath) { GetSubPath(parentPath, fullPath, subPath, out int bytesWritten); subPath = subPath.Slice(0, bytesWritten); } private static ReadOnlyMemory<byte> ModifyJson(EncodedValue currentValue, ReadOnlySpan<byte> jsonPath, EncodedValue encodedValue) { if (!currentValue.Kind.HasFlag(ValueKind.Json) && !currentValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) return encodedValue.Value; ReadOnlyMemory<byte> value = currentValue.Value; if (encodedValue.Kind == ValueKind.Removed) return value.Remove(jsonPath); JsonPathReader pathReader = new JsonPathReader(jsonPath); Utf8JsonReader jsonReader = new Utf8JsonReader(value.Span, default(JsonReaderOptions)); bool flag = ref jsonReader.Advance(ref pathReader); ReadOnlyMemory<byte> readOnlyMemory; int bytesConsumed; if (!NeedsQuotes(encodedValue.Kind, jsonPath.IsArrayIndex())) readOnlyMemory = encodedValue.Value; else { byte b = 34; ReadOnlySpan<byte> span = encodedValue.Value.Span; bytesConsumed = 0; byte[] array = new byte[2 + span.Length]; array[bytesConsumed] = b; bytesConsumed++; span.CopyTo(new Span<byte>(array).Slice(bytesConsumed, span.Length)); bytesConsumed += span.Length; array[bytesConsumed] = 34; readOnlyMemory = new ReadOnlyMemory<byte>(array); } ReadOnlyMemory<byte> readOnlyMemory2 = readOnlyMemory; JsonPathToken current = pathReader.Current; ReadOnlySpan<byte> valueSpan = current.ValueSpan; int value2 = 0; current = pathReader.Current; if (current.TokenType == JsonPathTokenType.ArrayIndex) { current = pathReader.Current; Utf8Parser.TryParse(current.ValueSpan, out value2, out bytesConsumed, ''); } current = pathReader.Current; if (current.TokenType != JsonPathTokenType.End || jsonReader.TokenType == JsonTokenType.Null) readOnlyMemory2 = GetNonRootNewJson(ref pathReader, jsonPath.GetParent().IsRoot(), jsonPath.IsArrayIndex(), encodedValue); if (jsonReader.TokenType == JsonTokenType.PropertyName) jsonReader.Read(); if (flag && (jsonReader.TokenType != JsonTokenType.StartArray || !encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend))) return jsonReader.SetCurrentValue(flag, valueSpan, value, readOnlyMemory2); return ref jsonReader.Insert(value, valueSpan, readOnlyMemory2, value2 > 0); } private static ReadOnlyMemory<byte> GetNewJson(ReadOnlySpan<byte> jsonPath, EncodedValue encodedValue) { if (encodedValue.Kind == ValueKind.Removed) return encodedValue.Value; if (jsonPath.IsRoot()) { if (encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { ReadOnlyMemory<byte> value; ReadOnlySpan<byte> span; Span<byte> span2; byte b; byte[] array; int num; if (!NeedsQuotes(encodedValue.Kind, true)) { b = 91; value = encodedValue.Value; span = value.Span; num = 0; array = new byte[2 + span.Length]; array[num] = b; num++; span2 = new Span<byte>(array); span.CopyTo(span2.Slice(num, span.Length)); num += span.Length; array[num] = 93; return new ReadOnlyMemory<byte>(array); } b = 91; byte b2 = 34; value = encodedValue.Value; span = value.Span; num = 0; array = new byte[4 + span.Length]; array[num] = b; num++; array[num] = b2; num++; span2 = new Span<byte>(array); span.CopyTo(span2.Slice(num, span.Length)); num += span.Length; array[num] = 34; num++; array[num] = 93; return new ReadOnlyMemory<byte>(array); } return encodedValue.Value; } JsonPathReader reader = new JsonPathReader(jsonPath); return GetNonRootNewJson(ref reader, jsonPath.GetParent().IsRoot(), jsonPath.IsArrayIndex(), encodedValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsQuotes(ValueKind kind, bool isArrayIndex) { ValueKind valueKind = ValueKind.Utf8String | ValueKind.DateTime | ValueKind.Guid | ValueKind.TimeSpan; if ((kind & valueKind) > ValueKind.None) { if (!isArrayIndex) return kind.HasFlag(ValueKind.ArrayItemAppend); return true; } return false; } private static ReadOnlyMemory<byte> GetNonRootNewJson(ref JsonPathReader reader, bool isParentRoot, bool isArrayIndex, EncodedValue encodedValue) { using (UnsafeBufferSequence unsafeBufferSequence = new UnsafeBufferSequence(16384)) using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(unsafeBufferSequence, default(JsonWriterOptions))) { if (reader.Peek().TokenType == JsonPathTokenType.End) { if (encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { utf8JsonWriter.WriteStartArray(); WriteEncodedValueAsJson(utf8JsonWriter, ReadOnlySpan<byte>.Empty, encodedValue); utf8JsonWriter.WriteEndArray(); } else WriteEncodedValueAsJson(utf8JsonWriter, ReadOnlySpan<byte>.Empty, encodedValue); } else ProjectJson(utf8JsonWriter, ref reader, encodedValue, false); utf8JsonWriter.Flush(); using (UnsafeBufferSequence.Reader reader2 = unsafeBufferSequence.ExtractReader()) return reader2.ToBinaryData().ToMemory(); } } [System.Runtime.CompilerServices.NullableContext(1)] private static void ProjectJson(Utf8JsonWriter writer, ref JsonPathReader pathReader, EncodedValue encodedValue, bool inArray) { while (pathReader.Read()) { JsonPathToken jsonPathToken = pathReader.Current; switch (jsonPathToken.TokenType) { case JsonPathTokenType.ArrayIndex: writer.WriteStartArray(); jsonPathToken = pathReader.Current; Utf8Parser.TryParse(jsonPathToken.ValueSpan, out int value, out int _, ''); for (int i = 0; i < value; i++) { writer.WriteNullValue(); } jsonPathToken = pathReader.Peek(); if (jsonPathToken.TokenType == JsonPathTokenType.End) { if (encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { writer.WriteStartArray(); WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, encodedValue); writer.WriteEndArray(); } else WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, encodedValue); } else ProjectJson(writer, ref pathReader, encodedValue, true); writer.WriteEndArray(); break; case JsonPathTokenType.Property: if (!inArray) { jsonPathToken = pathReader.Current; writer.WritePropertyName(jsonPathToken.ValueSpan); } jsonPathToken = pathReader.Peek(); if (jsonPathToken.TokenType == JsonPathTokenType.End) { if (encodedValue.Kind.HasFlag(ValueKind.ArrayItemAppend)) { writer.WriteStartArray(); WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, encodedValue); writer.WriteEndArray(); } else WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, encodedValue); } else ProjectJson(writer, ref pathReader, encodedValue, false); break; case JsonPathTokenType.PropertySeparator: writer.WriteStartObject(); jsonPathToken = pathReader.Peek(); if (jsonPathToken.TokenType == JsonPathTokenType.End) WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, encodedValue); else ProjectJson(writer, ref pathReader, encodedValue, false); writer.WriteEndObject(); break; default: jsonPathToken = pathReader.Current; ThrowInvalidToken(jsonPathToken.TokenType); break; case JsonPathTokenType.Root: case JsonPathTokenType.End: break; } } } [EditorBrowsable(EditorBrowsableState.Never)] public unsafe void WriteTo([System.Runtime.CompilerServices.Nullable(1)] Utf8JsonWriter writer, ReadOnlySpan<byte> jsonPath) { if (_properties != null) { if (_properties.TryGetValue(jsonPath, out EncodedValue value)) { if (value.Kind == ValueKind.Removed) return; if (value.Kind.HasFlag(ValueKind.ArrayItemAppend)) { _properties.TryUpdateValueKind(jsonPath, value.Kind | ValueKind.ModelOwned); ReadOnlyMemory<byte> value2 = value.Value; ReadOnlySpan<byte> span = value2.Span; value2 = value.Value; writer.WriteRawValue(span.Slice(1, value2.Length - 2), false); } } int length = jsonPath.Length; Span<byte> span2 = new Span<byte>(stackalloc byte[(int)(uint)length], length); JsonPathComparer.Default.Normalize(jsonPath, span2, out int bytesWritten); span2 = span2.Slice(0, bytesWritten); Dictionary<byte[], ValueKind> dictionary = new Dictionary<byte[], ValueKind>(); foreach (KeyValuePair<byte[], EncodedValue> property in _properties) { EncodedValue value3 = property.Value; if (value3.Kind != ValueKind.Removed) { value3 = property.Value; if (!value3.Kind.HasFlag(ValueKind.ModelOwned)) { ReadOnlySpan<byte> readOnlySpan = property.Key; if (readOnlySpan.StartsWith(span2)) { readOnlySpan = readOnlySpan.Slice(span2.Length); WriteEncodedValueAsJson(writer, readOnlySpan.GetPropertyNameFromSlice(), property.Value); Dictionary<byte[], ValueKind> dictionary2 = dictionary; byte[] key = property.Key; value3 = property.Value; dictionary2.Add(key, value3.Kind); } } } } foreach (KeyValuePair<byte[], ValueKind> item in dictionary) { _properties.TryUpdateValueKind(item.Key, item.Value | ValueKind.ModelOwned); } } } [System.Runtime.CompilerServices.NullableContext(1)] [EditorBrowsable(EditorBrowsableState.Never)] public unsafe void WriteTo(Utf8JsonWriter writer) { bool flag = writer.CurrentDepth == 0 && writer.BytesCommitted == 0 && writer.BytesPending == 0; ReadOnlyMemory<byte> value = _rawJson.Value; bool flag2 = !value.IsEmpty; SpanHashSet spanHashSet = null; if ((!flag2 && _properties == null) & flag) { writer.WriteStartObject(); writer.WriteEndObject(); } else if (_properties != null || flag) { Dictionary<byte[], EncodedValue>.Enumerator enumerator; EncodedValue value3; if (_properties != null && (!flag2 || !flag)) { EncodedValue value2; bool flag3 = (!flag2 & flag) && !_properties.TryGetValue(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.33B67CB5385CEDDAD93D0EE960679041613BED34B8B4A5E6362FE7539BA2D3CE, 1), out value2) && !value2.Kind.HasFlag(ValueKind.ArrayItemAppend); if (flag3) writer.WriteStartObject(); enumerator = _properties.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyValuePair<byte[], EncodedValue> current = enumerator.Current; value3 = current.Value; if (value3.Kind != ValueKind.Removed) { value3 = current.Value; if (!value3.Kind.HasFlag(ValueKind.ModelOwned)) { value3 = current.Value; if (value3.Kind.HasFlag(ValueKind.ArrayItemAppend)) { ReadOnlySpan<byte> firstNonIndexParent = current.Key.GetFirstNonIndexParent(); if (spanHashSet == null || !spanHashSet.Contains(firstNonIndexParent)) { if (!current.Key.IsRoot() && !current.Key.IsArrayIndex()) writer.WritePropertyName(current.Key.GetPropertyName()); _properties.TryGetValue(firstNonIndexParent, out EncodedValue value4); writer.WriteRawValue(GetCombinedArray(firstNonIndexParent, value4).Span, false); if (spanHashSet == null) spanHashSet = new SpanHashSet(); spanHashSet.Add(firstNonIndexParent); } } else WriteEncodedValueAsJson(writer, current.Key.GetPropertyName(), current.Value); } } } } finally { ((IDisposable)enumerator).Dispose(); } if (flag3) writer.WriteEndObject(); } else if (_properties == null) { value = _rawJson.Value; if (!value.IsEmpty && writer.CurrentDepth == 0 && writer.BytesCommitted == 0 && writer.BytesPending == 0) { value = _rawJson.Value; writer.WriteRawValue(value.Span, false); } } else { ReadOnlyMemory<byte> readOnlyMemory = _rawJson.Value; enumerator = _properties.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyValuePair<byte[], EncodedValue> current2 = enumerator.Current; value3 = current2.Value; if (value3.Kind.HasFlag(ValueKind.Removed)) readOnlyMemory = readOnlyMemory.Remove(current2.Key); else { value3 = current2.Value; if (value3.Kind.HasFlag(ValueKind.ArrayItemAppend)) { ReadOnlyMemory<byte> json = readOnlyMemory; ReadOnlySpan<byte> arrayPath = current2.Key; value3 = current2.Value; value = value3.Value; value3 = current2.Value; readOnlyMemory = json.Append(arrayPath, value.Slice(1, value3.Value.Length - 2)); } else readOnlyMemory = readOnlyMemory.Set(current2.Key, GetEncodedBytes(current2.Value)); } } } finally { ((IDisposable)enumerator).Dispose(); } writer.WriteRawValue(readOnlyMemory.Span, false); } } } private static ReadOnlyMemory<byte> GetEncodedBytes(EncodedValue value) { ValueKind kind = value.Kind; if (kind.HasFlag(ValueKind.Utf8String) || kind.HasFlag(ValueKind.DateTime) || kind.HasFlag(ValueKind.Guid) || kind.HasFlag(ValueKind.TimeSpan)) { byte b = 34; ReadOnlySpan<byte> span = value.Value.Span; int num = 0; byte[] array = new byte[2 + span.Length]; array[num] = b; num++; span.CopyTo(new Span<byte>(array).Slice(num, span.Length)); num += span.Length; array[num] = 34; return new ReadOnlyMemory<byte>(array); } return value.Value; } private static void WriteEncodedValueAsJson([System.Runtime.CompilerServices.Nullable(1)] Utf8JsonWriter writer, ReadOnlySpan<byte> propertyName, EncodedValue encodedValue) { ReadOnlyMemory<byte> value = encodedValue.Value; if (value.Length == 0) throw new ArgumentException("Empty encoded value"); ValueKind valueKind = encodedValue.Kind & ~ValueKind.ArrayItemAppend; value = encodedValue.Value; ReadOnlySpan<byte> span = value.Span; if (!propertyName.IsEmpty) writer.WritePropertyName(propertyName); switch (valueKind) { case ValueKind.Removed: break; case ValueKind.Number: writer.WriteRawValue(span, false); break; case ValueKind.BooleanTrue: case ValueKind.BooleanFalse: writer.WriteBooleanValue(valueKind == ValueKind.BooleanTrue); break; case ValueKind.Json: writer.WriteRawValue(span, true); break; case ValueKind.Null: writer.WriteNullValue(); break; case ValueKind.Utf8String: case ValueKind.DateTime: case ValueKind.Guid: case ValueKind.TimeSpan: writer.WriteStringValue(span); break; default: throw new NotSupportedException($"""{valueKind}"); } } [System.Runtime.CompilerServices.NullableContext(1)] private unsafe void WriteAsJsonPatchTo(Utf8JsonWriter writer) { if (_properties != null) { ReadOnlyMemory<byte> value = _rawJson.Value; bool flag = !value.IsEmpty; ReadOnlyMemory<byte> value3 = _rawJson.Value; int num = _properties.MaxKeyLength << 1; Span<byte> buffer = new Span<byte>(stackalloc byte[(int)(uint)num], num); foreach (KeyValuePair<byte[], EncodedValue> property in _properties) { EncodedValue value2 = property.Value; bool flag2 = value2.Kind.HasFlag(ValueKind.ArrayItemAppend); value2 = property.Value; ReadOnlySpan<byte> utf8Value; ReadOnlyMemory<byte> target; if (value2.Kind == ValueKind.Removed) utf8Value = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.E1DB42A568E5246D5F800C8CB69BCC3E097730572AA5B89B8012AE1400008B4C, 6); else if (flag2 || !flag || !_rawJson.Value.TryGetJson(property.Key, out target)) { utf8Value = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.E85D22CC2678869C9425831CBC59ED688F5415192A32129FB2A404D693BCF601, 3); } else { value2 = property.Value; value = value2.Value; ReadOnlySpan<byte> span = value.Span; if (span.SequenceEqual(target.Span) || (span.Length > 2 && span[0] == 34 && span[span.Length - 1] == 34 && span.Slice(1, span.Length - 2).SequenceEqual(target.Span))) continue; utf8Value = new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.28E9B4CAF31EF6B6F5E415FD4C329980316DF1714DBE2D7798E4035D7228D5FD, 7); } writer.WriteStartObject(); writer.WritePropertyName(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.70147C9CC7A38C5E292AE6CB58C4969BC624448EF58138049B67010DE248DC3F, 2)); writer.WriteStringValue(utf8Value); writer.WritePropertyName(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.0B693A4BBE070FB05B1D70EECD2EB3964059C4739AD3616B02A57B582E4B77F3, 4)); int length = property.Key.ConvertToJsonPointer(buffer, flag2); writer.WriteStringValue(buffer.Slice(0, length)); value2 = property.Value; if (value2.Kind != ValueKind.Removed) { writer.WritePropertyName(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.2AC3E771679DFE9EC82B8748F6F7718F3AD0E4EAAFABC9F68F4BC25187A5F230, 5)); value2 = property.Value; ReadOnlyMemory<byte> readOnlyMemory = value2.Value; value2 = property.Value; ValueKind kind = value2.Kind; if (flag2 && readOnlyMemory.IsArrayWrapped()) { kind = ValueKind.Json; readOnlyMemory = readOnlyMemory.Slice(1, readOnlyMemory.Length - 2); } WriteEncodedValueAsJson(writer, ReadOnlySpan<byte>.Empty, new EncodedValue(kind, readOnlyMemory)); } writer.WriteEndObject(); } } } [System.Runtime.CompilerServices.NullableContext(1)] private string SerializeToJson() { using (UnsafeBufferSequence unsafeBufferSequence = new UnsafeBufferSequence(16384)) using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(unsafeBufferSequence, default(JsonWriterOptions))) { WriteTo(utf8JsonWriter); utf8JsonWriter.Flush(); return Encoding.UTF8.GetString(unsafeBufferSequence.ExtractReader().ToBinaryData().ToArray()); } } [System.Runtime.CompilerServices.NullableContext(1)] private string SerializeToJsonPatch() { using (UnsafeBufferSequence unsafeBufferSequence = new UnsafeBufferSequence(16384)) using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(unsafeBufferSequence, default(JsonWriterOptions))) { utf8JsonWriter.WriteStartArray(); WriteAsJsonPatchTo(utf8JsonWriter); utf8JsonWriter.WriteEndArray(); utf8JsonWriter.Flush(); return Encoding.UTF8.GetString(unsafeBufferSequence.ExtractReader().ToBinaryData().ToArray()); } } [MethodImpl(MethodImplOptions.NoInlining)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static ReadOnlyMemory<byte> ThrowKeyNotFoundException(ReadOnlySpan<byte> jsonPath) { throw new KeyNotFoundException("No value found at JSON path '" + Encoding.UTF8.GetString(jsonPath.ToArray()) + "'."); } [System.Runtime.CompilerServices.NullableContext(1)] private static void ThrowIfNull([System.Runtime.CompilerServices.Nullable(2)] object obj, string parameterName) { if (obj == null) ThrowArgumentNullException(parameterName); } [System.Runtime.CompilerServices.NullableContext(1)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowArgumentNullException(string parameterName) { throw new ArgumentNullException(parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [System.Runtime.CompilerServices.NullableContext(1)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static string ThrowFormatNotSupportedException(string format) { throw new NotSupportedException("The format '" + format + "' is not supported."); } [MethodImpl(MethodImplOptions.NoInlining)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] [return: System.Runtime.CompilerServices.Nullable(1)] private static T ThrowFormatException<[System.Runtime.CompilerServices.Nullable(2)] T>(ReadOnlySpan<byte> jsonPath) { throw new FormatException($"""{Encoding.UTF8.GetString(jsonPath.ToArray())}""{typeof(T)}"""); } [MethodImpl(MethodImplOptions.NoInlining)] [System.Runtime.CompilerServices.NullableContext(2)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static T NullableTypeNotSupported<T>() { throw new NotSupportedException($"""{typeof(T)}"""); } [MethodImpl(MethodImplOptions.NoInlining)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowIndexOutOfRangeException(ReadOnlySpan<byte> jsonPath) { throw new IndexOutOfRangeException("Cannot remove non-existing array item at path '" + Encoding.UTF8.GetString(jsonPath.ToArray()) + "'."); } [MethodImpl(MethodImplOptions.NoInlining)] [System.Diagnostics.CodeAnalysis.DoesNotReturn] private static void ThrowInvalidToken(JsonPathTokenType tokenType) { throw new InvalidOperationException($"""{tokenType}"); } } }