summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Bailey <derek.bailey@thermofisher.com>2018-07-26 13:44:40 -0700
committerWouter van Oortmerssen <aardappel@gmail.com>2018-07-26 13:44:40 -0700
commit7b50004ec9a1b86db2b1b61a9906e52227f62b35 (patch)
tree97ac7c68e8dadf76252c674e95509f8233ada9f6
parent6e185d06a72272130047cb4fcddf5b751e76fca0 (diff)
downloadflatbuffers-7b50004ec9a1b86db2b1b61a9906e52227f62b35.tar.gz
flatbuffers-7b50004ec9a1b86db2b1b61a9906e52227f62b35.tar.bz2
flatbuffers-7b50004ec9a1b86db2b1b61a9906e52227f62b35.zip
Performance Increase of Vector of Structures using .NET BlockCopy (#4830)
* Added Get<vector_name>Array() method for accessing vectors of structures in C# using Buffer.Blockcopy(). * Added Get<vector_name>Array() method for accessing vectors of structures in C# using Buffer.Blockcopy(). Added Create<Name>VectorBlock() method to add a typed array using Buffer.BlockCopy() to speed up creation of vector of arrays New Lua files for namespace test * fixed c++ style issue
-rw-r--r--net/FlatBuffers/ByteBuffer.cs118
-rw-r--r--net/FlatBuffers/FlatBufferBuilder.cs43
-rw-r--r--net/FlatBuffers/Table.cs23
-rw-r--r--src/idl_gen_general.cpp25
-rw-r--r--tests/FlatBuffers.Test/ByteBufferTests.cs268
-rw-r--r--tests/FlatBuffers.Test/FlatBufferBuilderTests.cs105
-rw-r--r--tests/FlatBuffers.Test/FlatBuffersExampleTests.cs10
-rw-r--r--tests/MyGame/Example/Monster.cs24
-rw-r--r--tests/MyGame/Example/Stat.cs1
-rw-r--r--tests/MyGame/Example/TypeAliases.cs4
-rw-r--r--tests/monster_test.bfbsbin6352 -> 6432 bytes
-rw-r--r--tests/namespace_test/namespace_test2_generated.ts20
12 files changed, 625 insertions, 16 deletions
diff --git a/net/FlatBuffers/ByteBuffer.cs b/net/FlatBuffers/ByteBuffer.cs
index 878e740b..307a98fa 100644
--- a/net/FlatBuffers/ByteBuffer.cs
+++ b/net/FlatBuffers/ByteBuffer.cs
@@ -30,6 +30,7 @@
//
using System;
+using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -91,19 +92,78 @@ namespace FlatBuffers
public byte[] ToArray(int pos, int len)
{
- byte[] arr = new byte[len];
- Buffer.BlockCopy(_buffer, pos, arr, 0, len);
+ return ToArray<byte>(pos, len);
+ }
+
+ /// <summary>
+ /// A lookup of type sizes. Used instead of Marshal.SizeOf() which has additional
+ /// overhead, but also is compatible with generic functions for simplified code.
+ /// </summary>
+ private static Dictionary<Type, int> genericSizes = new Dictionary<Type, int>()
+ {
+ { typeof(bool), sizeof(bool) },
+ { typeof(float), sizeof(float) },
+ { typeof(double), sizeof(double) },
+ { typeof(sbyte), sizeof(sbyte) },
+ { typeof(byte), sizeof(byte) },
+ { typeof(short), sizeof(short) },
+ { typeof(ushort), sizeof(ushort) },
+ { typeof(int), sizeof(int) },
+ { typeof(uint), sizeof(uint) },
+ { typeof(ulong), sizeof(ulong) },
+ { typeof(long), sizeof(long) },
+ };
+
+ /// <summary>
+ /// Get the wire-size (in bytes) of a type supported by flatbuffers.
+ /// </summary>
+ /// <param name="t">The type to get the wire size of</param>
+ /// <returns></returns>
+ public static int SizeOf<T>()
+ {
+ return genericSizes[typeof(T)];
+ }
+
+ /// <summary>
+ /// Checks if the Type provided is supported as scalar value
+ /// </summary>
+ /// <typeparam name="T">The Type to check</typeparam>
+ /// <returns>True if the type is a scalar type that is supported, falsed otherwise</returns>
+ public static bool IsSupportedType<T>()
+ {
+ return genericSizes.ContainsKey(typeof(T));
+ }
+
+ /// <summary>
+ /// Get the wire-size (in bytes) of an typed array
+ /// </summary>
+ /// <typeparam name="T">The type of the array</typeparam>
+ /// <param name="x">The array to get the size of</param>
+ /// <returns>The number of bytes the array takes on wire</returns>
+ public static int ArraySize<T>(T[] x)
+ {
+ return SizeOf<T>() * x.Length;
+ }
+
+ // Get a portion of the buffer casted into an array of type T, given
+ // the buffer position and length.
+ public T[] ToArray<T>(int pos, int len)
+ where T: struct
+ {
+ AssertOffsetAndLength(pos, len);
+ T[] arr = new T[len];
+ Buffer.BlockCopy(_buffer, pos, arr, 0, ArraySize(arr));
return arr;
}
public byte[] ToSizedArray()
{
- return ToArray(Position, Length - Position);
+ return ToArray<byte>(Position, Length - Position);
}
public byte[] ToFullArray()
{
- return ToArray(0, Length);
+ return ToArray<byte>(0, Length);
}
public ArraySegment<byte> ToArraySegment(int pos, int len)
@@ -368,6 +428,56 @@ namespace FlatBuffers
WriteLittleEndian(offset, sizeof(double), ulonghelper[0]);
}
+ /// <summary>
+ /// Copies an array of type T into this buffer, ending at the given
+ /// offset into this buffer. The starting offset is calculated based on the length
+ /// of the array and is the value returned.
+ /// </summary>
+ /// <typeparam name="T">The type of the input data (must be a struct)</typeparam>
+ /// <param name="offset">The offset into this buffer where the copy will end</param>
+ /// <param name="x">The array to copy data from</param>
+ /// <returns>The 'start' location of this buffer now, after the copy completed</returns>
+ public int Put<T>(int offset, T[] x)
+ where T : struct
+ {
+ if(x == null)
+ {
+ throw new ArgumentNullException("Cannot put a null array");
+ }
+
+ if(x.Length == 0)
+ {
+ throw new ArgumentException("Cannot put an empty array");
+ }
+
+ if(!IsSupportedType<T>())
+ {
+ throw new ArgumentException("Cannot put an array of type "
+ + typeof(T) + " into this buffer");
+ }
+
+ if (BitConverter.IsLittleEndian)
+ {
+ int numBytes = ByteBuffer.ArraySize(x);
+ offset -= numBytes;
+ AssertOffsetAndLength(offset, numBytes);
+ // if we are LE, just do a block copy
+ Buffer.BlockCopy(x, 0, _buffer, offset, numBytes);
+ }
+ else
+ {
+ throw new NotImplementedException("Big Endian Support not implemented yet " +
+ "for putting typed arrays");
+ // if we are BE, we have to swap each element by itself
+ //for(int i = x.Length - 1; i >= 0; i--)
+ //{
+ // todo: low priority, but need to genericize the Put<T>() functions
+ //}
+ }
+ return offset;
+ }
+
+
#endif // UNSAFE_BYTEBUFFER
public sbyte GetSbyte(int index)
diff --git a/net/FlatBuffers/FlatBufferBuilder.cs b/net/FlatBuffers/FlatBufferBuilder.cs
index a2224498..33bba969 100644
--- a/net/FlatBuffers/FlatBufferBuilder.cs
+++ b/net/FlatBuffers/FlatBufferBuilder.cs
@@ -179,6 +179,18 @@ namespace FlatBuffers
_bb.PutFloat(_space -= sizeof(float), x);
}
+ /// <summary>
+ /// Puts an array of type T into this builder at the
+ /// current offset
+ /// </summary>
+ /// <typeparam name="T">The type of the input data </typeparam>
+ /// <param name="x">The array to copy data from</param>
+ public void Put<T>(T[] x)
+ where T : struct
+ {
+ _space = _bb.Put(_space, x);
+ }
+
public void PutDouble(double x)
{
_bb.PutDouble(_space -= sizeof(double), x);
@@ -246,6 +258,37 @@ namespace FlatBuffers
public void AddFloat(float x) { Prep(sizeof(float), 0); PutFloat(x); }
/// <summary>
+ /// Add an array of type T to the buffer (aligns the data and grows if necessary).
+ /// </summary>
+ /// <typeparam name="T">The type of the input data</typeparam>
+ /// <param name="x">The array to copy data from</param>
+ public void Add<T>(T[] x)
+ where T : struct
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("Cannot add a null array");
+ }
+
+ if( x.Length == 0)
+ {
+ // don't do anything if the array is empty
+ return;
+ }
+
+ if(!ByteBuffer.IsSupportedType<T>())
+ {
+ throw new ArgumentException("Cannot add this Type array to the builder");
+ }
+
+ int size = ByteBuffer.SizeOf<T>();
+ // Need to prep on size (for data alignment) and then we pass the
+ // rest of the length (minus 1) as additional bytes
+ Prep(size, size * (x.Length - 1));
+ Put(x);
+ }
+
+ /// <summary>
/// Add a `double` to the buffer (aligns the data and grows if necessary).
/// </summary>
/// <param name="x">The `double` to add to the buffer.</param>
diff --git a/net/FlatBuffers/Table.cs b/net/FlatBuffers/Table.cs
index 4a188ff8..07db5f42 100644
--- a/net/FlatBuffers/Table.cs
+++ b/net/FlatBuffers/Table.cs
@@ -94,6 +94,29 @@ namespace FlatBuffers
return bb.ToArraySegment(pos, len);
}
+ // Get the data of a vector whoses offset is stored at "offset" in this object as an
+ // T[]. If the vector is not present in the ByteBuffer, then a null value will be
+ // returned.
+ public T[] __vector_as_array<T>(int offset)
+ where T : struct
+ {
+ if(!BitConverter.IsLittleEndian)
+ {
+ throw new NotSupportedException("Getting typed arrays on a Big Endian " +
+ "system is not support");
+ }
+
+ var o = this.__offset(offset);
+ if (0 == o)
+ {
+ return null;
+ }
+
+ var pos = this.__vector(o);
+ var len = this.__vector_len(o);
+ return bb.ToArray<T>(pos, len);
+ }
+
// Initialize any Table-derived type to point to the union at the given offset.
public T __union<T>(int offset) where T : struct, IFlatbufferObject
{
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
index d3cc79b2..27eb8c40 100644
--- a/src/idl_gen_general.cpp
+++ b/src/idl_gen_general.cpp
@@ -1102,6 +1102,18 @@ class GeneralGenerator : public BaseGenerator {
code += lang_.accessor_prefix + "__vector_as_arraysegment(";
code += NumToString(field.value.offset);
code += "); }\n";
+
+ // For direct blockcopying the data into a typed array
+ code += " public ";
+ code += GenTypeBasic(field.value.type.VectorType());
+ code += "[] Get";
+ code += MakeCamel(field.name, lang_.first_camel_upper);
+ code += "Array() { return ";
+ code += lang_.accessor_prefix + "__vector_as_array<";
+ code += GenTypeBasic(field.value.type.VectorType());
+ code += ">(";
+ code += NumToString(field.value.offset);
+ code += "); }\n";
break;
default: break;
}
@@ -1324,6 +1336,19 @@ class GeneralGenerator : public BaseGenerator {
code += ".Value";
code += "); return ";
code += "builder." + FunctionStart('E') + "ndVector(); }\n";
+ // For C#, include a block copy method signature.
+ if (lang_.language == IDLOptions::kCSharp) {
+ code += " public static " + GenVectorOffsetType() + " ";
+ code += FunctionStart('C') + "reate";
+ code += MakeCamel(field.name);
+ code += "VectorBlock(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(vector_type) + "[] data) ";
+ code += "{ builder." + FunctionStart('S') + "tartVector(";
+ code += NumToString(elem_size);
+ code += ", data." + FunctionStart('L') + "ength, ";
+ code += NumToString(alignment);
+ code += "); builder.Add(data); return builder.EndVector(); }\n";
+ }
}
// Generate a method to start a vector, data to be added manually
// after.
diff --git a/tests/FlatBuffers.Test/ByteBufferTests.cs b/tests/FlatBuffers.Test/ByteBufferTests.cs
index 58bd71e5..1c33a2f5 100644
--- a/tests/FlatBuffers.Test/ByteBufferTests.cs
+++ b/tests/FlatBuffers.Test/ByteBufferTests.cs
@@ -100,7 +100,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(0x0A, buffer[3]);
}
- #if !BYTEBUFFER_NO_BOUNDS_CHECK
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
[FlatBuffersTestMethod]
public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
{
@@ -178,7 +178,7 @@ namespace FlatBuffers.Test
public void ByteBuffer_GetByteChecksOffset()
{
var uut = new ByteBuffer(1);
- Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
+ Assert.Throws<ArgumentOutOfRangeException>(() => uut.Get(1));
}
#endif
@@ -344,5 +344,269 @@ namespace FlatBuffers.Test
uut.Position = 1; uut = uut.Duplicate();
Assert.AreEqual(0x0A, uut.Get(3));
}
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_To_Array_Float()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var fData = new float[len];
+ fData[0] = 1.0079F;
+ fData[1] = 4.0026F;
+ fData[2] = 6.941F;
+ fData[3] = 9.0122F;
+ fData[4] = 10.811F;
+ fData[5] = 12.0107F;
+ fData[6] = 14.0067F;
+ fData[7] = 15.9994F;
+ fData[8] = 18.9984F;
+
+ // Tranfer it to a byte array
+ var buffer = new byte[sizeof(float) * fData.Length];
+ 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);
+ 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]);
+ }
+
+ // 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]);
+ }
+ }
+
+ public void ByteBuffer_Put_Array_Helper<T>(T[] data, int typeSize)
+ where T : struct
+ {
+ // Create the Byte Buffer
+ var uut = new ByteBuffer(1024);
+
+ // Put the data into the buffer and make sure the offset is
+ // calculated correctly
+ int nOffset = uut.Put(1024, data);
+ 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);
+ Assert.ArrayEqual(data, bbArray);
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Float()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new float[len];
+ data[0] = 1.0079F;
+ data[1] = 4.0026F;
+ data[2] = 6.941F;
+ data[3] = 9.0122F;
+ data[4] = 10.811F;
+ data[5] = 12.0107F;
+ data[6] = 14.0067F;
+ data[7] = 15.9994F;
+ data[8] = 18.9984F;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(float));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Double()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new double[len];
+ data[0] = 1.0079;
+ data[1] = 4.0026;
+ data[2] = 6.941;
+ data[3] = 9.0122;
+ data[4] = 10.811;
+ data[5] = 12.0107;
+ data[6] = 14.0067;
+ data[7] = 15.9994;
+ data[8] = 18.9984;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(double));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Int()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new int[len];
+ data[0] = 1;
+ data[1] = 4;
+ data[2] = 6;
+ data[3] = 9;
+ data[4] = 10;
+ data[5] = 12;
+ data[6] = 14;
+ data[7] = 15;
+ data[8] = 18;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(int));
+ }
+
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_UInt()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new uint[len];
+ data[0] = 1;
+ data[1] = 4;
+ data[2] = 6;
+ data[3] = 9;
+ data[4] = 10;
+ data[5] = 12;
+ data[6] = 14;
+ data[7] = 15;
+ data[8] = 18;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(uint));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Bool()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new bool[len];
+ data[0] = true;
+ data[1] = true;
+ data[2] = false;
+ data[3] = true;
+ data[4] = false;
+ data[5] = true;
+ data[6] = true;
+ data[7] = true;
+ data[8] = false;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(bool));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Long()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new long[len];
+ data[0] = 1;
+ data[1] = 4;
+ data[2] = 6;
+ data[3] = 9;
+ data[4] = 10;
+ data[5] = 12;
+ data[6] = 14;
+ data[7] = 15;
+ data[8] = 18;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(long));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Byte()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new byte[len];
+ data[0] = 1;
+ data[1] = 4;
+ data[2] = 6;
+ data[3] = 9;
+ data[4] = 10;
+ data[5] = 12;
+ data[6] = 14;
+ data[7] = 15;
+ data[8] = 18;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(byte));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_SByte()
+ {
+ const int len = 9;
+
+ // Construct the data array
+ var data = new sbyte[len];
+ data[0] = 1;
+ data[1] = 4;
+ data[2] = 6;
+ data[3] = 9;
+ data[4] = 10;
+ data[5] = 12;
+ data[6] = 14;
+ data[7] = 15;
+ data[8] = 18;
+
+ ByteBuffer_Put_Array_Helper(data, sizeof(sbyte));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Null_Throws()
+ {
+ // Create the Byte Buffer
+ var uut = new ByteBuffer(1024);
+
+ // create a null array and try to put it into the buffer
+ float[] data = null;
+ Assert.Throws<ArgumentNullException>(() => uut.Put(1024, data));
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_Empty_Throws()
+ {
+ // Create the Byte Buffer
+ var uut = new ByteBuffer(1024);
+
+ // create an array of length == 0, and try to put it into the buffer
+ float[] data = new float[0];
+ Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+ }
+
+ private struct dummyStruct
+ {
+ int a;
+ float b;
+ }
+
+ [FlatBuffersTestMethod]
+ public void ByteBuffer_Put_Array_IncorrectType_Throws()
+ {
+ // Create the Byte Buffer
+ var uut = new ByteBuffer(1024);
+
+ // Create an array of dummy structures that shouldn't be
+ // able to be put into the buffer
+ var data = new dummyStruct[10];
+ Assert.Throws<ArgumentException>(() => uut.Put(1024, data));
+ }
}
}
diff --git a/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
index f02df445..4ddd9a8c 100644
--- a/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
+++ b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+using System;
+
namespace FlatBuffers.Test
{
[FlatBuffersTestClass]
@@ -245,5 +247,108 @@ namespace FlatBuffers.Test
var endOffset = fbb.Offset;
Assert.AreEqual(endOffset, storedOffset);
}
+
+ [FlatBuffersTestMethod]
+ public void FlatBufferBuilder_Add_Array_Float()
+ {
+ var fbb = CreateBuffer(false);
+ var storedOffset = fbb.Offset;
+
+ const int len = 9;
+
+ // Construct the data array
+ var data = new float[len];
+ data[0] = 1.0079F;
+ data[1] = 4.0026F;
+ data[2] = 6.941F;
+ data[3] = 9.0122F;
+ data[4] = 10.811F;
+ data[5] = 12.0107F;
+ data[6] = 14.0067F;
+ data[7] = 15.9994F;
+ data[8] = 18.9984F;
+
+ fbb.Add(data);
+ var endOffset = fbb.Offset;
+ Assert.AreEqual(endOffset, storedOffset + sizeof(float) * data.Length);
+ }
+
+ [FlatBuffersTestMethod]
+ public void FlatBufferBuilder_Add_Array_Bool()
+ {
+ var fbb = CreateBuffer(false);
+ var storedOffset = fbb.Offset;
+
+ const int len = 9;
+
+ // Construct the data array
+ var data = new bool[len];
+ data[0] = true;
+ data[1] = true;
+ data[2] = false;
+ data[3] = true;
+ data[4] = false;
+ data[5] = true;
+ data[6] = true;
+ data[7] = true;
+ data[8] = false;
+
+ fbb.Add(data);
+ var endOffset = fbb.Offset;
+ Assert.AreEqual(endOffset, storedOffset + sizeof(bool) * data.Length);
+ }
+
+ [FlatBuffersTestMethod]
+ public void FlatBufferBuilder_Add_Array_Double()
+ {
+ var fbb = CreateBuffer(false);
+ var storedOffset = fbb.Offset;
+
+ const int len = 9;
+
+ // Construct the data array
+ var data = new double[len];
+ data[0] = 1.0079;
+ data[1] = 4.0026;
+ data[2] = 6.941;
+ data[3] = 9.0122;
+ data[4] = 10.811;
+ data[5] = 12.0107;
+ data[6] = 14.0067;
+ data[7] = 15.9994;
+ data[8] = 18.9984;
+
+ fbb.Add(data);
+ var endOffset = fbb.Offset;
+ Assert.AreEqual(endOffset, storedOffset + sizeof(double) * data.Length);
+ }
+
+ [FlatBuffersTestMethod]
+ public void FlatBufferBuilder_Add_Array_Null_Throws()
+ {
+ var fbb = CreateBuffer(false);
+
+ // Construct the data array
+ float[] data = null;
+
+ Assert.Throws<ArgumentNullException>(() => fbb.Add(data));
+ }
+
+ [FlatBuffersTestMethod]
+ public void FlatBufferBuilder_Add_Array_Empty_Noop()
+ {
+ var fbb = CreateBuffer(false);
+
+ var storedOffset = fbb.Offset;
+
+ // Construct an empty data array
+ float[] data = new float[0];
+ fbb.Add(data);
+
+ // Make sure the offset didn't change since nothing
+ // was really added
+ var endOffset = fbb.Offset;
+ Assert.AreEqual(endOffset, storedOffset);
+ }
}
}
diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
index 82d4fdf2..d438e0e4 100644
--- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
+++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
@@ -221,6 +221,16 @@ namespace FlatBuffers.Test
}
Assert.AreEqual(10, invsum);
+ // Get the inventory as an array and subtract the
+ // sum to get it back to 0
+ var inventoryArray = monster.GetInventoryArray();
+ Assert.AreEqual(5, inventoryArray.Length);
+ foreach(var inv in inventoryArray)
+ {
+ invsum -= inv;
+ }
+ Assert.AreEqual(0, invsum);
+
var test0 = monster.Test4(0).Value;
var test1 = monster.Test4(1).Value;
Assert.AreEqual(2, monster.Test4Length);
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs
index b7844fb3..b3109e95 100644
--- a/tests/MyGame/Example/Monster.cs
+++ b/tests/MyGame/Example/Monster.cs
@@ -26,9 +26,11 @@ public struct Monster : IFlatbufferObject
public bool MutateHp(short hp) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, hp); return true; } else { return false; } }
public string Name { get { int o = __p.__offset(10); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
+ public byte[] GetNameArray() { return __p.__vector_as_array<byte>(10); }
public byte Inventory(int j) { int o = __p.__offset(14); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
public int InventoryLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
+ public byte[] GetInventoryArray() { return __p.__vector_as_array<byte>(14); }
public bool MutateInventory(int j, byte inventory) { int o = __p.__offset(14); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, inventory); return true; } else { return false; } }
public Color Color { get { int o = __p.__offset(16); return o != 0 ? (Color)__p.bb.GetSbyte(o + __p.bb_pos) : Color.Blue; } }
public bool MutateColor(Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)color); return true; } else { return false; } }
@@ -48,6 +50,7 @@ public struct Monster : IFlatbufferObject
public byte Testnestedflatbuffer(int j) { int o = __p.__offset(30); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
public int TestnestedflatbufferLength { get { int o = __p.__offset(30); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
+ public byte[] GetTestnestedflatbufferArray() { return __p.__vector_as_array<byte>(30); }
public Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __p.__offset(30); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
public Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (Stat?)(new Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
@@ -72,6 +75,7 @@ public struct Monster : IFlatbufferObject
public bool Testarrayofbools(int j) { int o = __p.__offset(52); return o != 0 ? 0!=__p.bb.Get(__p.__vector(o) + j * 1) : false; }
public int TestarrayofboolsLength { get { int o = __p.__offset(52); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
+ public bool[] GetTestarrayofboolsArray() { return __p.__vector_as_array<bool>(52); }
public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __p.__offset(52); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
public float Testf { get { int o = __p.__offset(54); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.14159f; } }
public bool MutateTestf(float testf) { int o = __p.__offset(54); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf); return true; } else { return false; } }
@@ -86,16 +90,19 @@ public struct Monster : IFlatbufferObject
public byte Flex(int j) { int o = __p.__offset(64); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
+ public byte[] GetFlexArray() { return __p.__vector_as_array<byte>(64); }
public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
public Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (Test?)(new Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
public int Test5Length { get { int o = __p.__offset(66); return o != 0 ? __p.__vector_len(o) : 0; } }
public long VectorOfLongs(int j) { int o = __p.__offset(68); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
public int VectorOfLongsLength { get { int o = __p.__offset(68); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
+ public long[] GetVectorOfLongsArray() { return __p.__vector_as_array<long>(68); }
public bool MutateVectorOfLongs(int j, long vector_of_longs) { int o = __p.__offset(68); if (o != 0) { __p.bb.PutLong(__p.__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
public double VectorOfDoubles(int j) { int o = __p.__offset(70); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
public int VectorOfDoublesLength { get { int o = __p.__offset(70); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
+ public double[] GetVectorOfDoublesArray() { return __p.__vector_as_array<double>(70); }
public bool MutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __p.__offset(70); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
public MyGame.InParentNamespace? ParentNamespaceTest { get { int o = __p.__offset(72); return o != 0 ? (MyGame.InParentNamespace?)(new MyGame.InParentNamespace()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public Referrable? VectorOfReferrables(int j) { int o = __p.__offset(74); return o != 0 ? (Referrable?)(new Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
@@ -106,6 +113,7 @@ public struct Monster : IFlatbufferObject
public ulong VectorOfWeakReferences(int j) { int o = __p.__offset(78); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
public int VectorOfWeakReferencesLength { get { int o = __p.__offset(78); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVectorOfWeakReferencesBytes() { return __p.__vector_as_arraysegment(78); }
+ public ulong[] GetVectorOfWeakReferencesArray() { return __p.__vector_as_array<ulong>(78); }
public bool MutateVectorOfWeakReferences(int j, ulong vector_of_weak_references) { int o = __p.__offset(78); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
public Referrable? VectorOfStrongReferrables(int j) { int o = __p.__offset(80); return o != 0 ? (Referrable?)(new Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int VectorOfStrongReferrablesLength { get { int o = __p.__offset(80); return o != 0 ? __p.__vector_len(o) : 0; } }
@@ -115,12 +123,14 @@ public struct Monster : IFlatbufferObject
public ulong VectorOfCoOwningReferences(int j) { int o = __p.__offset(84); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
public int VectorOfCoOwningReferencesLength { get { int o = __p.__offset(84); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_arraysegment(84); }
+ public ulong[] GetVectorOfCoOwningReferencesArray() { return __p.__vector_as_array<ulong>(84); }
public bool MutateVectorOfCoOwningReferences(int j, ulong vector_of_co_owning_references) { int o = __p.__offset(84); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
public ulong NonOwningReference { get { int o = __p.__offset(86); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
public bool MutateNonOwningReference(ulong non_owning_reference) { int o = __p.__offset(86); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, non_owning_reference); return true; } else { return false; } }
public ulong VectorOfNonOwningReferences(int j) { int o = __p.__offset(88); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
public int VectorOfNonOwningReferencesLength { get { int o = __p.__offset(88); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_arraysegment(88); }
+ public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); }
public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(43); }
@@ -130,6 +140,7 @@ public struct Monster : IFlatbufferObject
public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(3, nameOffset.Value, 0); }
public static void AddInventory(FlatBufferBuilder builder, VectorOffset inventoryOffset) { builder.AddOffset(5, inventoryOffset.Value, 0); }
public static VectorOffset CreateInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
public static void StartInventoryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
public static void AddColor(FlatBufferBuilder builder, Color color) { builder.AddSbyte(6, (sbyte)color, 8); }
public static void AddTestType(FlatBufferBuilder builder, Any testType) { builder.AddByte(7, (byte)testType, 0); }
@@ -138,13 +149,16 @@ public struct Monster : IFlatbufferObject
public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
public static void AddTestarrayofstring(FlatBufferBuilder builder, VectorOffset testarrayofstringOffset) { builder.AddOffset(10, testarrayofstringOffset.Value, 0); }
public static VectorOffset CreateTestarrayofstringVector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+ public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static void AddTestarrayoftables(FlatBufferBuilder builder, VectorOffset testarrayoftablesOffset) { builder.AddOffset(11, testarrayoftablesOffset.Value, 0); }
public static VectorOffset CreateTestarrayoftablesVector(FlatBufferBuilder builder, Offset<Monster>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+ public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, Offset<Monster>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static void AddEnemy(FlatBufferBuilder builder, Offset<Monster> enemyOffset) { builder.AddOffset(12, enemyOffset.Value, 0); }
public static void AddTestnestedflatbuffer(FlatBufferBuilder builder, VectorOffset testnestedflatbufferOffset) { builder.AddOffset(13, testnestedflatbufferOffset.Value, 0); }
public static VectorOffset CreateTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
public static void StartTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
public static void AddTestempty(FlatBufferBuilder builder, Offset<Stat> testemptyOffset) { builder.AddOffset(14, testemptyOffset.Value, 0); }
public static void AddTestbool(FlatBufferBuilder builder, bool testbool) { builder.AddBool(15, testbool, false); }
@@ -158,44 +172,54 @@ public struct Monster : IFlatbufferObject
public static void AddTesthashu64Fnv1a(FlatBufferBuilder builder, ulong testhashu64Fnv1a) { builder.AddUlong(23, testhashu64Fnv1a, 0); }
public static void AddTestarrayofbools(FlatBufferBuilder builder, VectorOffset testarrayofboolsOffset) { builder.AddOffset(24, testarrayofboolsOffset.Value, 0); }
public static VectorOffset CreateTestarrayofboolsVector(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddBool(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
public static void StartTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
public static void AddTestf(FlatBufferBuilder builder, float testf) { builder.AddFloat(25, testf, 3.14159f); }
public static void AddTestf2(FlatBufferBuilder builder, float testf2) { builder.AddFloat(26, testf2, 3.0f); }
public static void AddTestf3(FlatBufferBuilder builder, float testf3) { builder.AddFloat(27, testf3, 0.0f); }
public static void AddTestarrayofstring2(FlatBufferBuilder builder, VectorOffset testarrayofstring2Offset) { builder.AddOffset(28, testarrayofstring2Offset.Value, 0); }
public static VectorOffset CreateTestarrayofstring2Vector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+ public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static void AddTestarrayofsortedstruct(FlatBufferBuilder builder, VectorOffset testarrayofsortedstructOffset) { builder.AddOffset(29, testarrayofsortedstructOffset.Value, 0); }
public static void StartTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
public static void AddTest5(FlatBufferBuilder builder, VectorOffset test5Offset) { builder.AddOffset(31, test5Offset.Value, 0); }
public static void StartTest5Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
public static void AddVectorOfLongs(FlatBufferBuilder builder, VectorOffset vectorOfLongsOffset) { builder.AddOffset(32, vectorOfLongsOffset.Value, 0); }
public static VectorOffset CreateVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static void AddVectorOfDoubles(FlatBufferBuilder builder, VectorOffset vectorOfDoublesOffset) { builder.AddOffset(33, vectorOfDoublesOffset.Value, 0); }
public static VectorOffset CreateVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static void AddParentNamespaceTest(FlatBufferBuilder builder, Offset<MyGame.InParentNamespace> parentNamespaceTestOffset) { builder.AddOffset(34, parentNamespaceTestOffset.Value, 0); }
public static void AddVectorOfReferrables(FlatBufferBuilder builder, VectorOffset vectorOfReferrablesOffset) { builder.AddOffset(35, vectorOfReferrablesOffset.Value, 0); }
public static VectorOffset CreateVectorOfReferrablesVector(FlatBufferBuilder builder, Offset<Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, Offset<Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static void AddSingleWeakReference(FlatBufferBuilder builder, ulong singleWeakReference) { builder.AddUlong(36, singleWeakReference, 0); }
public static void AddVectorOfWeakReferences(FlatBufferBuilder builder, VectorOffset vectorOfWeakReferencesOffset) { builder.AddOffset(37, vectorOfWeakReferencesOffset.Value, 0); }
public static VectorOffset CreateVectorOfWeakReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static void AddVectorOfStrongReferrables(FlatBufferBuilder builder, VectorOffset vectorOfStrongReferrablesOffset) { builder.AddOffset(38, vectorOfStrongReferrablesOffset.Value, 0); }
public static VectorOffset CreateVectorOfStrongReferrablesVector(FlatBufferBuilder builder, Offset<Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, Offset<Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static void AddCoOwningReference(FlatBufferBuilder builder, ulong coOwningReference) { builder.AddUlong(39, coOwningReference, 0); }
public static void AddVectorOfCoOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfCoOwningReferencesOffset) { builder.AddOffset(40, vectorOfCoOwningReferencesOffset.Value, 0); }
public static VectorOffset CreateVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static void AddNonOwningReference(FlatBufferBuilder builder, ulong nonOwningReference) { builder.AddUlong(41, nonOwningReference, 0); }
public static void AddVectorOfNonOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfNonOwningReferencesOffset) { builder.AddOffset(42, vectorOfNonOwningReferencesOffset.Value, 0); }
public static VectorOffset CreateVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
int o = builder.EndObject();
diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs
index e1fd572e..9d78da5a 100644
--- a/tests/MyGame/Example/Stat.cs
+++ b/tests/MyGame/Example/Stat.cs
@@ -19,6 +19,7 @@ public struct Stat : IFlatbufferObject
public string Id { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
public ArraySegment<byte>? GetIdBytes() { return __p.__vector_as_arraysegment(4); }
+ public byte[] GetIdArray() { return __p.__vector_as_array<byte>(4); }
public long Val { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
public bool MutateVal(long val) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, val); return true; } else { return false; } }
public ushort Count { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
diff --git a/tests/MyGame/Example/TypeAliases.cs b/tests/MyGame/Example/TypeAliases.cs
index f03c142b..c4d87243 100644
--- a/tests/MyGame/Example/TypeAliases.cs
+++ b/tests/MyGame/Example/TypeAliases.cs
@@ -40,10 +40,12 @@ public struct TypeAliases : IFlatbufferObject
public sbyte V8(int j) { int o = __p.__offset(24); return o != 0 ? __p.bb.GetSbyte(__p.__vector(o) + j * 1) : (sbyte)0; }
public int V8Length { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetV8Bytes() { return __p.__vector_as_arraysegment(24); }
+ public sbyte[] GetV8Array() { return __p.__vector_as_array<sbyte>(24); }
public bool MutateV8(int j, sbyte v8) { int o = __p.__offset(24); if (o != 0) { __p.bb.PutSbyte(__p.__vector(o) + j * 1, v8); return true; } else { return false; } }
public double Vf64(int j) { int o = __p.__offset(26); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
public int Vf64Length { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
public ArraySegment<byte>? GetVf64Bytes() { return __p.__vector_as_arraysegment(26); }
+ public double[] GetVf64Array() { return __p.__vector_as_array<double>(26); }
public bool MutateVf64(int j, double vf64) { int o = __p.__offset(26); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vf64); return true; } else { return false; } }
public static Offset<TypeAliases> CreateTypeAliases(FlatBufferBuilder builder,
@@ -88,9 +90,11 @@ public struct TypeAliases : IFlatbufferObject
public static void AddF64(FlatBufferBuilder builder, double f64) { builder.AddDouble(9, f64, 0.0); }
public static void AddV8(FlatBufferBuilder builder, VectorOffset v8Offset) { builder.AddOffset(10, v8Offset.Value, 0); }
public static VectorOffset CreateV8Vector(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddSbyte(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateV8VectorBlock(FlatBufferBuilder builder, sbyte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
public static void StartV8Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
public static void AddVf64(FlatBufferBuilder builder, VectorOffset vf64Offset) { builder.AddOffset(11, vf64Offset.Value, 0); }
public static VectorOffset CreateVf64Vector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateVf64VectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static void StartVf64Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static Offset<TypeAliases> EndTypeAliases(FlatBufferBuilder builder) {
int o = builder.EndObject();
diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs
index a6b87d4a..bb4121c2 100644
--- a/tests/monster_test.bfbs
+++ b/tests/monster_test.bfbs
Binary files differ
diff --git a/tests/namespace_test/namespace_test2_generated.ts b/tests/namespace_test/namespace_test2_generated.ts
index 18f1d6e8..1034ef2b 100644
--- a/tests/namespace_test/namespace_test2_generated.ts
+++ b/tests/namespace_test/namespace_test2_generated.ts
@@ -1,6 +1,6 @@
// automatically generated by the FlatBuffers compiler, do not modify
-import * as NS9459827973991502386 from "./namespace_test1_generated";
+import * as NS11563891686210618450 from "./namespace_test1_generated";
/**
* @constructor
*/
@@ -39,24 +39,24 @@ static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):T
* @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.TableInNestedNS|null}
*/
-fooTable(obj?:NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS|null {
+fooTable(obj?:NS11563891686210618450.NamespaceA.NamespaceB.TableInNestedNS):NS11563891686210618450.NamespaceA.NamespaceB.TableInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new NS11563891686210618450.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
* @returns {NamespaceA.NamespaceB.EnumInNestedNS}
*/
-fooEnum():NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS {
+fooEnum():NS11563891686210618450.NamespaceA.NamespaceB.EnumInNestedNS {
var offset = this.bb!.__offset(this.bb_pos, 6);
- return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb!.readInt8(this.bb_pos + offset)) : NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A;
+ return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb!.readInt8(this.bb_pos + offset)) : NS11563891686210618450.NamespaceA.NamespaceB.EnumInNestedNS.A;
};
/**
* @param {NamespaceA.NamespaceB.EnumInNestedNS} value
* @returns {boolean}
*/
-mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
+mutate_foo_enum(value:NS11563891686210618450.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
var offset = this.bb!.__offset(this.bb_pos, 6);
if (offset === 0) {
@@ -71,9 +71,9 @@ mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS
* @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.StructInNestedNS|null}
*/
-fooStruct(obj?:NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS|null {
+fooStruct(obj?:NS11563891686210618450.NamespaceA.NamespaceB.StructInNestedNS):NS11563891686210618450.NamespaceA.NamespaceB.StructInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 8);
- return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
+ return offset ? (obj || new NS11563891686210618450.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
};
/**
@@ -95,8 +95,8 @@ static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offse
* @param {flatbuffers.Builder} builder
* @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
*/
-static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS) {
- builder.addFieldInt8(1, fooEnum, NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A);
+static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS11563891686210618450.NamespaceA.NamespaceB.EnumInNestedNS) {
+ builder.addFieldInt8(1, fooEnum, NS11563891686210618450.NamespaceA.NamespaceB.EnumInNestedNS.A);
};
/**