BufferHelpers
Represents helper methods to work with various buffer representations.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Buffers
{
public static class BufferHelpers
{
private static void Write<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref BufferWriterSlim<byte> builder, IntPtr encoder, T value) where T : struct
{
Span<byte> span = Span.AsBytes(ref value);
;
builder.Write((ReadOnlySpan<byte>)span);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt16(ref BufferWriterSlim<byte> builder, short value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt16(ref BufferWriterSlim<byte> builder, ushort value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt32(ref BufferWriterSlim<byte> builder, int value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt32(ref BufferWriterSlim<byte> builder, uint value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt64(ref BufferWriterSlim<byte> builder, long value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt64(ref BufferWriterSlim<byte> builder, ulong value, bool isLittleEndian)
{
Write(ref builder, (IntPtr)(void*)(isLittleEndian ? : ), value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public static ReadOnlySequence<T> ToReadOnlySequence<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] this IEnumerable<ReadOnlyMemory<T>> chunks)
{
Chunk<T> first = null;
Chunk<T> last = null;
foreach (ReadOnlyMemory<T> chunk in chunks) {
if (!chunk.IsEmpty)
Chunk<T>.AddChunk(chunk, ref first, ref last);
}
if (first == null || last == null)
return ReadOnlySequence<T>.Empty;
if (first == last)
return new ReadOnlySequence<T>(((ReadOnlySequenceSegment<T>)first).Memory);
return Chunk<T>.CreateSequence(first, last);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public static ReadOnlySequence<T> Concat<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] this ReadOnlyMemory<T> first, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlyMemory<T> second)
{
if (first.IsEmpty) {
if (!second.IsEmpty)
return new ReadOnlySequence<T>(second);
return ReadOnlySequence<T>.Empty;
}
if (second.IsEmpty)
return new ReadOnlySequence<T>(first);
Chunk<T> first2 = null;
Chunk<T> last = null;
Chunk<T>.AddChunk(first, ref first2, ref last);
Chunk<T>.AddChunk(second, ref first2, ref last);
return Chunk<T>.CreateSequence(first2, last);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static string BuildString(this ArrayBufferWriter<char> writer)
{
ReadOnlySpan<char> writtenSpan = writer.WrittenSpan;
if (!writtenSpan.IsEmpty)
return new string(writtenSpan);
return string.Empty;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static void Write<[System.Runtime.CompilerServices.Nullable(2)] T>(this IBufferWriter<T> writer, T value)
{
writer.GetSpan(0)[0] = value;
writer.Advance(1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static void Write<[System.Runtime.CompilerServices.Nullable(2)] T>(this IBufferWriter<T> writer, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySequence<T> value)
{
if (value.IsSingleSegment)
writer.Write(value.FirstSpan);
else
<Write>g__WriteSlow|11_0(writer, ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(2)]
public static void CopyTo<T>([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref ReadOnlySequence<T> source, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> destination, out int writtenCount)
{
if (source.IsSingleSegment)
source.FirstSpan.CopyTo(destination, out writtenCount);
else
writtenCount = <CopyTo>g__CopyToSlow|12_0(ref source, destination);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static void ReleaseAll<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref MemoryOwner<T> owner) where T : IDisposable
{
Span<T> span = owner.Memory.Span;
for (int i = 0; i < span.Length; i++) {
ref T reference = ref span[i];
reference.Dispose();
reference = default(T);
}
owner.Dispose(false);
}
[System.Runtime.CompilerServices.NullableContext(1)]
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static ref T GetReference<[System.Runtime.CompilerServices.Nullable(2)] T>([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref MemoryOwner<T> owner)
{
if (!owner.IsEmpty)
return ref owner.First;
return ref Unsafe.NullRef<T>();
}
public unsafe static bool TryRead<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanReader<byte> reader, out T result) where T : struct
{
if (MemoryMarshal.TryRead(reader.RemainingSpan, out result)) {
reader.Advance(sizeof(T));
return true;
}
result = default(T);
return false;
}
public unsafe static T Read<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanReader<byte> reader) where T : struct
{
T result = MemoryMarshal.Read<T>(reader.RemainingSpan);
reader.Advance(sizeof(T));
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static T Read<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanReader<byte> reader, IntPtr parser) where T : struct
{
object result = (object);
reader.Advance(sizeof(T));
return (T)result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static short ReadInt16(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<short>((IntPtr)(void*)(isLittleEndian ? : ));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static ushort ReadUInt16(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<ushort>((IntPtr)(void*)(isLittleEndian ? : ));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static int ReadInt32(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<int>((IntPtr)(void*)(isLittleEndian ? : ));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static uint ReadUInt32(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<uint>((IntPtr)(void*)(isLittleEndian ? : ));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static long ReadInt64(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<long>((IntPtr)(void*)(isLittleEndian ? : ));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static ulong ReadUInt64(ref SpanReader<byte> reader, bool isLittleEndian)
{
return ref reader.Read<ulong>((IntPtr)(void*)(isLittleEndian ? : ));
}
public static bool TryWrite<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanWriter<byte> writer, [In] [IsReadOnly] ref T value) where T : struct
{
return writer.TryWrite(Span.AsReadOnlyBytes(ref value));
}
public static void Write<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanWriter<byte> writer, [In] [IsReadOnly] ref T value) where T : struct
{
writer.Write(Span.AsReadOnlyBytes(ref value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static void Write<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref SpanWriter<byte> writer, IntPtr action, T value) where T : struct
{
;
writer.Advance(sizeof(T));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt16(ref SpanWriter<byte> writer, short value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt16(ref SpanWriter<byte> writer, ushort value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt32(ref SpanWriter<byte> writer, int value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt32(ref SpanWriter<byte> writer, uint value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static void WriteInt64(ref SpanWriter<byte> writer, long value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void WriteUInt64(ref SpanWriter<byte> writer, ulong value, bool isLittleEndian)
{
ref writer.Write((IntPtr)(void*)(isLittleEndian ? : ), value);
}
internal static int LinearGrowth(int chunkSize, ref int chunkIndex)
{
return Math.Max(chunkSize * ++chunkIndex, chunkSize);
}
internal static int ExponentialGrowth(int chunkSize, ref int chunkIndex)
{
return Math.Max(chunkSize << ++chunkIndex, chunkSize);
}
internal static int NoGrowth(int chunkSize, ref int chunkIndex)
{
return chunkSize;
}
}
}