Correct span and non-span versions of ToArray() and ToArrayPadded() methods (#8734)

* Correction of bug inside ToArray<T> methods

Avoid allocating too large buffers (len is expressed in bytes, not in Ts).
Added validation to ensure len is a multiple of SizeOf<T>() before converting to array.

* Update ByteBuffer.cs

* Refactor ToArray and ToArrayPadded methods

I understand from failed test that pos, len, padLeft and padRight are expressed in Ts

* Refactor ToArray and ToArrayPadded methods

* Final correction
All functions parameters expressed in bytes for homogeneity
Tests run:
  - UNSAFE_BYTEBUFFER=true/ENABLE_SPAN_T=true: passed
  - UNSAFE_BYTEBUFFER=true/ENABLE_SPAN_T=false: passed
  - UNSAFE_BYTEBUFFER=false/ENABLE_SPAN_T=false: passed
  - UNSAFE_BYTEBUFFER=false/ENABLE_SPAN_T=true: configuration forbidden by compilation
Correction of FlatBuffers.Test.csproj to allow UNSAFE_BYTEBUFFER/ENABLE_SPAN_T tests
Correction of FlatBuffersExampleTests.cs: I think the test was not run because it could not pass (to be reviewed carefully)
This commit is contained in:
vsmcea
2025-10-25 20:58:05 +02:00
committed by GitHub
parent 27325e002a
commit 95053e6a47
4 changed files with 69 additions and 46 deletions

View File

@@ -15,6 +15,7 @@
*/
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace Google.FlatBuffers.Test
@@ -363,34 +364,32 @@ namespace Google.FlatBuffers.Test
fData[7] = 15.9994F;
fData[8] = 18.9984F;
var sizeInBytes = ByteBuffer.ConvertTsToBytes<float>(fData.Length);
// Tranfer it to a byte array
var buffer = new byte[sizeof(float) * fData.Length];
var buffer = new byte[sizeInBytes];
Buffer.BlockCopy(fData, 0, buffer, 0, buffer.Length);
// Create the Byte Buffer from byte array
var uut = new ByteBuffer(buffer);
// Get the full array back out and ensure they are equivalent
var bbArray = uut.ToArray<float>(0, len);
var bbArray = uut.ToArray<float>(0, sizeInBytes);
Assert.ArrayEqual(fData, bbArray);
// Get a portion of the full array back out and ensure the
// subrange agrees
var bbArray2 = uut.ToArray<float>(4, len - 1);
Assert.AreEqual(bbArray2.Length, len - 1);
for (int i = 1; i < len - 1; i++)
{
Assert.AreEqual(fData[i], bbArray2[i - 1]);
}
var posInFloats = 4;
var lenInFloats = Math.Min(fData.Length - posInFloats - 1, 4);
var bbArray2 = uut.ToArray<float>(ByteBuffer.ConvertTsToBytes<float>(posInFloats), ByteBuffer.ConvertTsToBytes<float>(lenInFloats));
Assert.ArrayEqual(fData.Skip(posInFloats).Take(bbArray2.Length).ToArray(), bbArray2);
// Get a sub portion of the full array back out and ensure the
// subrange agrees
var bbArray3 = uut.ToArray<float>(8, len - 4);
Assert.AreEqual(bbArray3.Length, len - 4);
for (int i = 2; i < len - 4; i++)
{
Assert.AreEqual(fData[i], bbArray3[i - 2]);
}
posInFloats = 6;
lenInFloats = Math.Min(fData.Length - posInFloats - 1, 1);
var bbArray3 = uut.ToArray<float>(ByteBuffer.ConvertTsToBytes<float>(posInFloats), ByteBuffer.ConvertTsToBytes<float>(lenInFloats));
Assert.ArrayEqual(fData.Skip(posInFloats).Take(bbArray3.Length).ToArray(), bbArray3);
}
public void ByteBuffer_Put_Array_Helper<T>(T[] data, int typeSize)
@@ -405,7 +404,7 @@ namespace Google.FlatBuffers.Test
Assert.AreEqual(1024 - typeSize * data.Length, nOffset);
// Get the full array back out and ensure they are equivalent
var bbArray = uut.ToArray<T>(nOffset, data.Length);
var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Length));
Assert.ArrayEqual(data, bbArray);
}
@@ -421,7 +420,7 @@ namespace Google.FlatBuffers.Test
Assert.AreEqual(1024 - typeSize * data.Count, nOffset);
// Get the full array back out and ensure they are equivalent
var bbArray = uut.ToArray<T>(nOffset, data.Count);
var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Count));
Assert.ArrayEqual(data, bbArray);
}
@@ -443,7 +442,7 @@ namespace Google.FlatBuffers.Test
Assert.AreEqual(1024 - sizeInBytes, nOffset);
// Get the full array back out and ensure they are equivalent
var bbArray = uut.ToArray<T>(nOffset, data.Length);
var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Length));
Assert.ArrayEqual(data, bbArray);
}
finally

View File

@@ -9,12 +9,12 @@
<Compile Remove="Properties\AssemblyInfo.cs" />
</ItemGroup>
<PropertyGroup Condition="'$(UnsafeByteBuffer)' == 'true'">
<PropertyGroup Condition="'$(UNSAFE_BYTEBUFFER)' == 'true'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(EnableSpanT)' == 'true'">
<PropertyGroup Condition="'$(ENABLE_SPAN_T)' == 'true'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);ENABLE_SPAN_T</DefineConstants>
</PropertyGroup>

View File

@@ -268,10 +268,10 @@ namespace Google.FlatBuffers.Test
}
var longArrayBytes = monster.GetVectorOfLongsBytes();
Assert.IsTrue(monster.VectorOfLongsLength * 8 == longArrayBytes.Length);
Assert.IsTrue(monster.VectorOfLongsLength == longArrayBytes.Length);
var doubleArrayBytes = monster.GetVectorOfDoublesBytes();
Assert.IsTrue(monster.VectorOfDoublesLength * 8 == doubleArrayBytes.Length);
Assert.IsTrue(monster.VectorOfDoublesLength == doubleArrayBytes.Length);
#else
var nameBytes = monster.GetNameBytes().Value;
Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));