diff --git a/net/FlatBuffers/ByteBuffer.cs b/net/FlatBuffers/ByteBuffer.cs index 5040d3463..0e959aec9 100644 --- a/net/FlatBuffers/ByteBuffer.cs +++ b/net/FlatBuffers/ByteBuffer.cs @@ -275,6 +275,11 @@ namespace Google.FlatBuffers } #if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER + public ReadOnlySpan ToSizedReadOnlySpan() + { + return _buffer.ReadOnlySpan.Slice(Position, Length - Position); + } + public ReadOnlyMemory ToReadOnlyMemory(int pos, int len) { return _buffer.ReadOnlyMemory.Slice(pos, len); @@ -289,6 +294,11 @@ namespace Google.FlatBuffers { return _buffer.Span.Slice(pos, len); } + + public ReadOnlySpan ToReadOnlySpan(int pos, int len) + { + return _buffer.ReadOnlySpan.Slice(pos, len); + } #else public ArraySegment ToArraySegment(int pos, int len) { @@ -380,18 +390,19 @@ namespace Google.FlatBuffers #elif ENABLE_SPAN_T protected void WriteLittleEndian(int offset, int count, ulong data) { + Span span = _buffer.Span.Slice(offset, count); if (BitConverter.IsLittleEndian) { for (int i = 0; i < count; i++) { - _buffer.Span[offset + i] = (byte)(data >> i * 8); + span[i] = (byte)(data >> i * 8); } } else { for (int i = 0; i < count; i++) { - _buffer.Span[offset + count - 1 - i] = (byte)(data >> i * 8); + span[count - 1 - i] = (byte)(data >> i * 8); } } } @@ -399,19 +410,20 @@ namespace Google.FlatBuffers protected ulong ReadLittleEndian(int offset, int count) { AssertOffsetAndLength(offset, count); + ReadOnlySpan span = _buffer.ReadOnlySpan.Slice(offset, count); ulong r = 0; if (BitConverter.IsLittleEndian) { for (int i = 0; i < count; i++) { - r |= (ulong)_buffer.Span[offset + i] << i * 8; + r |= (ulong)span[i] << i * 8; } } else { for (int i = 0; i < count; i++) { - r |= (ulong)_buffer.Span[offset + count - 1 - i] << i * 8; + r |= (ulong)span[count - 1 - i] << i * 8; } } return r; @@ -445,8 +457,7 @@ namespace Google.FlatBuffers { AssertOffsetAndLength(offset, sizeof(byte) * count); Span span = _buffer.Span.Slice(offset, count); - for (var i = 0; i < span.Length; ++i) - span[i] = value; + span.Fill(value); } #else public void PutSbyte(int offset, sbyte value) diff --git a/net/FlatBuffers/FlatBufferBuilder.cs b/net/FlatBuffers/FlatBufferBuilder.cs index afe168352..3932f4bc3 100644 --- a/net/FlatBuffers/FlatBufferBuilder.cs +++ b/net/FlatBuffers/FlatBufferBuilder.cs @@ -957,6 +957,21 @@ namespace Google.FlatBuffers return _bb.ToSizedArray(); } +#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER + /// + /// A utility function return the ByteBuffer data as a + /// `ReadOnlySpan`. + /// + /// + /// A `ReadOnlySpan` that references the internal + /// ByteBuffer data. + /// + public ReadOnlySpan SizedReadOnlySpan() + { + return _bb.ToSizedReadOnlySpan(); + } +#endif + /// /// Finalize a buffer, pointing to the given `rootTable`. /// diff --git a/net/FlatBuffers/Table.cs b/net/FlatBuffers/Table.cs index f3860bfea..d6d9d09fb 100644 --- a/net/FlatBuffers/Table.cs +++ b/net/FlatBuffers/Table.cs @@ -183,6 +183,12 @@ namespace Google.FlatBuffers var len_2 = bb.GetInt(offset_2); var startPos_1 = offset_1 + sizeof(int); var startPos_2 = offset_2 + sizeof(int); + +#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER + var span_1 = bb.ToReadOnlySpan(startPos_1, len_1); + var span_2 = bb.ToReadOnlySpan(startPos_2, len_2); + return span_1.SequenceCompareTo(span_2); +#else var len = Math.Min(len_1, len_2); for(int i = 0; i < len; i++) { byte b1 = bb.Get(i + startPos_1); @@ -191,6 +197,7 @@ namespace Google.FlatBuffers return b1 - b2; } return len_1 - len_2; +#endif } // Compare string from the ByteBuffer with the string object @@ -200,6 +207,11 @@ namespace Google.FlatBuffers var len_1 = bb.GetInt(offset_1); var len_2 = key.Length; var startPos_1 = offset_1 + sizeof(int); +#if ENABLE_SPAN_T && UNSAFE_BYTEBUFFER + ReadOnlySpan span = bb.ToReadOnlySpan(startPos_1, len_1); + ReadOnlySpan keySpan = key; + return span.SequenceCompareTo(keySpan); +#else var len = Math.Min(len_1, len_2); for (int i = 0; i < len; i++) { byte b = bb.Get(i + startPos_1); @@ -207,6 +219,7 @@ namespace Google.FlatBuffers return b - key[i]; } return len_1 - len_2; +#endif } } }