<PackageReference Include="System.Text.Json" Version="10.0.0-preview.7.25380.108" />

ArrayBuffer

using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Net { [StructLayout(LayoutKind.Auto)] internal struct ArrayBuffer : IDisposable { private const int ArrayMaxLength = 2147483591; private readonly bool _usePool; private byte[] _bytes; private int _activeStart; private int _availableStart; public int ActiveLength => _availableStart - _activeStart; public Span<byte> ActiveSpan => new Span<byte>(_bytes, _activeStart, _availableStart - _activeStart); public ReadOnlySpan<byte> ActiveReadOnlySpan => new ReadOnlySpan<byte>(_bytes, _activeStart, _availableStart - _activeStart); public Memory<byte> ActiveMemory => new Memory<byte>(_bytes, _activeStart, _availableStart - _activeStart); public int AvailableLength => _bytes.Length - _availableStart; public Span<byte> AvailableSpan => _bytes.AsSpan(_availableStart); public Memory<byte> AvailableMemory => _bytes.AsMemory(_availableStart); public int Capacity => _bytes.Length; public int ActiveStartOffset => _activeStart; public ArrayBuffer(int initialSize, bool usePool = false) { _usePool = usePool; _bytes = ((initialSize == 0) ? Array.Empty<byte>() : (usePool ? ArrayPool<byte>.Shared.Rent(initialSize) : new byte[initialSize])); _activeStart = 0; _availableStart = 0; } public ArrayBuffer(byte[] buffer) { _usePool = false; _bytes = buffer; _activeStart = 0; _availableStart = 0; } public void Dispose() { _activeStart = 0; _availableStart = 0; byte[] bytes = _bytes; _bytes = null; if (bytes != null) ReturnBufferIfPooled(bytes); } public void ClearAndReturnBuffer() { _activeStart = 0; _availableStart = 0; byte[] bytes = _bytes; _bytes = Array.Empty<byte>(); ReturnBufferIfPooled(bytes); } public Memory<byte> AvailableMemorySliced(int length) { return new Memory<byte>(_bytes, _availableStart, length); } public byte[] DangerousGetUnderlyingBuffer() { return _bytes; } public void Discard(int byteCount) { _activeStart += byteCount; if (_activeStart == _availableStart) { _activeStart = 0; _availableStart = 0; } } public void Commit(int byteCount) { _availableStart += byteCount; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EnsureAvailableSpace(int byteCount) { if (byteCount > AvailableLength) EnsureAvailableSpaceCore(byteCount); } private void EnsureAvailableSpaceCore(int byteCount) { if (_bytes.Length == 0) _bytes = ArrayPool<byte>.Shared.Rent(byteCount); else { int num = _activeStart + AvailableLength; if (byteCount <= num) { Buffer.BlockCopy(_bytes, _activeStart, _bytes, 0, ActiveLength); _availableStart = ActiveLength; _activeStart = 0; } else { int num2 = ActiveLength + byteCount; if ((uint)num2 > 2147483591) throw new OutOfMemoryException(); int num3 = Math.Max(num2, (int)Math.Min(2147483591, (uint)(2 * _bytes.Length))); byte[] array = _usePool ? ArrayPool<byte>.Shared.Rent(num3) : new byte[num3]; byte[] bytes = _bytes; if (ActiveLength != 0) Buffer.BlockCopy(bytes, _activeStart, array, 0, ActiveLength); _availableStart = ActiveLength; _activeStart = 0; _bytes = array; ReturnBufferIfPooled(bytes); } } } public void Grow() { EnsureAvailableSpaceCore(AvailableLength + 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReturnBufferIfPooled(byte[] buffer) { if (_usePool && buffer.Length != 0) ArrayPool<byte>.Shared.Return(buffer, false); } } }