mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 10:20:02 +00:00
[Issue 252] Add type cast for default enum values in C#
When creating a CreateXxx(...) method for a simple table type, enum-type fields with a non-zero default must have an explicit cast for the respective argument default value, because in C#, there is an implicit cast from int to an enum only for 0. Also, added an example of such type into the example monster_test type, so that we test this feature.
This commit is contained in:
@@ -789,7 +789,15 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
|
|||||||
// Java doesn't have defaults, which means this method must always
|
// Java doesn't have defaults, which means this method must always
|
||||||
// supply all arguments, and thus won't compile when fields are added.
|
// supply all arguments, and thus won't compile when fields are added.
|
||||||
if (lang.language != GeneratorOptions::kJava) {
|
if (lang.language != GeneratorOptions::kJava) {
|
||||||
code += " = " + GenDefaultValue(lang, field.value, false);
|
code += " = ";
|
||||||
|
// in C#, enum values have their own type, so we need to cast the
|
||||||
|
// numeric value to the proper type
|
||||||
|
if (lang.language == GeneratorOptions::kCSharp &&
|
||||||
|
field.value.type.enum_def != nullptr &&
|
||||||
|
field.value.type.base_type != BASE_TYPE_UNION) {
|
||||||
|
code += "(" + field.value.type.enum_def->name + ")";
|
||||||
|
}
|
||||||
|
code += GenDefaultValue(lang, field.value, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code += ") {\n builder.";
|
code += ") {\n builder.";
|
||||||
|
|||||||
@@ -71,6 +71,9 @@
|
|||||||
<Compile Include="..\MyGame\Example\Test.cs">
|
<Compile Include="..\MyGame\Example\Test.cs">
|
||||||
<Link>MyGame\Example\Test.cs</Link>
|
<Link>MyGame\Example\Test.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MyGame\Example\TestSimpleTableWithEnum.cs">
|
||||||
|
<Link>MyGame\Example\TestSimpleTableWithEnum.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\MyGame\Example\Vec3.cs">
|
<Compile Include="..\MyGame\Example\Vec3.cs">
|
||||||
<Link>MyGame\Example\Vec3.cs</Link>
|
<Link>MyGame\Example\Vec3.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public enum Any : byte
|
|||||||
{
|
{
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
Monster = 1,
|
Monster = 1,
|
||||||
|
TestSimpleTableWithEnum = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ package Example
|
|||||||
const (
|
const (
|
||||||
AnyNONE = 0
|
AnyNONE = 0
|
||||||
AnyMonster = 1
|
AnyMonster = 1
|
||||||
|
AnyTestSimpleTableWithEnum = 2
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ public final class Any {
|
|||||||
private Any() { }
|
private Any() { }
|
||||||
public static final byte NONE = 0;
|
public static final byte NONE = 0;
|
||||||
public static final byte Monster = 1;
|
public static final byte Monster = 1;
|
||||||
|
public static final byte TestSimpleTableWithEnum = 2;
|
||||||
|
|
||||||
private static final String[] names = { "NONE", "Monster", };
|
private static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", };
|
||||||
|
|
||||||
public static String name(int e) { return names[e]; }
|
public static String name(int e) { return names[e]; }
|
||||||
};
|
};
|
||||||
|
|||||||
31
tests/MyGame/Example/TestSimpleTableWithEnum.cs
Normal file
31
tests/MyGame/Example/TestSimpleTableWithEnum.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// automatically generated, do not modify
|
||||||
|
|
||||||
|
namespace MyGame.Example
|
||||||
|
{
|
||||||
|
|
||||||
|
using FlatBuffers;
|
||||||
|
|
||||||
|
public sealed class TestSimpleTableWithEnum : Table {
|
||||||
|
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
|
||||||
|
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||||
|
public TestSimpleTableWithEnum __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||||
|
|
||||||
|
public Color Color { get { int o = __offset(4); return o != 0 ? (Color)bb.GetSbyte(o + bb_pos) : (Color)2; } }
|
||||||
|
|
||||||
|
public static Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
|
||||||
|
Color color = (Color)2) {
|
||||||
|
builder.StartObject(1);
|
||||||
|
TestSimpleTableWithEnum.AddColor(builder, color);
|
||||||
|
return TestSimpleTableWithEnum.EndTestSimpleTableWithEnum(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||||
|
public static void AddColor(FlatBufferBuilder builder, Color color) { builder.AddSbyte(0, (sbyte)(color), 2); }
|
||||||
|
public static Offset<TestSimpleTableWithEnum> EndTestSimpleTableWithEnum(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.EndObject();
|
||||||
|
return new Offset<TestSimpleTableWithEnum>(o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
27
tests/MyGame/Example/TestSimpleTableWithEnum.go
Normal file
27
tests/MyGame/Example/TestSimpleTableWithEnum.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// automatically generated, do not modify
|
||||||
|
|
||||||
|
package Example
|
||||||
|
|
||||||
|
import (
|
||||||
|
flatbuffers "github.com/google/flatbuffers/go"
|
||||||
|
)
|
||||||
|
type TestSimpleTableWithEnum struct {
|
||||||
|
_tab flatbuffers.Table
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *TestSimpleTableWithEnum) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||||
|
rcv._tab.Bytes = buf
|
||||||
|
rcv._tab.Pos = i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *TestSimpleTableWithEnum) Color() int8 {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||||
|
if o != 0 {
|
||||||
|
return rcv._tab.GetInt8(o + rcv._tab.Pos)
|
||||||
|
}
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimpleTableWithEnumStart(builder *flatbuffers.Builder) { builder.StartObject(1) }
|
||||||
|
func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color int8) { builder.PrependInt8Slot(0, color, 2) }
|
||||||
|
func TestSimpleTableWithEnumEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
|
||||||
31
tests/MyGame/Example/TestSimpleTableWithEnum.java
Normal file
31
tests/MyGame/Example/TestSimpleTableWithEnum.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// automatically generated, do not modify
|
||||||
|
|
||||||
|
package MyGame.Example;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
import java.lang.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.google.flatbuffers.*;
|
||||||
|
|
||||||
|
public final class TestSimpleTableWithEnum extends Table {
|
||||||
|
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
|
||||||
|
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||||
|
public TestSimpleTableWithEnum __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||||
|
|
||||||
|
public byte color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 2; }
|
||||||
|
|
||||||
|
public static int createTestSimpleTableWithEnum(FlatBufferBuilder builder,
|
||||||
|
byte color) {
|
||||||
|
builder.startObject(1);
|
||||||
|
TestSimpleTableWithEnum.addColor(builder, color);
|
||||||
|
return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.startObject(1); }
|
||||||
|
public static void addColor(FlatBufferBuilder builder, byte color) { builder.addByte(0, color, 2); }
|
||||||
|
public static int endTestSimpleTableWithEnum(FlatBufferBuilder builder) {
|
||||||
|
int o = builder.endObject();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@@ -8,10 +8,14 @@ attribute "priority";
|
|||||||
|
|
||||||
enum Color:byte (bit_flags) { Red = 0, Green, Blue = 3, }
|
enum Color:byte (bit_flags) { Red = 0, Green, Blue = 3, }
|
||||||
|
|
||||||
union Any { Monster } // TODO: add more elements
|
union Any { Monster, TestSimpleTableWithEnum } // TODO: add more elements
|
||||||
|
|
||||||
struct Test { a:short; b:byte; }
|
struct Test { a:short; b:byte; }
|
||||||
|
|
||||||
|
table TestSimpleTableWithEnum {
|
||||||
|
color: Color = Green;
|
||||||
|
}
|
||||||
|
|
||||||
struct Vec3 (force_align: 16) {
|
struct Vec3 (force_align: 16) {
|
||||||
x:float;
|
x:float;
|
||||||
y:float;
|
y:float;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace MyGame {
|
|||||||
namespace Example {
|
namespace Example {
|
||||||
|
|
||||||
struct Test;
|
struct Test;
|
||||||
|
struct TestSimpleTableWithEnum;
|
||||||
struct Vec3;
|
struct Vec3;
|
||||||
struct Stat;
|
struct Stat;
|
||||||
struct Monster;
|
struct Monster;
|
||||||
@@ -34,11 +35,12 @@ inline const char *EnumNameColor(Color e) { return EnumNamesColor()[e - Color_Re
|
|||||||
|
|
||||||
enum Any {
|
enum Any {
|
||||||
Any_NONE = 0,
|
Any_NONE = 0,
|
||||||
Any_Monster = 1
|
Any_Monster = 1,
|
||||||
|
Any_TestSimpleTableWithEnum = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char **EnumNamesAny() {
|
inline const char **EnumNamesAny() {
|
||||||
static const char *names[] = { "NONE", "Monster", nullptr };
|
static const char *names[] = { "NONE", "Monster", "TestSimpleTableWithEnum", nullptr };
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +96,35 @@ MANUALLY_ALIGNED_STRUCT(16) Vec3 FLATBUFFERS_FINAL_CLASS {
|
|||||||
};
|
};
|
||||||
STRUCT_END(Vec3, 32);
|
STRUCT_END(Vec3, 32);
|
||||||
|
|
||||||
|
struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
Color color() const { return static_cast<Color>(GetField<int8_t>(4, 2)); }
|
||||||
|
bool mutate_color(Color color) { return SetField(4, static_cast<int8_t>(color)); }
|
||||||
|
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||||
|
return VerifyTableStart(verifier) &&
|
||||||
|
VerifyField<int8_t>(verifier, 4 /* color */) &&
|
||||||
|
verifier.EndTable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestSimpleTableWithEnumBuilder {
|
||||||
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
|
flatbuffers::uoffset_t start_;
|
||||||
|
void add_color(Color color) { fbb_.AddElement<int8_t>(4, static_cast<int8_t>(color), 2); }
|
||||||
|
TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||||
|
TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &);
|
||||||
|
flatbuffers::Offset<TestSimpleTableWithEnum> Finish() {
|
||||||
|
auto o = flatbuffers::Offset<TestSimpleTableWithEnum>(fbb_.EndTable(start_, 1));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
Color color = Color_Green) {
|
||||||
|
TestSimpleTableWithEnumBuilder builder_(_fbb);
|
||||||
|
builder_.add_color(color);
|
||||||
|
return builder_.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
const flatbuffers::String *id() const { return GetPointer<const flatbuffers::String *>(4); }
|
const flatbuffers::String *id() const { return GetPointer<const flatbuffers::String *>(4); }
|
||||||
flatbuffers::String *mutable_id() { return GetPointer<flatbuffers::String *>(4); }
|
flatbuffers::String *mutable_id() { return GetPointer<flatbuffers::String *>(4); }
|
||||||
@@ -318,6 +349,7 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, An
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case Any_NONE: return true;
|
case Any_NONE: return true;
|
||||||
case Any_Monster: return verifier.VerifyTable(reinterpret_cast<const Monster *>(union_obj));
|
case Any_Monster: return verifier.VerifyTable(reinterpret_cast<const Monster *>(union_obj));
|
||||||
|
case Any_TestSimpleTableWithEnum: return verifier.VerifyTable(reinterpret_cast<const TestSimpleTableWithEnum *>(union_obj));
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user