SpanT is available in .Net Standard 2.0. (#6137)

This commit is contained in:
春条
2020-09-26 02:39:28 +09:00
committed by GitHub
parent dca12522a9
commit 52e3628794
3 changed files with 53 additions and 29 deletions

View File

@@ -42,15 +42,19 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
using System.Buffers.Binary; using System.Buffers.Binary;
#endif #endif
#if ENABLE_SPAN_T && !UNSAFE_BYTEBUFFER && !NETSTANDARD2_1
#warning ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
#endif
namespace FlatBuffers namespace FlatBuffers
{ {
public abstract class ByteBufferAllocator public abstract class ByteBufferAllocator
{ {
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public abstract Span<byte> Span { get; } public abstract Span<byte> Span { get; }
public abstract ReadOnlySpan<byte> ReadOnlySpan { get; } public abstract ReadOnlySpan<byte> ReadOnlySpan { get; }
public abstract Memory<byte> Memory { get; } public abstract Memory<byte> Memory { get; }
@@ -98,7 +102,7 @@ namespace FlatBuffers
InitBuffer(); InitBuffer();
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public override Span<byte> Span => _buffer; public override Span<byte> Span => _buffer;
public override ReadOnlySpan<byte> ReadOnlySpan => _buffer; public override ReadOnlySpan<byte> ReadOnlySpan => _buffer;
public override Memory<byte> Memory => _buffer; public override Memory<byte> Memory => _buffer;
@@ -108,7 +112,7 @@ namespace FlatBuffers
private void InitBuffer() private void InitBuffer()
{ {
Length = _buffer.Length; Length = _buffer.Length;
#if !ENABLE_SPAN_T || !NETSTANDARD2_1 #if !ENABLE_SPAN_T
Buffer = _buffer; Buffer = _buffer;
#endif #endif
} }
@@ -220,7 +224,7 @@ namespace FlatBuffers
return SizeOf<T>() * x.Length; return SizeOf<T>() * x.Length;
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public static int ArraySize<T>(Span<T> x) public static int ArraySize<T>(Span<T> x)
{ {
return SizeOf<T>() * x.Length; return SizeOf<T>() * x.Length;
@@ -229,7 +233,7 @@ namespace FlatBuffers
// Get a portion of the buffer casted into an array of type T, given // Get a portion of the buffer casted into an array of type T, given
// the buffer position and length. // the buffer position and length.
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public T[] ToArray<T>(int pos, int len) public T[] ToArray<T>(int pos, int len)
where T : struct where T : struct
{ {
@@ -257,7 +261,7 @@ namespace FlatBuffers
return ToArray<byte>(0, Length); return ToArray<byte>(0, Length);
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public ReadOnlyMemory<byte> ToReadOnlyMemory(int pos, int len) public ReadOnlyMemory<byte> ToReadOnlyMemory(int pos, int len)
{ {
return _buffer.ReadOnlyMemory.Slice(pos, len); return _buffer.ReadOnlyMemory.Slice(pos, len);
@@ -320,7 +324,7 @@ namespace FlatBuffers
((input & 0xFF00000000000000UL) >> 56)); ((input & 0xFF00000000000000UL) >> 56));
} }
#if !UNSAFE_BYTEBUFFER && !ENABLE_SPAN_T #if !UNSAFE_BYTEBUFFER && (!ENABLE_SPAN_T || !NETSTANDARD2_1)
// Helper functions for the safe (but slower) version. // Helper functions for the safe (but slower) version.
protected void WriteLittleEndian(int offset, int count, ulong data) protected void WriteLittleEndian(int offset, int count, ulong data)
{ {
@@ -399,7 +403,7 @@ namespace FlatBuffers
} }
return r; return r;
} }
#endif // !UNSAFE_BYTEBUFFER && !ENABLE_SPAN_T #endif
private void AssertOffsetAndLength(int offset, int length) private void AssertOffsetAndLength(int offset, int length)
{ {
@@ -410,7 +414,7 @@ namespace FlatBuffers
#endif #endif
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public void PutSbyte(int offset, sbyte value) public void PutSbyte(int offset, sbyte value)
{ {
@@ -458,7 +462,19 @@ namespace FlatBuffers
PutByte(offset, value); PutByte(offset, value);
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER
public unsafe void PutStringUTF8(int offset, string value)
{
AssertOffsetAndLength(offset, value.Length);
fixed (char* s = value)
{
fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.Span))
{
Encoding.UTF8.GetBytes(s, value.Length, buffer + offset, Length - offset);
}
}
}
#elif ENABLE_SPAN_T && NETSTANDARD2_1
public void PutStringUTF8(int offset, string value) public void PutStringUTF8(int offset, string value)
{ {
AssertOffsetAndLength(offset, value.Length); AssertOffsetAndLength(offset, value.Length);
@@ -484,7 +500,7 @@ namespace FlatBuffers
public unsafe void PutUshort(int offset, ushort value) public unsafe void PutUshort(int offset, ushort value)
{ {
AssertOffsetAndLength(offset, sizeof(ushort)); AssertOffsetAndLength(offset, sizeof(ushort));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
Span<byte> span = _buffer.Span.Slice(offset); Span<byte> span = _buffer.Span.Slice(offset);
BinaryPrimitives.WriteUInt16LittleEndian(span, value); BinaryPrimitives.WriteUInt16LittleEndian(span, value);
#else #else
@@ -505,7 +521,7 @@ namespace FlatBuffers
public unsafe void PutUint(int offset, uint value) public unsafe void PutUint(int offset, uint value)
{ {
AssertOffsetAndLength(offset, sizeof(uint)); AssertOffsetAndLength(offset, sizeof(uint));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
Span<byte> span = _buffer.Span.Slice(offset); Span<byte> span = _buffer.Span.Slice(offset);
BinaryPrimitives.WriteUInt32LittleEndian(span, value); BinaryPrimitives.WriteUInt32LittleEndian(span, value);
#else #else
@@ -526,7 +542,7 @@ namespace FlatBuffers
public unsafe void PutUlong(int offset, ulong value) public unsafe void PutUlong(int offset, ulong value)
{ {
AssertOffsetAndLength(offset, sizeof(ulong)); AssertOffsetAndLength(offset, sizeof(ulong));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
Span<byte> span = _buffer.Span.Slice(offset); Span<byte> span = _buffer.Span.Slice(offset);
BinaryPrimitives.WriteUInt64LittleEndian(span, value); BinaryPrimitives.WriteUInt64LittleEndian(span, value);
#else #else
@@ -542,7 +558,7 @@ namespace FlatBuffers
public unsafe void PutFloat(int offset, float value) public unsafe void PutFloat(int offset, float value)
{ {
AssertOffsetAndLength(offset, sizeof(float)); AssertOffsetAndLength(offset, sizeof(float));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span)) fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
#else #else
fixed (byte* ptr = _buffer.Buffer) fixed (byte* ptr = _buffer.Buffer)
@@ -562,7 +578,7 @@ namespace FlatBuffers
public unsafe void PutDouble(int offset, double value) public unsafe void PutDouble(int offset, double value)
{ {
AssertOffsetAndLength(offset, sizeof(double)); AssertOffsetAndLength(offset, sizeof(double));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span)) fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
#else #else
fixed (byte* ptr = _buffer.Buffer) fixed (byte* ptr = _buffer.Buffer)
@@ -635,7 +651,7 @@ namespace FlatBuffers
#endif // UNSAFE_BYTEBUFFER #endif // UNSAFE_BYTEBUFFER
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public sbyte GetSbyte(int index) public sbyte GetSbyte(int index)
{ {
AssertOffsetAndLength(index, sizeof(sbyte)); AssertOffsetAndLength(index, sizeof(sbyte));
@@ -661,7 +677,15 @@ namespace FlatBuffers
} }
#endif #endif
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER
public unsafe string GetStringUTF8(int startPos, int len)
{
fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan.Slice(startPos)))
{
return Encoding.UTF8.GetString(buffer, len);
}
}
#elif ENABLE_SPAN_T && NETSTANDARD2_1
public string GetStringUTF8(int startPos, int len) public string GetStringUTF8(int startPos, int len)
{ {
return Encoding.UTF8.GetString(_buffer.Span.Slice(startPos, len)); return Encoding.UTF8.GetString(_buffer.Span.Slice(startPos, len));
@@ -683,7 +707,7 @@ namespace FlatBuffers
public unsafe ushort GetUshort(int offset) public unsafe ushort GetUshort(int offset)
{ {
AssertOffsetAndLength(offset, sizeof(ushort)); AssertOffsetAndLength(offset, sizeof(ushort));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset); ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
return BinaryPrimitives.ReadUInt16LittleEndian(span); return BinaryPrimitives.ReadUInt16LittleEndian(span);
#else #else
@@ -704,7 +728,7 @@ namespace FlatBuffers
public unsafe uint GetUint(int offset) public unsafe uint GetUint(int offset)
{ {
AssertOffsetAndLength(offset, sizeof(uint)); AssertOffsetAndLength(offset, sizeof(uint));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset); ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
return BinaryPrimitives.ReadUInt32LittleEndian(span); return BinaryPrimitives.ReadUInt32LittleEndian(span);
#else #else
@@ -725,7 +749,7 @@ namespace FlatBuffers
public unsafe ulong GetUlong(int offset) public unsafe ulong GetUlong(int offset)
{ {
AssertOffsetAndLength(offset, sizeof(ulong)); AssertOffsetAndLength(offset, sizeof(ulong));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset); ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
return BinaryPrimitives.ReadUInt64LittleEndian(span); return BinaryPrimitives.ReadUInt64LittleEndian(span);
#else #else
@@ -741,7 +765,7 @@ namespace FlatBuffers
public unsafe float GetFloat(int offset) public unsafe float GetFloat(int offset)
{ {
AssertOffsetAndLength(offset, sizeof(float)); AssertOffsetAndLength(offset, sizeof(float));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan)) fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
#else #else
fixed (byte* ptr = _buffer.Buffer) fixed (byte* ptr = _buffer.Buffer)
@@ -762,7 +786,7 @@ namespace FlatBuffers
public unsafe double GetDouble(int offset) public unsafe double GetDouble(int offset)
{ {
AssertOffsetAndLength(offset, sizeof(double)); AssertOffsetAndLength(offset, sizeof(double));
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T // && UNSAFE_BYTEBUFFER
fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan)) fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
#else #else
fixed (byte* ptr = _buffer.Buffer) fixed (byte* ptr = _buffer.Buffer)
@@ -861,7 +885,7 @@ namespace FlatBuffers
offset -= numBytes; offset -= numBytes;
AssertOffsetAndLength(offset, numBytes); AssertOffsetAndLength(offset, numBytes);
// if we are LE, just do a block copy // if we are LE, just do a block copy
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes)); MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
#else #else
Buffer.BlockCopy(x, 0, _buffer.Buffer, offset, numBytes); Buffer.BlockCopy(x, 0, _buffer.Buffer, offset, numBytes);
@@ -880,7 +904,7 @@ namespace FlatBuffers
return offset; return offset;
} }
#if ENABLE_SPAN_T && NETSTANDARD2_1 #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
public int Put<T>(int offset, Span<T> x) public int Put<T>(int offset, Span<T> x)
where T : struct where T : struct
{ {

View File

@@ -206,7 +206,7 @@ namespace FlatBuffers
_space = _bb.Put(_space, x); _space = _bb.Put(_space, x);
} }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
/// <summary> /// <summary>
/// Puts a span of type T into this builder at the /// Puts a span of type T into this builder at the
/// current offset /// current offset
@@ -317,7 +317,7 @@ namespace FlatBuffers
Put(x); Put(x);
} }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
/// <summary> /// <summary>
/// Add a span of type T to the buffer (aligns the data and grows if necessary). /// Add a span of type T to the buffer (aligns the data and grows if necessary).
/// </summary> /// </summary>
@@ -567,7 +567,7 @@ namespace FlatBuffers
} }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
/// <summary> /// <summary>
/// Creates a string in the buffer from a Span containing /// Creates a string in the buffer from a Span containing
/// a UTF8 string. /// a UTF8 string.

View File

@@ -86,7 +86,7 @@ namespace FlatBuffers
return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length
} }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
// Get the data of a vector whoses offset is stored at "offset" in this object as an // Get the data of a vector whoses offset is stored at "offset" in this object as an
// Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer, // Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer,
// then an empty span will be returned. // then an empty span will be returned.