diff options
-rw-r--r-- | src/idl_gen_general.cpp | 36 | ||||
-rw-r--r-- | tests/FlatBuffers.Test/FlatBuffersExampleTests.cs | 19 | ||||
-rw-r--r-- | tests/MyGame/Example/Monster.cs | 3 | ||||
-rw-r--r-- | tests/union_vector/Movie.cs | 3 |
4 files changed, 50 insertions, 11 deletions
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 8994e553..a5b8942e 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -1238,12 +1238,31 @@ class GeneralGenerator : public BaseGenerator { 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"; + code += "Array() { "; + if (IsEnum(field.value.type.VectorType())) { + // Since __vector_as_array does not work for enum types, + // fill array using an explicit loop. + code += "int o = " + lang_.accessor_prefix + "__offset("; + code += NumToString(field.value.offset); + code += "); if (o == 0) return null; int p = "; + code += lang_.accessor_prefix + "__vector(o); int l = "; + code += lang_.accessor_prefix + "__vector_len(o); "; + code += GenTypeBasic(field.value.type.VectorType()); + code += "[] a = new "; + code += GenTypeBasic(field.value.type.VectorType()); + code += "[l]; for (int i = 0; i < l; i++) { a[i] = " + getter; + code += "(p + i * "; + code += NumToString(InlineSize(field.value.type.VectorType())); + code += "); } return a;"; + } else { + code += "return "; + code += lang_.accessor_prefix + "__vector_as_array<"; + code += GenTypeBasic(field.value.type.VectorType()); + code += ">("; + code += NumToString(field.value.offset); + code += ");"; + } + code += " }\n"; break; default: break; } @@ -1476,7 +1495,10 @@ class GeneralGenerator : public BaseGenerator { code += "); return "; code += "builder." + FunctionStart('E') + "ndVector(); }\n"; // For C#, include a block copy method signature. - if (lang_.language == IDLOptions::kCSharp) { + // Skip if the vector is of enums, because builder.Add + // throws an exception when supplied an enum array. + if (lang_.language == IDLOptions::kCSharp && + !IsEnum(vector_type)) { code += " public static " + GenVectorOffsetType() + " "; code += FunctionStart('C') + "reate"; code += MakeCamel(field.name); diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs index 8e9fd3dd..6bb2d32c 100644 --- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs +++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs @@ -293,6 +293,25 @@ namespace FlatBuffers.Test } [FlatBuffersTestMethod] + public void TestVectorOfEnums() + { + const string monsterName = "TestVectorOfEnumsMonster"; + var colorVec = new Color[] { Color.Red, Color.Green, Color.Blue }; + var fbb = new FlatBufferBuilder(32); + var str1 = fbb.CreateString(monsterName); + var vec1 = Monster.CreateVectorOfEnumsVector(fbb, colorVec); + Monster.StartMonster(fbb); + Monster.AddName(fbb, str1); + Monster.AddVectorOfEnums(fbb, vec1); + var monster1 = Monster.EndMonster(fbb); + Monster.FinishMonsterBuffer(fbb, monster1); + + var mons = Monster.GetRootAsMonster(fbb.DataBuffer); + var colors = mons.GetVectorOfEnumsArray(); + Assert.ArrayEqual(colorVec, colors); + } + + [FlatBuffersTestMethod] public void TestNestedFlatBuffer() { const string nestedMonsterName = "NestedMonsterName"; diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index 5dc669e8..99876aa5 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -186,7 +186,7 @@ public struct Monster : IFlatbufferObject #else public ArraySegment<byte>? GetVectorOfEnumsBytes() { return __p.__vector_as_arraysegment(98); } #endif - public MyGame.Example.Color[] GetVectorOfEnumsArray() { return __p.__vector_as_array<MyGame.Example.Color>(98); } + public MyGame.Example.Color[] GetVectorOfEnumsArray() { int o = __p.__offset(98); if (o == 0) return null; int p = __p.__vector(o); int l = __p.__vector_len(o); MyGame.Example.Color[] a = new MyGame.Example.Color[l]; for (int i = 0; i < l; i++) { a[i] = (MyGame.Example.Color)__p.bb.Get(p + i * 1); } return a; } public bool MutateVectorOfEnums(int j, MyGame.Example.Color vector_of_enums) { int o = __p.__offset(98); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } } public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(48); } @@ -283,7 +283,6 @@ public struct Monster : IFlatbufferObject public static void AddAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.AddOffset(46, anyAmbiguousOffset, 0); } public static void AddVectorOfEnums(FlatBufferBuilder builder, VectorOffset vectorOfEnumsOffset) { builder.AddOffset(47, vectorOfEnumsOffset.Value, 0); } public static VectorOffset CreateVectorOfEnumsVector(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); } - public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); } public static void StartVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); } public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) { int o = builder.EndTable(); diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs index 13dbfac8..55544b0f 100644 --- a/tests/union_vector/Movie.cs +++ b/tests/union_vector/Movie.cs @@ -26,7 +26,7 @@ public struct Movie : IFlatbufferObject #else public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); } #endif - public Character[] GetCharactersTypeArray() { return __p.__vector_as_array<Character>(8); } + public Character[] GetCharactersTypeArray() { int o = __p.__offset(8); if (o == 0) return null; int p = __p.__vector(o); int l = __p.__vector_len(o); Character[] a = new Character[l]; for (int i = 0; i < l; i++) { a[i] = (Character)__p.bb.Get(p + i * 1); } return a; } public bool MutateCharactersType(int j, Character characters_type) { int o = __p.__offset(8); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)characters_type); return true; } else { return false; } } public TTable? Characters<TTable>(int j) where TTable : struct, IFlatbufferObject { int o = __p.__offset(10); return o != 0 ? (TTable?)__p.__union<TTable>(__p.__vector(o) + j * 4 - __p.bb_pos) : null; } public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } } @@ -49,7 +49,6 @@ public struct Movie : IFlatbufferObject public static void AddMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.AddOffset(1, mainCharacterOffset, 0); } public static void AddCharactersType(FlatBufferBuilder builder, VectorOffset charactersTypeOffset) { builder.AddOffset(2, charactersTypeOffset.Value, 0); } public static VectorOffset CreateCharactersTypeVector(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); } - public static VectorOffset CreateCharactersTypeVectorBlock(FlatBufferBuilder builder, Character[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); } public static void StartCharactersTypeVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); } public static void AddCharacters(FlatBufferBuilder builder, VectorOffset charactersOffset) { builder.AddOffset(3, charactersOffset.Value, 0); } public static VectorOffset CreateCharactersVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); } |