Update MessagePack commit to be inline with upstream changes (#9753)
* Update MessagePack commit to be inline with upstream changes
This commit is contained in:
parent
3a4e7866d4
commit
3c40df452d
|
|
@ -95,3 +95,72 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
License notice for MessagePack-CSharp
|
||||
-------------------------------------
|
||||
|
||||
MessagePack for C#
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Yoshifumi Kawai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
lz4net
|
||||
|
||||
Copyright (c) 2013-2017, Milosz Krajewski
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
License notice for Nerdbank.Streams
|
||||
-----------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Andrew Arnott
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
internal class NativeDateTimeFormatter
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Andrew Arnott. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
||||
namespace Nerdbank.Streams
|
||||
{
|
||||
internal static class Requires
|
||||
{
|
||||
internal static void NotNull(object arg, string paramName)
|
||||
{
|
||||
if (arg == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(paramName));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Argument(bool condition, string paramName, string message)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
throw new ArgumentException(message, paramName);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Range(bool condition, string paramName)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(paramName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
// Copyright (c) Andrew Arnott. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
||||
|
||||
namespace Nerdbank.Streams
|
||||
{
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft;
|
||||
|
||||
/// <summary>
|
||||
/// Manages a sequence of elements, readily castable as a <see cref="ReadOnlySequence{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of element stored by the sequence.</typeparam>
|
||||
/// <remarks>
|
||||
/// Instance members are not thread-safe.
|
||||
/// </remarks>
|
||||
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
|
||||
internal class Sequence<T> : IBufferWriter<T>, IDisposable
|
||||
{
|
||||
private static readonly int DefaultLengthFromArrayPool = 1 + (4095 / Marshal.SizeOf<T>());
|
||||
|
||||
private readonly Stack<SequenceSegment> segmentPool = new Stack<SequenceSegment>();
|
||||
|
||||
private readonly MemoryPool<T> memoryPool;
|
||||
|
||||
private readonly ArrayPool<T> arrayPool;
|
||||
|
||||
private SequenceSegment first;
|
||||
|
||||
private SequenceSegment last;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Sequence{T}"/> class
|
||||
/// that uses a private <see cref="ArrayPool{T}"/> for recycling arrays.
|
||||
/// </summary>
|
||||
public Sequence()
|
||||
: this(ArrayPool<T>.Create())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Sequence{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="memoryPool">The pool to use for recycling backing arrays.</param>
|
||||
public Sequence(MemoryPool<T> memoryPool)
|
||||
{
|
||||
Requires.NotNull(memoryPool, nameof(memoryPool));
|
||||
this.memoryPool = memoryPool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Sequence{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arrayPool">The pool to use for recycling backing arrays.</param>
|
||||
public Sequence(ArrayPool<T> arrayPool)
|
||||
{
|
||||
Requires.NotNull(arrayPool, nameof(arrayPool));
|
||||
this.arrayPool = arrayPool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum length for any array allocated as a segment in the sequence.
|
||||
/// Any non-positive value allows the pool to determine the length of the array.
|
||||
/// </summary>
|
||||
/// <value>The default value is 0.</value>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Each time <see cref="GetSpan(int)"/> or <see cref="GetMemory(int)"/> is called,
|
||||
/// previously allocated memory is used if it is large enough to satisfy the length demand.
|
||||
/// If new memory must be allocated, the argument to one of these methods typically dictate
|
||||
/// the length of array to allocate. When the caller uses very small values (just enough for its immediate need)
|
||||
/// but the high level scenario can predict that a large amount of memory will be ultimately required,
|
||||
/// it can be advisable to set this property to a value such that just a few larger arrays are allocated
|
||||
/// instead of many small ones.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The <see cref="MemoryPool{T}"/> in use may itself have a minimum array length as well,
|
||||
/// in which case the higher of the two minimums dictate the minimum array size that will be allocated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public int MinimumSpanLength { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets this sequence expressed as a <see cref="ReadOnlySequence{T}"/>.
|
||||
/// </summary>
|
||||
/// <returns>A read only sequence representing the data in this object.</returns>
|
||||
public ReadOnlySequence<T> AsReadOnlySequence => this;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the sequence.
|
||||
/// </summary>
|
||||
public long Length => this.AsReadOnlySequence.Length;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value to display in a debugger datatip.
|
||||
/// </summary>
|
||||
private string DebuggerDisplay => $"Length: {AsReadOnlySequence.Length}";
|
||||
|
||||
/// <summary>
|
||||
/// Expresses this sequence as a <see cref="ReadOnlySequence{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="sequence">The sequence to convert.</param>
|
||||
public static implicit operator ReadOnlySequence<T>(Sequence<T> sequence)
|
||||
{
|
||||
return sequence.first != null
|
||||
? new ReadOnlySequence<T>(sequence.first, sequence.first.Start, sequence.last, sequence.last.End)
|
||||
: ReadOnlySequence<T>.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all elements from the sequence from its beginning to the specified position,
|
||||
/// considering that data to have been fully processed.
|
||||
/// </summary>
|
||||
/// <param name="position">
|
||||
/// The position of the first element that has not yet been processed.
|
||||
/// This is typically <see cref="ReadOnlySequence{T}.End"/> after reading all elements from that instance.
|
||||
/// </param>
|
||||
public void AdvanceTo(SequencePosition position)
|
||||
{
|
||||
var firstSegment = (SequenceSegment)position.GetObject();
|
||||
int firstIndex = position.GetInteger();
|
||||
|
||||
// Before making any mutations, confirm that the block specified belongs to this sequence.
|
||||
var current = this.first;
|
||||
while (current != firstSegment && current != null)
|
||||
{
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
Requires.Argument(current != null, nameof(position), "Position does not represent a valid position in this sequence.");
|
||||
|
||||
// Also confirm that the position is not a prior position in the block.
|
||||
Requires.Argument(firstIndex >= current.Start, nameof(position), "Position must not be earlier than current position.");
|
||||
|
||||
// Now repeat the loop, performing the mutations.
|
||||
current = this.first;
|
||||
while (current != firstSegment)
|
||||
{
|
||||
current = this.RecycleAndGetNext(current);
|
||||
}
|
||||
|
||||
firstSegment.AdvanceTo(firstIndex);
|
||||
|
||||
if (firstSegment.Length == 0)
|
||||
{
|
||||
firstSegment = this.RecycleAndGetNext(firstSegment);
|
||||
}
|
||||
|
||||
this.first = firstSegment;
|
||||
|
||||
if (this.first == null)
|
||||
{
|
||||
this.last = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advances the sequence to include the specified number of elements initialized into memory
|
||||
/// returned by a prior call to <see cref="GetMemory(int)"/>.
|
||||
/// </summary>
|
||||
/// <param name="count">The number of elements written into memory.</param>
|
||||
public void Advance(int count)
|
||||
{
|
||||
SequenceSegment last = this.last;
|
||||
Debug.Assert(last != null, "Cannot advance before acquiring memory.");
|
||||
last.Advance(count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets writable memory that can be initialized and added to the sequence via a subsequent call to <see cref="Advance(int)"/>.
|
||||
/// </summary>
|
||||
/// <param name="sizeHint">The size of the memory required, or 0 to just get a convenient (non-empty) buffer.</param>
|
||||
/// <returns>The requested memory.</returns>
|
||||
public Memory<T> GetMemory(int sizeHint) => this.GetSegment(sizeHint).RemainingMemory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets writable memory that can be initialized and added to the sequence via a subsequent call to <see cref="Advance(int)"/>.
|
||||
/// </summary>
|
||||
/// <param name="sizeHint">The size of the memory required, or 0 to just get a convenient (non-empty) buffer.</param>
|
||||
/// <returns>The requested memory.</returns>
|
||||
public Span<T> GetSpan(int sizeHint) => this.GetSegment(sizeHint).RemainingSpan;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the entire sequence, recycles associated memory into pools,
|
||||
/// and resets this instance for reuse.
|
||||
/// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void Dispose() => this.Reset();
|
||||
|
||||
/// <summary>
|
||||
/// Clears the entire sequence and recycles associated memory into pools.
|
||||
/// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
var current = this.first;
|
||||
while (current != null)
|
||||
{
|
||||
current = this.RecycleAndGetNext(current);
|
||||
}
|
||||
|
||||
this.first = this.last = null;
|
||||
}
|
||||
|
||||
private SequenceSegment GetSegment(int sizeHint)
|
||||
{
|
||||
Requires.Range(sizeHint >= 0, nameof(sizeHint));
|
||||
int? minBufferSize = null;
|
||||
if (sizeHint == 0)
|
||||
{
|
||||
if (this.last == null || this.last.WritableBytes == 0)
|
||||
{
|
||||
// We're going to need more memory. Take whatever size the pool wants to give us.
|
||||
minBufferSize = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sizeHint = Math.Max(this.MinimumSpanLength, sizeHint);
|
||||
if (this.last == null || this.last.WritableBytes < sizeHint)
|
||||
{
|
||||
minBufferSize = sizeHint;
|
||||
}
|
||||
}
|
||||
|
||||
if (minBufferSize.HasValue)
|
||||
{
|
||||
var segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment();
|
||||
if (this.arrayPool != null)
|
||||
{
|
||||
segment.Assign(this.arrayPool.Rent(minBufferSize.Value == -1 ? DefaultLengthFromArrayPool : minBufferSize.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
segment.Assign(this.memoryPool.Rent(minBufferSize.Value));
|
||||
}
|
||||
|
||||
this.Append(segment);
|
||||
}
|
||||
|
||||
return this.last;
|
||||
}
|
||||
|
||||
private void Append(SequenceSegment segment)
|
||||
{
|
||||
if (this.last == null)
|
||||
{
|
||||
this.first = this.last = segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.last.Length > 0)
|
||||
{
|
||||
// Add a new block.
|
||||
this.last.SetNext(segment);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The last block is completely unused. Replace it instead of appending to it.
|
||||
var current = this.first;
|
||||
if (this.first != this.last)
|
||||
{
|
||||
while (current.Next != this.last)
|
||||
{
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.first = segment;
|
||||
}
|
||||
|
||||
current.SetNext(segment);
|
||||
this.RecycleAndGetNext(this.last);
|
||||
}
|
||||
|
||||
this.last = segment;
|
||||
}
|
||||
}
|
||||
|
||||
private SequenceSegment RecycleAndGetNext(SequenceSegment segment)
|
||||
{
|
||||
var recycledSegment = segment;
|
||||
segment = segment.Next;
|
||||
recycledSegment.ResetMemory(this.arrayPool);
|
||||
this.segmentPool.Push(recycledSegment);
|
||||
return segment;
|
||||
}
|
||||
|
||||
private class SequenceSegment : ReadOnlySequenceSegment<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// A value indicating whether the element is a value type.
|
||||
/// </summary>
|
||||
private static readonly bool IsValueTypeElement = typeof(T).GetTypeInfo().IsValueType;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the backing array, when using an <see cref="ArrayPool{T}"/> instead of a <see cref="MemoryPool{T}"/>.
|
||||
/// </summary>
|
||||
private T[] array;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position within <see cref="ReadOnlySequenceSegment{T}.Memory"/> where the data starts.
|
||||
/// </summary>
|
||||
/// <remarks>This may be nonzero as a result of calling <see cref="Sequence{T}.AdvanceTo(SequencePosition)"/>.</remarks>
|
||||
internal int Start { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position within <see cref="ReadOnlySequenceSegment{T}.Memory"/> where the data ends.
|
||||
/// </summary>
|
||||
internal int End { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tail of memory that has not yet been committed.
|
||||
/// </summary>
|
||||
internal Memory<T> RemainingMemory => this.AvailableMemory.Slice(this.End);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tail of memory that has not yet been committed.
|
||||
/// </summary>
|
||||
internal Span<T> RemainingSpan => this.AvailableMemory.Span.Slice(this.End);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tracker for the underlying array for this segment, which can be used to recycle the array when we're disposed of.
|
||||
/// Will be <c>null</c> if using an array pool, in which case the memory is held by <see cref="array"/>.
|
||||
/// </summary>
|
||||
internal IMemoryOwner<T> MemoryOwner { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full memory owned by the <see cref="MemoryOwner"/>.
|
||||
/// </summary>
|
||||
internal Memory<T> AvailableMemory => this.array ?? this.MemoryOwner?.Memory ?? default;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements that are committed in this segment.
|
||||
/// </summary>
|
||||
internal int Length => this.End - this.Start;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of writable bytes in this segment.
|
||||
/// It is the amount of bytes between <see cref="Length"/> and <see cref="End"/>.
|
||||
/// </summary>
|
||||
internal int WritableBytes => this.AvailableMemory.Length - this.End;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next segment in the singly linked list of segments.
|
||||
/// </summary>
|
||||
internal new SequenceSegment Next
|
||||
{
|
||||
get => (SequenceSegment)base.Next;
|
||||
set => base.Next = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns this (recyclable) segment a new area in memory.
|
||||
/// </summary>
|
||||
/// <param name="memoryOwner">The memory and a means to recycle it.</param>
|
||||
internal void Assign(IMemoryOwner<T> memoryOwner)
|
||||
{
|
||||
this.MemoryOwner = memoryOwner;
|
||||
this.Memory = memoryOwner.Memory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns this (recyclable) segment a new area in memory.
|
||||
/// </summary>
|
||||
/// <param name="array">An array drawn from an <see cref="ArrayPool{T}"/>.</param>
|
||||
internal void Assign(T[] array)
|
||||
{
|
||||
this.array = array;
|
||||
this.Memory = array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all fields in preparation to recycle this instance.
|
||||
/// </summary>
|
||||
internal void ResetMemory(ArrayPool<T> arrayPool)
|
||||
{
|
||||
this.ClearReferences(this.Start, this.End);
|
||||
this.Memory = default;
|
||||
this.Next = null;
|
||||
this.RunningIndex = 0;
|
||||
this.Start = 0;
|
||||
this.End = 0;
|
||||
if (this.array != null)
|
||||
{
|
||||
arrayPool.Return(this.array);
|
||||
this.array = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.MemoryOwner?.Dispose();
|
||||
this.MemoryOwner = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new segment after this one.
|
||||
/// </summary>
|
||||
/// <param name="segment">The next segment in the linked list.</param>
|
||||
internal void SetNext(SequenceSegment segment)
|
||||
{
|
||||
Debug.Assert(segment != null, "Null not allowed.");
|
||||
this.Next = segment;
|
||||
segment.RunningIndex = this.RunningIndex + this.Start + this.Length;
|
||||
|
||||
// When setting Memory, we start with index 0 instead of this.Start because
|
||||
// the first segment has an explicit index set anyway,
|
||||
// and we don't want to double-count it here.
|
||||
this.Memory = this.AvailableMemory.Slice(0, this.Start + this.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commits more elements as written in this segment.
|
||||
/// </summary>
|
||||
/// <param name="count">The number of elements written.</param>
|
||||
internal void Advance(int count)
|
||||
{
|
||||
Requires.Range(count >= 0 && this.End + count <= this.Memory.Length, nameof(count));
|
||||
this.End += count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes some elements from the start of this segment.
|
||||
/// </summary>
|
||||
/// <param name="offset">The number of elements to ignore from the start of the underlying array.</param>
|
||||
internal void AdvanceTo(int offset)
|
||||
{
|
||||
Debug.Assert(offset >= this.Start, "Trying to rewind.");
|
||||
this.ClearReferences(this.Start, offset - this.Start);
|
||||
this.Start = offset;
|
||||
}
|
||||
|
||||
private void ClearReferences(int startIndex, int length)
|
||||
{
|
||||
// If we store references, clear them to allow the objects to be GC'd.
|
||||
if (!IsValueTypeElement)
|
||||
{
|
||||
this.AvailableMemory.Span.Slice(startIndex, length).Fill(default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>CS0436;$(NoWarn)</NoWarn>
|
||||
<DefineConstants>$(DefineConstants);MESSAGEPACK_INTERNAL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -42,6 +44,7 @@
|
|||
<Compile Include="$(MessagePackRoot)FloatBits.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
<Compile Include="$(MessagePackRoot)Internal\DateTimeConstants.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
<Compile Include="$(MessagePackRoot)StringEncoding.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
<Compile Include="$(MessagePackRoot)SequencePool.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
<Compile Include="$(MessagePackRoot)SequenceReader.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
<Compile Include="$(MessagePackRoot)SequenceReaderExtensions.cs" LinkBase="BlazorPack\MessagePack" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
|
|||
<SharedFxContent Include="$(ProjectDepsFilePath)" />
|
||||
<SharedFxContent Include="$(ProjectRuntimeConfigFilePath)" />
|
||||
<SharedFxContent Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)' != '.pdb'" />
|
||||
<SharedFxContent Include="$(RepositoryRoot)THIRD-PARTY-NOTICES.txt" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 1917b8018fca93805573663d5baf067e6ac2b137
|
||||
Subproject commit 8861abdde93a3b97180ac3b2eafa33459ad52392
|
||||
Loading…
Reference in New Issue