ChunkSequence<T>
Represents sequence of memory chunks.
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Buffers
{
[StructLayout(LayoutKind.Auto)]
public readonly struct ChunkSequence<[System.Runtime.CompilerServices.Nullable(2)] T> : IEnumerable<ReadOnlyMemory<T>>, IEnumerable
{
[StructLayout(LayoutKind.Auto)]
public struct Enumerator : IEnumerator<ReadOnlyMemory<T>>, IEnumerator, IDisposable
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private readonly ReadOnlyMemory<T> source;
private readonly int chunkSize;
private int startIndex;
private int length;
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlyMemory<T> Current {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return source.Slice(startIndex, length);
}
}
[System.Runtime.CompilerServices.Nullable(1)]
object IEnumerator.Current {
[IsReadOnly]
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return Current;
}
}
internal Enumerator([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlyMemory<T> source, int chunkSize)
{
this.source = source;
this.chunkSize = chunkSize;
startIndex = (length = -1);
}
void IDisposable.Dispose()
{
this = default(Enumerator);
}
public bool MoveNext()
{
if (startIndex == -1) {
startIndex = 0;
length = Math.Min(chunkSize, source.Length);
} else {
startIndex += chunkSize;
length = Math.Min(source.Length - startIndex, chunkSize);
}
return startIndex < source.Length;
}
public void Reset()
{
startIndex = -1;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private readonly ReadOnlyMemory<T> memory;
private readonly int chunkSize;
public ChunkSequence([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlyMemory<T> memory, int chunkSize)
{
if (chunkSize < 1)
throw new ArgumentOutOfRangeException("chunkSize");
this.chunkSize = chunkSize;
this.memory = memory;
}
public Enumerator GetEnumerator()
{
return new Enumerator(memory, chunkSize);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})]
IEnumerator<ReadOnlyMemory<T>> IEnumerable<ReadOnlyMemory<T>>.GetEnumerator()
{
return GetEnumerator();
}
[System.Runtime.CompilerServices.NullableContext(1)]
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlySequence<T> ToReadOnlySequence()
{
if (memory.IsEmpty)
return ReadOnlySequence<T>.Empty;
if (memory.Length < chunkSize)
return new ReadOnlySequence<T>(memory);
Chunk<T> first = null;
Chunk<T> last = null;
using (Enumerator enumerator = GetEnumerator()) {
while (enumerator.MoveNext()) {
Chunk<T>.AddChunk(enumerator.Current, ref first, ref last);
}
}
return Chunk<T>.CreateSequence(first, last);
}
public static explicit operator ReadOnlySequence<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ChunkSequence<T> sequence)
{
return sequence.ToReadOnlySequence();
}
}
}